Chrome DevTools Logging Features
Logging features using CDP.
Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!
While Selenium 4 provides direct access to the Chrome DevTools Protocol, these methods will eventually be removed when WebDriver BiDi implemented.
Console Logs
((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
Show full example
package dev.selenium.bidi.cdp;
import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;
import dev.selenium.BaseTest;
import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoggingTest extends BaseTest {
@BeforeEach
public void createSession() {
driver = new ChromeDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
@Test
public void consoleLogs() {
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();
((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
driver.findElement(By.id("consoleLog")).click();
driver.findElement(By.id("consoleError")).click();
wait.until(_d -> messages.size() > 1);
Assertions.assertTrue(messages.contains("Hello, world!"));
Assertions.assertTrue(messages.contains("I am console error"));
}
}
async with driver.bidi_connection() as session:
async with Log(driver, session).add_listener(Console.ALL) as messages:
Show full example
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
@pytest.mark.trio
async def test_console_log(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
async with driver.bidi_connection() as session:
async with Log(driver, session).add_listener(Console.ALL) as messages:
driver.find_element(by=By.ID, value='consoleLog').click()
assert messages["message"] == "Hello, world!"
@pytest.mark.trio
async def test_js_error(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
async with driver.bidi_connection() as session:
async with Log(driver, session).add_js_error_listener() as messages:
driver.find_element(by=By.ID, value='jsException').click()
assert "Error: Not working" in messages.exception_details.exception.description
using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
var messages = new List<string>();
monitor.JavaScriptConsoleApiCalled += (_, e) =>
{
messages.Add(e.MessageContent);
};
await monitor.StartEventMonitoring();
Show full example
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
namespace SeleniumDocs.BiDi.CDP
{
[TestClass]
public class LoggingTest : BaseChromeTest
{
[TestMethod]
public async Task ConsoleLogs()
{
driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";
using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
var messages = new List<string>();
monitor.JavaScriptConsoleApiCalled += (_, e) =>
{
messages.Add(e.MessageContent);
};
await monitor.StartEventMonitoring();
driver.FindElement(By.Id("consoleLog")).Click();
driver.FindElement(By.Id("consoleError")).Click();
new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
monitor.StopEventMonitoring();
Assert.IsTrue(messages.Contains("Hello, world!"));
Assert.IsTrue(messages.Contains("I am console error"));
}
[TestMethod]
public async Task JsErrors()
{
driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";
using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
var messages = new List<string>();
monitor.JavaScriptExceptionThrown += (_, e) =>
{
messages.Add(e.Message);
};
await monitor.StartEventMonitoring();
driver.FindElement(By.Id("jsException")).Click();
new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
monitor.StopEventMonitoring();
Assert.IsTrue(messages.Contains("Uncaught"));
}
}
}
driver.on_log_event(:console) { |log| logs << log.args.first }
Show full example
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Logging' do
let(:driver) { start_session }
it 'listens for console logs' do
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
logs = []
driver.on_log_event(:console) { |log| logs << log.args.first }
driver.find_element(id: 'consoleLog').click
driver.find_element(id: 'consoleError').click
Selenium::WebDriver::Wait.new.until { logs.size > 1 }
expect(logs).to include 'Hello, world!'
expect(logs).to include 'I am console error'
end
it 'listens for js exception' do
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
exceptions = []
driver.on_log_event(:exception) { |exception| exceptions << exception }
driver.find_element(id: 'jsException').click
Selenium::WebDriver::Wait.new.until { exceptions.any? }
expect(exceptions.first&.description).to include 'Error: Not working'
end
end
JavaScript Exceptions
async with driver.bidi_connection() as session:
async with Log(driver, session).add_js_error_listener() as messages:
Show full example
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
@pytest.mark.trio
async def test_console_log(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
async with driver.bidi_connection() as session:
async with Log(driver, session).add_listener(Console.ALL) as messages:
driver.find_element(by=By.ID, value='consoleLog').click()
assert messages["message"] == "Hello, world!"
@pytest.mark.trio
async def test_js_error(driver):
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
async with driver.bidi_connection() as session:
async with Log(driver, session).add_js_error_listener() as messages:
driver.find_element(by=By.ID, value='jsException').click()
assert "Error: Not working" in messages.exception_details.exception.description
using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
var messages = new List<string>();
monitor.JavaScriptExceptionThrown += (_, e) =>
{
messages.Add(e.Message);
};
await monitor.StartEventMonitoring();
Show full example
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
namespace SeleniumDocs.BiDi.CDP
{
[TestClass]
public class LoggingTest : BaseChromeTest
{
[TestMethod]
public async Task ConsoleLogs()
{
driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";
using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
var messages = new List<string>();
monitor.JavaScriptConsoleApiCalled += (_, e) =>
{
messages.Add(e.MessageContent);
};
await monitor.StartEventMonitoring();
driver.FindElement(By.Id("consoleLog")).Click();
driver.FindElement(By.Id("consoleError")).Click();
new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
monitor.StopEventMonitoring();
Assert.IsTrue(messages.Contains("Hello, world!"));
Assert.IsTrue(messages.Contains("I am console error"));
}
[TestMethod]
public async Task JsErrors()
{
driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";
using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
var messages = new List<string>();
monitor.JavaScriptExceptionThrown += (_, e) =>
{
messages.Add(e.Message);
};
await monitor.StartEventMonitoring();
driver.FindElement(By.Id("jsException")).Click();
new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
monitor.StopEventMonitoring();
Assert.IsTrue(messages.Contains("Uncaught"));
}
}
}
driver.on_log_event(:exception) { |exception| exceptions << exception }
Show full example
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Logging' do
let(:driver) { start_session }
it 'listens for console logs' do
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
logs = []
driver.on_log_event(:console) { |log| logs << log.args.first }
driver.find_element(id: 'consoleLog').click
driver.find_element(id: 'consoleError').click
Selenium::WebDriver::Wait.new.until { logs.size > 1 }
expect(logs).to include 'Hello, world!'
expect(logs).to include 'I am console error'
end
it 'listens for js exception' do
driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
exceptions = []
driver.on_log_event(:exception) { |exception| exceptions << exception }
driver.find_element(id: 'jsException').click
Selenium::WebDriver::Wait.new.until { exceptions.any? }
expect(exceptions.first&.description).to include 'Error: Not working'
end
end