Browsing Context

Commands

This section contains the APIs related to browsing context commands.

Open a new window

Creates a new browsing context in a new window.

Selenium v4.8

    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
Show full example
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.skip('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)
  })
})

Open a new tab

Creates a new browsing context in a new tab.

Selenium v4.8

    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
Show full example
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.skip('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)
  })
})

Use existing window handle

Creates a browsing context for the existing tab/window to run commands.

Selenium v4.8

    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
Show full example
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.skip('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)
  })
})

Open a window with a reference browsing context

A reference browsing context is a top-level browsing context. The API allows to pass the reference browsing context, which is used to create a new window. The implementation is operating system specific.

Selenium v4.8

    void testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
Show full example
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.skip('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)
  })
})

Open a tab with a reference browsing context

A reference browsing context is a top-level browsing context. The API allows to pass the reference browsing context, which is used to create a new tab. The implementation is operating system specific.

Selenium v4.8

    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
Show full example
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.skip('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)
  })
})

Selenium v4.8

    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);

        NavigationResult info = browsingContext.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
Show full example
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.skip('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)
  })
})

Selenium v4.8

    void testNavigateToAUrlWithReadinessState() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);

        NavigationResult info = browsingContext.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html",
                ReadinessState.COMPLETE);

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
Show full example
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.skip('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)
  })
})

Get browsing context tree

Provides a tree of all browsing contexts descending from the parent browsing context, including the parent browsing context.

Selenium v4.8

    void testGetTreeWithAChild() {
        String referenceContextId = driver.getWindowHandle();
        BrowsingContext parentWindow = new BrowsingContext(driver, referenceContextId);

        parentWindow.navigate("https://www.selenium.dev/selenium/web/iframes.html", ReadinessState.COMPLETE);

        List<BrowsingContextInfo> contextInfoList = parentWindow.getTree();

        Assertions.assertEquals(1, contextInfoList.size());
        BrowsingContextInfo info = contextInfoList.get(0);
        Assertions.assertEquals(1, info.getChildren().size());
        Assertions.assertEquals(referenceContextId, info.getId());
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const browsingContextId = await driver.getWindowHandle()
    const parentWindow = await BrowsingContext(driver, {
      browsingContextId: browsingContextId,
    })
    await parentWindow.navigate('https://www.selenium.dev/selenium/web/iframes.html', 'complete')

    const contextInfo = await parentWindow.getTree()
Show full example
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.skip('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)
  })
})

Get browsing context tree with depth

Provides a tree of all browsing contexts descending from the parent browsing context, including the parent browsing context upto the depth value passed.

Selenium v4.8

    void testGetTreeWithDepth() {
        String referenceContextId = driver.getWindowHandle();
        BrowsingContext parentWindow = new BrowsingContext(driver, referenceContextId);

        parentWindow.navigate("https://www.selenium.dev/selenium/web/iframes.html", ReadinessState.COMPLETE);

        List<BrowsingContextInfo> contextInfoList = parentWindow.getTree(0);

        Assertions.assertEquals(1, contextInfoList.size());
        BrowsingContextInfo info = contextInfoList.get(0);
        Assertions.assertNull(info.getChildren()); // since depth is 0
        Assertions.assertEquals(referenceContextId, info.getId());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const browsingContextId = await driver.getWindowHandle()
    const parentWindow = await BrowsingContext(driver, {
      browsingContextId: browsingContextId,
    })
    await parentWindow.navigate('https://www.selenium.dev/selenium/web/iframes.html', 'complete')

    const contextInfo = await parentWindow.getTree(0)
Show full example
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.skip('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)
  })
})

Get All Top level browsing contexts

Selenium v4.8

    void testGetAllTopLevelContexts() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        List<BrowsingContextInfo> contextInfoList = window1.getTopLevelContexts();

        Assertions.assertEquals(2, contextInfoList.size());
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.20.0

    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
Show full example
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.skip('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)
  })
})

Close a tab/window

Selenium v4.8

    void testCloseAWindow() {
        BrowsingContext window1 = new BrowsingContext(driver, WindowType.WINDOW);
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
    void testCloseATab() {
        BrowsingContext tab1 = new BrowsingContext(driver, WindowType.TAB);
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.8

    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
Show full example
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.skip('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)
  })
})

Activate a browsing context

Selenium v4.14.1

        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
Show full example
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.skip('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)
  })
})
    await window1.activate()
Show full example
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.skip('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)
  })
})

Reload a browsing context

Selenium v4.13.0

        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);

        browsingContext.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", ReadinessState.COMPLETE);

        NavigationResult reloadInfo = browsingContext.reload(ReadinessState.INTERACTIVE);
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    await browsingContext.reload(undefined, 'complete')
Show full example
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.skip('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)
  })
})

Handle user prompt

Selenium v4.13.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

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

        driver.findElement(By.id("prompt-with-default")).click();

        String userText = "Selenium automates browsers";
        browsingContext.handleUserPrompt(true, userText);
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    await browsingContext.handleUserPrompt(true, userText)
Show full example
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.skip('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)
  })
})

Capture Screenshot

