Browsing Context

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

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

    }
        var bidi = await driver.AsBiDiAsync();

        var context = (await bidi.BrowsingContext.CreateAsync(ContextType.Window)).Context;

        Assert.IsNotNull(context);

Selenium v4.8

    })
    assert.notEqual(browsingContext.id, null)
  })

Open a new tab

Creates a new browsing context in a new tab.

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");
        var bidi = await driver.AsBiDiAsync();

        var context = (await bidi.BrowsingContext.CreateAsync(ContextType.Tab)).Context;

        Assert.IsNotNull(context);

Selenium v4.8

    })
    assert.notEqual(browsingContext.id, null)
  })

Use existing window handle

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

Selenium v4.8


    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        var context = (await bidi.BrowsingContext.GetTreeAsync()).Contexts[0].Context;

        Assert.IsNotNull(context);

Selenium v4.8

      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

Open a window with a reference browsing context

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

Selenium v4.8


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

        var context2 = (await context1.BiDi.BrowsingContext.CreateAsync(ContextType.Window, new() { ReferenceContext = context1 })).Context;

        Assert.IsNotNull(context2);

Selenium v4.8

      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

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

        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testNavigateToAUrlWithReadinessState() {
        var context1 = context;

        var context2 = (await context1.BiDi.BrowsingContext.CreateAsync(ContextType.Tab, new() { ReferenceContext = context1 })).Context;

        Assert.IsNotNull(context2);

Selenium v4.8

      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

Selenium v4.8

        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
        var info = await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

        Assert.IsNotNull(info);
        Assert.IsNotNull(info.Navigation);
        StringAssert.Contains(info.Url, "/bidi/logEntryAdded.html");

Selenium v4.8

    assert.notEqual(browsingContext.id, null)

Selenium v4.8

        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());
        var info = await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        Assert.IsNotNull(info);
        Assert.IsNotNull(info.Navigation);
        StringAssert.Contains(info.Url, "/bidi/logEntryAdded.html");

Selenium v4.8

      'complete'
    )

    assert.notEqual(browsingContext.id, null)

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


    @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());
        await context.NavigateAsync("https://www.selenium.dev/selenium/web/iframes.html", new() { Wait = ReadinessState.Complete });

        var contexts = (await context.GetTreeAsync()).Contexts;

        Assert.AreEqual(1, contexts.Length);
        Assert.IsNotNull(contexts[0].Children);
        Assert.IsTrue(contexts[0].Children.Value.Length >= 1, "Context should contain iframes as children");

Selenium v4.8

      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)

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

    @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);
        await context.NavigateAsync("https://www.selenium.dev/selenium/web/iframes.html", new() { Wait = ReadinessState.Complete });

        var contexts = (await context.GetTreeAsync(new() { MaxDepth = 0 })).Contexts;

        Assert.AreEqual(1, contexts.Length);
        Assert.IsNull(contexts[0].Children, "Context should not contain iframes as children since depth is 0");

Selenium v4.8

      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)

Get All Top level browsing contexts

Selenium v4.8

        window2.close();

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

    @Test
    void testCloseATab() {
        BrowsingContext tab1 = new BrowsingContext(driver, WindowType.TAB);
        var window = (await bidi.BrowsingContext.CreateAsync(ContextType.Window)).Context;

        var contexts = (await bidi.BrowsingContext.GetTreeAsync()).Contexts;

        Assert.AreEqual(2, contexts.Length);
        Assert.IsTrue(contexts.Any(c => c.Context == window));

Selenium v4.20.0

      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })

Close a tab/window

