WebDriver BiDi Logging Features
These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.
Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see Enabling BiDi
Console Message Handlers
Record or take actions on console.log events.
Add Handler
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete);/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/high_level/LogTest.java
package dev.selenium.bidirectional.webdriver_bidi.high_level;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
class LogTest extends BaseTest {
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
}
@Test
void canAddConsoleMessageHandler()
throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("consoleLog")).click();
ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Hello, world!", logEntry.getText());
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
}
@Test
void canRemoveConsoleMessageHandler() {
CopyOnWriteArrayList<ConsoleLogEntry> logs = new CopyOnWriteArrayList<>();
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(logs::add);
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
driver.findElement(By.id("consoleLog")).click();
Assertions.assertEquals(0, logs.size());
}
@Test
void canAddJsErrorHandler() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Error: Not working", logEntry.getText());
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
}
@Test
void canRemoveJsErrorHandler() {
CopyOnWriteArrayList<JavascriptLogEntry> logs = new CopyOnWriteArrayList<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(logs::add);
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
Assertions.assertEquals(0, logs.size());
}
}
driver.script.add_console_message_handler(log_entries.append)/examples/python/tests/bidi/test_bidi_logging.py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_console_message_handler(log_entries.append)
driver.find_element(By.ID, "consoleLog").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Hello, world!"
@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_console_message_handler(log_entries.append)
driver.script.remove_console_message_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_javascript_error_handler(log_entries.append)
driver.find_element(By.ID, "jsException").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Error: Not working"
@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_javascript_error_handler(log_entries.append)
driver.script.remove_javascript_error_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
log_entries = []/examples/ruby/spec/bidi/logging_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Logging' do
let(:driver) { start_bidi_session }
let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
it 'adds console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_console_message_handler { |log| log_entries << log }
driver.find_element(id: 'consoleLog').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Hello, world!'
end
it 'removes console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_console_message_handler { |log| log_entries << log }
driver.script.remove_console_message_handler(id)
driver.find_element(id: 'consoleLog').click
expect(log_entries).to be_empty
end
it 'adds JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.find_element(id: 'jsException').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Error: Not working'
end
it 'removes JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.script.remove_javascript_error_handler(id)
driver.find_element(id: 'jsException').click
expect(log_entries).to be_empty
end
end
Remove Handler
You need to store the ID returned when adding the handler to delete it.
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(logs::add);
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/high_level/LogTest.java
package dev.selenium.bidirectional.webdriver_bidi.high_level;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
class LogTest extends BaseTest {
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
}
@Test
void canAddConsoleMessageHandler()
throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("consoleLog")).click();
ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Hello, world!", logEntry.getText());
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
}
@Test
void canRemoveConsoleMessageHandler() {
CopyOnWriteArrayList<ConsoleLogEntry> logs = new CopyOnWriteArrayList<>();
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(logs::add);
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
driver.findElement(By.id("consoleLog")).click();
Assertions.assertEquals(0, logs.size());
}
@Test
void canAddJsErrorHandler() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Error: Not working", logEntry.getText());
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
}
@Test
void canRemoveJsErrorHandler() {
CopyOnWriteArrayList<JavascriptLogEntry> logs = new CopyOnWriteArrayList<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(logs::add);
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
Assertions.assertEquals(0, logs.size());
}
}
id = driver.script.add_console_message_handler(log_entries.append)
driver.script.remove_console_message_handler(id)/examples/python/tests/bidi/test_bidi_logging.py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_console_message_handler(log_entries.append)
driver.find_element(By.ID, "consoleLog").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Hello, world!"
@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_console_message_handler(log_entries.append)
driver.script.remove_console_message_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_javascript_error_handler(log_entries.append)
driver.find_element(By.ID, "jsException").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Error: Not working"
@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_javascript_error_handler(log_entries.append)
driver.script.remove_javascript_error_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
log_entries = []
/examples/ruby/spec/bidi/logging_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Logging' do
let(:driver) { start_bidi_session }
let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
it 'adds console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_console_message_handler { |log| log_entries << log }
driver.find_element(id: 'consoleLog').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Hello, world!'
end
it 'removes console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_console_message_handler { |log| log_entries << log }
driver.script.remove_console_message_handler(id)
driver.find_element(id: 'consoleLog').click
expect(log_entries).to be_empty
end
it 'adds JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.find_element(id: 'jsException').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Error: Not working'
end
it 'removes JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.script.remove_javascript_error_handler(id)
driver.find_element(id: 'jsException').click
expect(log_entries).to be_empty
end
end
JavaScript Exception Handlers
Record or take actions on JavaScript exception events.
Add Handler
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(future::complete);/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/high_level/LogTest.java
package dev.selenium.bidirectional.webdriver_bidi.high_level;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
class LogTest extends BaseTest {
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
}
@Test
void canAddConsoleMessageHandler()
throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("consoleLog")).click();
ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Hello, world!", logEntry.getText());
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
}
@Test
void canRemoveConsoleMessageHandler() {
CopyOnWriteArrayList<ConsoleLogEntry> logs = new CopyOnWriteArrayList<>();
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(logs::add);
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
driver.findElement(By.id("consoleLog")).click();
Assertions.assertEquals(0, logs.size());
}
@Test
void canAddJsErrorHandler() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Error: Not working", logEntry.getText());
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
}
@Test
void canRemoveJsErrorHandler() {
CopyOnWriteArrayList<JavascriptLogEntry> logs = new CopyOnWriteArrayList<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(logs::add);
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
Assertions.assertEquals(0, logs.size());
}
}
driver.script.add_javascript_error_handler(log_entries.append)/examples/python/tests/bidi/test_bidi_logging.py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_console_message_handler(log_entries.append)
driver.find_element(By.ID, "consoleLog").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Hello, world!"
@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_console_message_handler(log_entries.append)
driver.script.remove_console_message_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_javascript_error_handler(log_entries.append)
driver.find_element(By.ID, "jsException").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Error: Not working"
@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_javascript_error_handler(log_entries.append)
driver.script.remove_javascript_error_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
log_entries = []/examples/ruby/spec/bidi/logging_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Logging' do
let(:driver) { start_bidi_session }
let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
it 'adds console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_console_message_handler { |log| log_entries << log }
driver.find_element(id: 'consoleLog').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Hello, world!'
end
it 'removes console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_console_message_handler { |log| log_entries << log }
driver.script.remove_console_message_handler(id)
driver.find_element(id: 'consoleLog').click
expect(log_entries).to be_empty
end
it 'adds JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.find_element(id: 'jsException').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Error: Not working'
end
it 'removes JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.script.remove_javascript_error_handler(id)
driver.find_element(id: 'jsException').click
expect(log_entries).to be_empty
end
end
Remove Handler
You need to store the ID returned when adding the handler to delete it.
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(logs::add);
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/high_level/LogTest.java
package dev.selenium.bidirectional.webdriver_bidi.high_level;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
class LogTest extends BaseTest {
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
}
@Test
void canAddConsoleMessageHandler()
throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("consoleLog")).click();
ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Hello, world!", logEntry.getText());
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
}
@Test
void canRemoveConsoleMessageHandler() {
CopyOnWriteArrayList<ConsoleLogEntry> logs = new CopyOnWriteArrayList<>();
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
String id = ((RemoteWebDriver) driver).script().addConsoleMessageHandler(logs::add);
((RemoteWebDriver) driver).script().removeConsoleMessageHandler(id);
driver.findElement(By.id("consoleLog")).click();
Assertions.assertEquals(0, logs.size());
}
@Test
void canAddJsErrorHandler() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(future::complete);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
Assertions.assertEquals("Error: Not working", logEntry.getText());
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
}
@Test
void canRemoveJsErrorHandler() {
CopyOnWriteArrayList<JavascriptLogEntry> logs = new CopyOnWriteArrayList<>();
String id = ((RemoteWebDriver) driver).script().addJavaScriptErrorHandler(logs::add);
((RemoteWebDriver) driver).script().removeJavaScriptErrorHandler(id);
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
driver.findElement(By.id("jsException")).click();
Assertions.assertEquals(0, logs.size());
}
}
id = driver.script.add_javascript_error_handler(log_entries.append)
driver.script.remove_javascript_error_handler(id)/examples/python/tests/bidi/test_bidi_logging.py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_console_message_handler(log_entries.append)
driver.find_element(By.ID, "consoleLog").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Hello, world!"
@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_console_message_handler(log_entries.append)
driver.script.remove_console_message_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
driver.script.add_javascript_error_handler(log_entries.append)
driver.find_element(By.ID, "jsException").click()
WebDriverWait(driver, 5).until(lambda _: log_entries)
assert log_entries[0].text == "Error: Not working"
@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
log_entries = []
id = driver.script.add_javascript_error_handler(log_entries.append)
driver.script.remove_javascript_error_handler(id)
driver.find_element(By.ID, "consoleLog").click()
assert len(log_entries) == 0
log_entries = []
/examples/ruby/spec/bidi/logging_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Logging' do
let(:driver) { start_bidi_session }
let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
it 'adds console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_console_message_handler { |log| log_entries << log }
driver.find_element(id: 'consoleLog').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Hello, world!'
end
it 'removes console message handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_console_message_handler { |log| log_entries << log }
driver.script.remove_console_message_handler(id)
driver.find_element(id: 'consoleLog').click
expect(log_entries).to be_empty
end
it 'adds JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.find_element(id: 'jsException').click
wait.until { log_entries.any? }
expect(log_entries.first&.text).to eq 'Error: Not working'
end
it 'removes JavaScript error handler' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
log_entries = []
id = driver.script.add_javascript_error_handler { |error| log_entries << error }
driver.script.remove_javascript_error_handler(id)
driver.find_element(id: 'jsException').click
expect(log_entries).to be_empty
end
end
Last modified September 24, 2026: added webdriver bidi java log code example lines to respective files (#2844) (623d352136)