Selenium v4.13.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

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

        String screenshot = browsingContext.captureScreenshot();
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    const response = await browsingContext.captureScreenshot()
Show full example
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.skip('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)
  })
})

Capture Viewport Screenshot

Selenium v4.14.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();

        String screenshot =
                browsingContext.captureBoxScreenshot(
                        elementRectangle.getX(), elementRectangle.getY(), 5, 5);
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
Show full example
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.skip('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)
  })
})

Capture Element Screenshot

Selenium v4.14.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        WebElement element = driver.findElement(By.id("checky"));

        String screenshot = browsingContext.captureElementScreenshot(((RemoteWebElement) element).getId());
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    const response = await browsingContext.captureElementScreenshot(elementId)
Show full example
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.skip('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)
  })
})

Set Viewport

Selenium v4.14.1

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.15

    await browsingContext.setViewport(250, 300)
Show full example
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.skip('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)
  })
})

Selenium v4.14.1

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();

        String printPage = browsingContext.print(printOptions);
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.10

    const result = await browsingContext.printPage({
      orientation: 'landscape',
      scale: 1,
      background: true,
      width: 30,
      height: 30,
      top: 1,
      bottom: 1,
      left: 1,
      right: 1,
      shrinkToFit: true,
      pageRanges: ['1-2'],
    })
Show full example
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.skip('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)
  })
})

Selenium v4.16.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        browsingContext.navigate("https://www.selenium.dev/selenium/web/formPage.html", ReadinessState.COMPLETE);

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.17

    await browsingContext.back()
Show full example
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.skip('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)
  })
})

Selenium v4.16.0

    void canNavigateForwardInTheBrowserHistory() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        browsingContext.navigate("https://www.selenium.dev/selenium/web/formPage.html", ReadinessState.COMPLETE);

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));

        browsingContext.forward();
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.17

    await browsingContext.forward()
Show full example
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.skip('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)
  })
})

Traverse history

Selenium v4.16.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        browsingContext.navigate("https://www.selenium.dev/selenium/web/formPage.html", ReadinessState.COMPLETE);

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.traverseHistory(-1);
Show full example
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
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 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);
    }

    @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 testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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.assertTrue(screenshot.length() > 0);
    }

    @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
    @Disabled("Supported by Firefox Nightly 124")
    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.assertTrue(printPage.length() > 0);
    }

    @Test
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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
    @Disabled("Supported by Firefox Nightly 124")
    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"));
    }
}

Selenium v4.17

    await browsingContext.traverseHistory(-1)
Show full example
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.skip('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)
  })
})

Events

This section contains the APIs related to browsing context events.

Browsing Context Created Event

Selenium v4.10

    try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
        CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();

        inspector.onBrowsingContextCreated(future::complete);

        String windowHandle = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();

        BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);
Show full example
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"));
        }
    }
}

Selenium v4.9.2

    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
Show full example
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, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})

Dom Content loaded Event

Selenium v4.10

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
Show full example
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"));
        }
    }
}

Selenium v4.9.2

    const browsingContextInspector = await BrowsingContextInspector(driver)
    let navigationInfo = null
    await browsingContextInspector.onDomContentLoaded((entry) => {
      navigationInfo = entry
    })

    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: await driver.getWindowHandle(),
    })
    await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')
Show full example
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, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})

Browsing Context Loaded Event

Selenium v4.10

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextLoaded(future::complete);

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);
Show full example
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"));
        }
    }
}

Selenium v4.9.2

    const browsingContextInspector = await BrowsingContextInspector(driver)

    await browsingContextInspector.onBrowsingContextLoaded((entry) => {
      navigationInfo = entry
    })
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: await driver.getWindowHandle(),
    })
    await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')
Show full example
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, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onNavigationStarted(future::complete);

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);
Show full example
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"));
        }
    }
}

Fragment Navigated Event

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html", ReadinessState.COMPLETE);

            inspector.onFragmentNavigated(future::complete);

            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);
Show full example
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"));
        }
    }
}

Selenium v4.15.0

    const browsingContextInspector = await BrowsingContextInspector(driver)

    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: await driver.getWindowHandle(),
    })
    await browsingContext.navigate('https://www.selenium.dev/selenium/web/linked_image.html', 'complete')

    await browsingContextInspector.onFragmentNavigated((entry) => {
      navigationInfo = entry
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage', 'complete')
Show full example
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, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})

User Prompt Opened Event

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html", ReadinessState.COMPLETE);

            inspector.onFragmentNavigated(future::complete);

            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);
Show full example
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"));
        }
    }
}

User Prompt Closed Event

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptClosed> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptClosed(future::complete);

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

            driver.findElement(By.id("prompt")).click();

            context.handleUserPrompt(true, "selenium");

            UserPromptClosed userPromptClosed = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptClosed.getBrowsingContextId());
Show full example
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"));
        }
    }
}

Browsing Context Destroyed Event

Selenium v4.18

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();

            inspector.onBrowsingContextDestroyed(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();

            driver.close();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
Show full example
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"));
        }
    }
}

Selenium v4.18.0

    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
Show full example
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, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})