Selenium v4.8

        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
    [TestMethod]
    public async Task CloseTab()
    {
        var context = (await bidi.BrowsingContext.CreateAsync(ContextType.Tab)).Context;

        await context.CloseAsync();
    }

    [TestMethod]
    public async Task CloseWindow()
    {
        var context = (await bidi.BrowsingContext.CreateAsync(ContextType.Window)).Context;

        await context.CloseAsync();

Selenium v4.8


    await window2.close()

    assert.doesNotThrow(async function () {

Activate a browsing context

Selenium v4.14.1

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

        NavigationResult reloadInfo = browsingContext.reload(ReadinessState.INTERACTIVE);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        await context.ActivateAsync();

Selenium v4.15

    })

    await BrowsingContext(driver, {

Reload a browsing context

Selenium v4.13.0

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

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

        browsingContext.handleUserPrompt();
        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        var info = await context.ReloadAsync();

        Assert.IsNotNull(info);
        Assert.IsNotNull(info.Navigation);
        StringAssert.Contains(info.Url, "/bidi/logEntryAdded.html");

Selenium v4.15

    assert(result.url.includes('/bidi/logEntryAdded.html'))

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(false, userText);
        // temporary use firefox because of chrome automatically handle prompts
        using var driver = new FirefoxDriver(new FirefoxOptions() { UseWebSocketUrl = true, UnhandledPromptBehavior = UnhandledPromptBehavior.Ignore });

        var bidi = await driver.AsBiDiAsync();

        var context = (await bidi.BrowsingContext.GetTreeAsync()).Contexts[0].Context;

        driver.Url = "https://www.selenium.dev/selenium/web/alerts.html";

        TaskCompletionSource<UserPromptOpenedEventArgs> promptOpened = new();

        await bidi.BrowsingContext.UserPromptOpened.SubscribeAsync(args => promptOpened.TrySetResult(args));

        driver.FindElement(By.Id("prompt-with-default")).Click();

        await promptOpened.Task.WaitAsync(TimeSpan.FromSeconds(5));

        await context.HandleUserPromptAsync(new() { Accept = true, UserText = "Selenium automates browsers" });

Selenium v4.15

    const result = await driver.getPageSource()

Capture Screenshot

Selenium v4.13.0


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

        String screenshot =
        var screenshot = await context.CaptureScreenshotAsync();

        Assert.IsNotNull(screenshot);
        Assert.IsNotNull(screenshot.Data);
        Assert.IsNotNull(screenshot.ToByteArray());

Selenium v4.15

    assert.equal(base64code, pngMagicNumber)

Capture Viewport Screenshot

Selenium v4.14.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.assertFalse(screenshot.isEmpty());
        var screenshot = await context.CaptureScreenshotAsync(new() { Clip = new BoxClipRectangle(5, 5, 10, 10) });

        Assert.IsNotNull(screenshot);
        Assert.IsNotNull(screenshot.Data);

Selenium v4.15

    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)

Capture Element Screenshot

Selenium v4.14.0


        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
        driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";

        var nodes = (await context.LocateNodesAsync(new CssLocator("#checky"))).Nodes;

        Assert.IsTrue(nodes.Length > 0, "Expected to locate #checky");

        var screenshot = await context.CaptureScreenshotAsync(new() { Clip = new ElementClipRectangle(nodes[0]) });

        Assert.IsNotNull(screenshot);
        Assert.IsNotNull(screenshot.Data);

Selenium v4.15

    const base64code = response.slice(0, 5)

Set Viewport

Selenium v4.14.1

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

        String printPage = browsingContext.print(printOptions);
        await context.SetViewportAsync(new() { Viewport = new Viewport(Width: 250, Height: 300), DevicePixelRatio = 5 });

Selenium v4.15

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')

Selenium v4.14.1

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

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
        var pdf = await context.PrintAsync(new() { PageRanges = [1, 2, 3..5, new(3, 5), 7..] });

        Assert.IsNotNull(pdf);
        Assert.IsNotNull(pdf.Data);
        Assert.IsNotNull(pdf.ToByteArray());

Selenium v4.10

      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)

Selenium v4.16.0

        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"));
        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        await context.TraverseHistoryAsync(-1);

        var url = await WaitForUrlAsync("about:blank");

        Assert.AreEqual("about:blank", url);

Selenium v4.17

    const source = await driver.getPageSource()

Selenium v4.16.0

        browsingContext.navigate("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"));
    }
}
        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        await context.TraverseHistoryAsync(-1);
        await WaitForUrlAsync("about:blank");

        await context.TraverseHistoryAsync(1);
        var url = await WaitForUrlAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

        Assert.AreEqual("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", url);

Selenium v4.17

    await driver.wait(until.titleIs('We Arrive Here'), 2500)

Traverse history

Selenium v4.16.0

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        await context.TraverseHistoryAsync(-1);

        var url = await WaitForUrlAsync("about:blank");

        Assert.AreEqual("about:blank", url);

Selenium v4.17

    const source = await driver.getPageSource()

Events

This section contains the APIs related to browsing context events.

Browsing Context Created Event

