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

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