Selenium v4.10


        inspector.onBrowsingContextCreated(future::complete);

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

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

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        TaskCompletionSource<ContextCreatedEventArgs> tcs = new();

        await bidi.BrowsingContext.ContextCreated.SubscribeAsync(args => tcs.TrySetResult(args));

        driver.SwitchTo().NewWindow(OpenQA.Selenium.WindowType.Window);

        var info = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(info);
        Console.WriteLine(info);

Selenium v4.9.2

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

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

Dom Content loaded Event

Selenium v4.10

            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)) {
        TaskCompletionSource<DomContentLoadedEventArgs> tcs = new();

        await context.DomContentLoaded.SubscribeAsync(args => tcs.TrySetResult(args));

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        var navigationInfo = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(navigationInfo);
        Console.WriteLine(navigationInfo);

Selenium v4.9.2

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

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

Browsing Context Loaded Event

Selenium v4.10

            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"));
        TaskCompletionSource<LoadEventArgs> tcs = new();

        await context.Load.SubscribeAsync(args => tcs.TrySetResult(args));

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        var navigationInfo = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(navigationInfo);
        Console.WriteLine(navigationInfo);

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')

Selenium v4.15

            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"));
        TaskCompletionSource<NavigationStartedEventArgs> tcs = new();

        await context.NavigationStarted.SubscribeAsync(args => tcs.TrySetResult(args));

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", new() { Wait = ReadinessState.Complete });

        var info = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(info);

Fragment Navigated Event

Selenium v4.15


            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"));
        await context.NavigateAsync("https://www.selenium.dev/selenium/web/linked_image.html", new() { Wait = ReadinessState.Complete });

        TaskCompletionSource<FragmentNavigatedEventArgs> tcs = new();

        await context.FragmentNavigated.SubscribeAsync(args => tcs.TrySetResult(args));

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage", new() { Wait = ReadinessState.Complete });

        var navigationInfo = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(navigationInfo);
        Console.WriteLine(navigationInfo);

Selenium v4.15.0

    const browsingContextInspector = await BrowsingContextInspector(driver)

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

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

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage', 'complete')

User Prompt Opened Event

Selenium v4.15


            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"));
        TaskCompletionSource<UserPromptOpenedEventArgs> tcs = new();

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/alerts.html", new() { Wait = ReadinessState.Complete });

        // TODO: this event can be a part of context
        await bidi.BrowsingContext.UserPromptOpened.SubscribeAsync(args => tcs.TrySetResult(args));

        driver.FindElement(By.Id("prompt")).Click();

        var userPromptOpenedEventArgs = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(userPromptOpenedEventArgs);
        Console.WriteLine(userPromptOpenedEventArgs);

User Prompt Closed Event

Selenium v4.15


            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());
        }
    }
        TaskCompletionSource<UserPromptOpenedEventArgs> opened = new();
        TaskCompletionSource<UserPromptClosedEventArgs> closed = new();

        await context.NavigateAsync("https://www.selenium.dev/selenium/web/alerts.html", new() { Wait = ReadinessState.Complete });

        // TODO: these events can be a part of context
        await bidi.BrowsingContext.UserPromptOpened.SubscribeAsync(args => opened.TrySetResult(args));
        await bidi.BrowsingContext.UserPromptClosed.SubscribeAsync(args => closed.TrySetResult(args));

        driver.FindElement(By.Id("prompt")).Click();

        await opened.Task.WaitAsync(TimeSpan.FromSeconds(5));

        try
        {
            // Chrome's default unhandled prompt behavior may already have closed the
            // prompt by this point; tolerate that instead of treating it as a failure.
            await context.HandleUserPromptAsync(new() { Accept = true });
        }
        catch (BiDiException ex) when (ex.Message.Contains("no such alert"))
        {
        }

        var userPromptClosedEventArgs = await closed.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(userPromptClosedEventArgs);
        Console.WriteLine(userPromptClosedEventArgs);

Browsing Context Destroyed Event

Selenium v4.18


            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"));
        }
        TaskCompletionSource<ContextDestroyedEventArgs> tcs = new();

        await bidi.BrowsingContext.ContextDestroyed.SubscribeAsync(args => tcs.TrySetResult(args));

        await context.CloseAsync();

        var contextInfo = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));

        Assert.IsNotNull(contextInfo);
        Assert.AreEqual(context, contextInfo.Context);
        Console.WriteLine(contextInfo);

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()