Outdated Selenium patterns and their current replacements
Selenium 2 and 3 idioms that coding agents and old tutorials still produce, with the current form of each.
Coding agents and old tutorials reproduce Selenium 2 and Selenium 3 idioms,
because that is what most of the published material describes.
Each section below shows one outdated pattern,
when it stopped being the right way to write Selenium,
why, and the current form.
The outdated form is always marked with an Outdated — do not use comment.
Outdated since Selenium 4, which uses the W3C WebDriver standard by default and removes
support for the legacy protocol.
Java Grid also stopped accepting session requests that use the desiredCapabilities keyword in 4.17.
Free-form capability maps predate the W3C standard.
Non-standard capabilities now have to be vendor-prefixed,
and an unprefixed one can stop the session from starting.
The browser Options classes produce a valid payload by construction.
See the upgrade guide
and Browser options.
// Outdated — do not useDesiredCapabilitiescaps=DesiredCapabilities.chrome();caps.setCapability("pageLoadStrategy","eager");WebDriverdriver=newChromeDriver(caps);
# Outdated — do not usecaps=DesiredCapabilities.CHROME.copy()caps["pageLoadStrategy"]="eager"driver=webdriver.Chrome(desired_capabilities=caps)
packagedev.selenium.drivers;importdev.selenium.BaseTest;importjava.time.Duration;importjava.time.temporal.ChronoUnit;importorg.junit.jupiter.api.Test;importorg.junit.jupiter.api.Assertions;importorg.openqa.selenium.PageLoadStrategy;importorg.openqa.selenium.Proxy;importorg.openqa.selenium.UnexpectedAlertBehaviour;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.chrome.ChromeOptions;importorg.openqa.selenium.remote.CapabilityType;importorg.openqa.selenium.chrome.ChromeDriver;publicclassOptionsTestextendsBaseTest{@TestpublicvoidsetPageLoadStrategyNormal(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);WebDriverdriver=newChromeDriver(chromeOptions);try{// Navigate to Urldriver.get("https://selenium.dev");}finally{driver.quit();}}@TestpublicvoidsetPageLoadStrategyEager(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);WebDriverdriver=newChromeDriver(chromeOptions);try{// Navigate to Urldriver.get("https://selenium.dev");}finally{driver.quit();}}@TestpublicvoidsetPageLoadStrategyNone(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);WebDriverdriver=newChromeDriver(chromeOptions);try{// Navigate to Urldriver.get("https://selenium.dev");}finally{driver.quit();}}@TestpublicvoidsetAcceptInsecureCerts(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setAcceptInsecureCerts(true);WebDriverdriver=newChromeDriver(chromeOptions);try{// Navigate to Urldriver.get("https://selenium.dev");}finally{driver.quit();}}@TestpublicvoidgetBrowserName(){ChromeOptionschromeOptions=getDefaultChromeOptions();Stringname=chromeOptions.getBrowserName();Assertions.assertFalse(name.isEmpty(),"Browser name should not be empty");}@TestpublicvoidsetBrowserVersion(){ChromeOptionschromeOptions=getDefaultChromeOptions();Stringversion="latest";chromeOptions.setBrowserVersion(version);Assertions.assertEquals(version,chromeOptions.getBrowserVersion());}@TestpublicvoidsetPlatformName(){ChromeOptionschromeOptions=getDefaultChromeOptions();Stringplatform="OS X 10.6";chromeOptions.setPlatformName(platform);Assertions.assertEquals(platform,chromeOptions.getPlatformName().toString());}@TestpublicvoidsetScriptTimeout(){ChromeOptionschromeOptions=getDefaultChromeOptions();Durationduration=Duration.of(5,ChronoUnit.SECONDS);chromeOptions.setScriptTimeout(duration);WebDriverdriver=newChromeDriver(chromeOptions);try{Durationtimeout=driver.manage().timeouts().getScriptTimeout();Assertions.assertEquals(timeout,duration,"The script timeout should be set to 5 seconds.");}finally{driver.quit();}}@TestpublicvoidsetPageLoadTimeout(){ChromeOptionschromeOptions=getDefaultChromeOptions();Durationduration=Duration.of(5,ChronoUnit.SECONDS);chromeOptions.setPageLoadTimeout(duration);WebDriverdriver=newChromeDriver(chromeOptions);try{Durationtimeout=driver.manage().timeouts().getPageLoadTimeout();Assertions.assertEquals(timeout,duration,"The page load timeout should be set to 5 seconds.");}finally{driver.quit();}}@TestpublicvoidsetImplicitWaitTimeout(){ChromeOptionschromeOptions=getDefaultChromeOptions();Durationduration=Duration.of(5,ChronoUnit.SECONDS);chromeOptions.setImplicitWaitTimeout(duration);WebDriverdriver=newChromeDriver(chromeOptions);try{Durationtimeout=driver.manage().timeouts().getImplicitWaitTimeout();Assertions.assertEquals(timeout,duration,"The implicit wait timeout should be set to 5 seconds.");}finally{driver.quit();}}@TestpublicvoidsetUnhandledPromptBehaviour(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);//verify the capability object is not nullObjectcapabilityObject=chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);Assertions.assertNotNull(capabilityObject,"Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");Assertions.assertEquals(capabilityObject.toString(),UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());}@TestpublicvoidsetWindowRect(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT,true);//verify the capability object is not nullObjectcapabilityObject=chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);Assertions.assertNotNull(capabilityObject,"Capability SET_WINDOW_RECT should not be null.");Booleancapability=(Boolean)capabilityObject;Assertions.assertTrue(capability,"The capability SET_WINDOW_RECT should be set to true.");}@TestpublicvoidsetStrictFileInteractability(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY,true);//verify the capability object is not nullObjectcapabilityObject=chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);Assertions.assertNotNull(capabilityObject,"Capability STRICT_FILE_INTERACTABILITY should not be null.");Booleancapability=(Boolean)capabilityObject;Assertions.assertTrue(capability,"The capability STRICT_FILE_INTERACTABILITY should be set to true.");}@TestpublicvoidsetsProxy(){Proxyproxy=newProxy();proxy.setHttpProxy("myproxy.com:8080");ChromeOptionsoptions=getDefaultChromeOptions();options.setCapability("proxy",proxy);ObjectcapabilityObject=options.getCapability("proxy");Assertions.assertNotNull(capabilityObject,"Capability proxy should not be null.");Assertions.assertEquals("myproxy.com:8080",((Proxy)capabilityObject).getHttpProxy());}}
fromseleniumimportwebdriverfromselenium.webdriver.common.proxyimportProxyfromselenium.webdriver.common.proxyimportProxyTypedeftest_page_load_strategy_normal():options=get_default_chrome_options()options.page_load_strategy='normal'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_page_load_strategy_eager():options=get_default_chrome_options()options.page_load_strategy='eager'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_page_load_strategy_none():options=get_default_chrome_options()options.page_load_strategy='none'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_timeouts_script():options=get_default_chrome_options()options.timeouts={'script':5000}driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_timeouts_page_load():options=get_default_chrome_options()options.timeouts={'pageLoad':5000}driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_timeouts_implicit_wait():options=get_default_chrome_options()options.timeouts={'implicit':5000}driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_unhandled_prompt():options=get_default_chrome_options()options.unhandled_prompt_behavior='accept'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_set_window_rect():options=webdriver.FirefoxOptions()options.set_window_rect=True# Full support in Firefoxdriver=webdriver.Firefox(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_strict_file_interactability():options=get_default_chrome_options()options.strict_file_interactability=Truedriver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_proxy():options=get_default_chrome_options()options.proxy=Proxy({'proxyType':ProxyType.MANUAL,'httpProxy':'http.proxy:1234'})driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_set_browser_name():options=get_default_chrome_options()assertoptions.capabilities['browserName']=='chrome'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_set_browser_version():options=get_default_chrome_options()options.browser_version='stable'assertoptions.capabilities['browserVersion']=='stable'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_platform_name():options=get_default_chrome_options()options.platform_name='any'driver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()deftest_accept_insecure_certs():options=get_default_chrome_options()options.accept_insecure_certs=Truedriver=webdriver.Chrome(options=options)driver.get("https://www.selenium.dev/")driver.quit()defget_default_chrome_options():options=webdriver.ChromeOptions()options.add_argument("--no-sandbox")returnoptions
Manual driver downloads and driver managers
Superseded in Selenium 4.6, when Selenium Manager began shipping with every Selenium release.
Since 4.11 Selenium Manager can also download the browser.
Setting a path to chromedriver, putting a driver on the PATH by hand,
or adding a third-party driver manager adds a second, slower source of truth
for which driver version to use.
There is nothing to write:
start the driver and Selenium Manager finds or downloads the matching one.
See Selenium Manager.
// Outdated — do not useWebDriverManager.chromedriver().setup();System.setProperty("webdriver.chrome.driver","/path/to/chromedriver");WebDriverdriver=newChromeDriver();
# Outdated — do not usefromwebdriver_manager.chromeimportChromeDriverManagerdriver=webdriver.Chrome(ChromeDriverManager().install())
packagedev.selenium.selenium_manager;importorg.junit.jupiter.api.Disabled;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.chrome.ChromeDriver;publicclassSeleniumManagerUsageDemo{@Test@Disabled("This test is just for demo purposes and should not be run in CI")publicvoidtestSetupWithoutManager(){System.setProperty("webdriver.chrome.driver","/path/to/chromedriver");WebDriverdriver=newChromeDriver();driver.get("https://www.selenium.dev/documentation/selenium_manager/");driver.quit();}@TestpublicvoidtestSetupWithManager(){WebDriverdriver=newChromeDriver();driver.get("https://www.selenium.dev/documentation/selenium_manager/");driver.quit();}}
Never good practice.
Fixed sleeps were bad advice before Selenium 4 and are bad advice now.
A fixed sleep is either too short, and the test fails,
or too long, and the suite crawls.
Wait for the condition the next line depends on instead.
See Waiting strategies.
// Outdated — do not usedriver.findElement(By.id("adder")).click();Thread.sleep(5000);WebElementadded=driver.findElement(By.id("box0"));
# Outdated — do not usedriver.find_element(By.ID,"adder").click()time.sleep(5)added=driver.find_element(By.ID,"box0")
Never good practice.
An absolute path describes where an element sits in today’s markup,
so it breaks on the next front-end change.
Prefer an id or name, then a CSS selector on a stable attribute.
When an element has no usable locator but is easy to describe by position,
use a relative locator.
See Locator strategies.
// Outdated — do not usedriver.findElement(By.xpath("/html/body/div[2]/div[1]/form/div[3]/input"));
# Outdated — do not usedriver.find_element(By.XPATH,"/html/body/div[2]/div[1]/form/div[3]/input")
importjava.util.List;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.By;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeDriver;importorg.openqa.selenium.support.pagefactory.ByAll;importorg.openqa.selenium.support.pagefactory.ByChained;publicclassLocatorTest{privateWebDriverdriver;@BeforeEachpublicvoidsetUp(){// Initialize the driver before each testdriver=newChromeDriver();driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html");}@AfterEachpublicvoidtearDown(){// Close the browser after each testif(driver!=null){driver.quit();}}@TestpublicvoidtestClassName(){WebElementelement=driver.findElement(By.className("information"));Assertions.assertNotNull(element);Assertions.assertEquals("input",element.getTagName());}@TestpublicvoidtestCssSelector(){WebElementelement=driver.findElement(By.cssSelector("#fname"));Assertions.assertNotNull(element);Assertions.assertEquals("Jane",element.getAttribute("value"));}@TestpublicvoidtestId(){WebElementelement=driver.findElement(By.id("lname"));Assertions.assertNotNull(element);Assertions.assertEquals("Doe",element.getAttribute("value"));}@TestpublicvoidtestName(){WebElementelement=driver.findElement(By.name("newsletter"));Assertions.assertNotNull(element);Assertions.assertEquals("input",element.getTagName());}@TestpublicvoidtestLinkText(){WebElementelement=driver.findElement(By.linkText("Selenium Official Page"));Assertions.assertNotNull(element);Assertions.assertEquals("https://www.selenium.dev/",element.getAttribute("href"));}@TestpublicvoidtestPartialLinkText(){WebElementelement=driver.findElement(By.partialLinkText("Official Page"));Assertions.assertNotNull(element);Assertions.assertEquals("https://www.selenium.dev/",element.getAttribute("href"));}@TestpublicvoidtestTagName(){WebElementelement=driver.findElement(By.tagName("a"));Assertions.assertNotNull(element);Assertions.assertEquals("https://www.selenium.dev/",element.getAttribute("href"));}@TestpublicvoidtestXpath(){WebElementelement=driver.findElement(By.xpath("//input[@value='f']"));Assertions.assertNotNull(element);Assertions.assertEquals("radio",element.getAttribute("type"));}@TestpublicvoidtestByAll(){driver.get("https://www.selenium.dev/selenium/web/login.html");Bylocator=newByAll(By.id("password-field"),By.id("username-field"));List<WebElement>loginInputs=driver.findElements(locator);Assertions.assertEquals(2,loginInputs.size());}@TestpublicvoidtestByChained(){driver.get("https://www.selenium.dev/selenium/web/login.html");Bylocator=newByChained(By.id("login-form"),By.tagName("input"));WebElementusernameInput=driver.findElement(locator);Assertions.assertEquals("Username",usernameInput.getAttribute("placeholder"));}}
importpytestfromseleniumimportwebdriverfromselenium.webdriver.common.byimportBydeftest_class_name():driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.CLASS_NAME,"information")assertelementisnotNoneassertelement.tag_name=="input"driver.quit()deftest_css_selector(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.CSS_SELECTOR,"#fname")assertelementisnotNoneassertelement.get_attribute("value")=="Jane"driver.quit()deftest_id(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.ID,"lname")assertelementisnotNoneassertelement.get_attribute("value")=="Doe"driver.quit()deftest_name(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.NAME,"newsletter")assertelementisnotNoneassertelement.tag_name=="input"driver.quit()deftest_link_text(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.LINK_TEXT,"Selenium Official Page")assertelementisnotNoneassertelement.get_attribute("href")=="https://www.selenium.dev/"driver.quit()deftest_partial_link_text(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.PARTIAL_LINK_TEXT,"Official Page")assertelementisnotNoneassertelement.get_attribute("href")=="https://www.selenium.dev/"driver.quit()deftest_tag_name(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.TAG_NAME,"a")assertelementisnotNoneassertelement.get_attribute("href")=="https://www.selenium.dev/"driver.quit()deftest_xpath(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.XPATH,"//input[@value='f']")assertelementisnotNoneassertelement.get_attribute("type")=="radio"driver.quit()
Superseded in Selenium 4.
The Python bindings announced the removal of find_element_by_* and find_elements_by_*
after Selenium 4.2.
The Java findElementBy* helpers were removed in Selenium 4.
importjava.util.List;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.By;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeDriver;importorg.openqa.selenium.support.pagefactory.ByAll;importorg.openqa.selenium.support.pagefactory.ByChained;publicclassLocatorTest{privateWebDriverdriver;@BeforeEachpublicvoidsetUp(){// Initialize the driver before each testdriver=newChromeDriver();driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html");}@AfterEachpublicvoidtearDown(){// Close the browser after each testif(driver!=null){driver.quit();}}@TestpublicvoidtestClassName(){WebElementelement=driver.findElement(By.className("information"));Assertions.assertNotNull(element);Assertions.assertEquals("input",element.getTagName());}@TestpublicvoidtestCssSelector(){WebElementelement=driver.findElement(By.cssSelector("#fname"));Assertions.assertNotNull(element);Assertions.assertEquals("Jane",element.getAttribute("value"));}@TestpublicvoidtestId(){WebElementelement=driver.findElement(By.id("lname"));Assertions.assertNotNull(element);Assertions.assertEquals("Doe",element.getAttribute("value"));}@TestpublicvoidtestName(){WebElementelement=driver.findElement(By.name("newsletter"));Assertions.assertNotNull(element);Assertions.assertEquals("input",element.getTagName());}@TestpublicvoidtestLinkText(){WebElementelement=driver.findElement(By.linkText("Selenium Official Page"));Assertions.assertNotNull(element);Assertions.assertEquals("https://www.selenium.dev/",element.getAttribute("href"));}@TestpublicvoidtestPartialLinkText(){WebElementelement=driver.findElement(By.partialLinkText("Official Page"));Assertions.assertNotNull(element);Assertions.assertEquals("https://www.selenium.dev/",element.getAttribute("href"));}@TestpublicvoidtestTagName(){WebElementelement=driver.findElement(By.tagName("a"));Assertions.assertNotNull(element);Assertions.assertEquals("https://www.selenium.dev/",element.getAttribute("href"));}@TestpublicvoidtestXpath(){WebElementelement=driver.findElement(By.xpath("//input[@value='f']"));Assertions.assertNotNull(element);Assertions.assertEquals("radio",element.getAttribute("type"));}@TestpublicvoidtestByAll(){driver.get("https://www.selenium.dev/selenium/web/login.html");Bylocator=newByAll(By.id("password-field"),By.id("username-field"));List<WebElement>loginInputs=driver.findElements(locator);Assertions.assertEquals(2,loginInputs.size());}@TestpublicvoidtestByChained(){driver.get("https://www.selenium.dev/selenium/web/login.html");Bylocator=newByChained(By.id("login-form"),By.tagName("input"));WebElementusernameInput=driver.findElement(locator);Assertions.assertEquals("Username",usernameInput.getAttribute("placeholder"));}}
importpytestfromseleniumimportwebdriverfromselenium.webdriver.common.byimportBydeftest_class_name():driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.CLASS_NAME,"information")assertelementisnotNoneassertelement.tag_name=="input"driver.quit()deftest_css_selector(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.CSS_SELECTOR,"#fname")assertelementisnotNoneassertelement.get_attribute("value")=="Jane"driver.quit()deftest_id(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.ID,"lname")assertelementisnotNoneassertelement.get_attribute("value")=="Doe"driver.quit()deftest_name(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.NAME,"newsletter")assertelementisnotNoneassertelement.tag_name=="input"driver.quit()deftest_link_text(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.LINK_TEXT,"Selenium Official Page")assertelementisnotNoneassertelement.get_attribute("href")=="https://www.selenium.dev/"driver.quit()deftest_partial_link_text(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.PARTIAL_LINK_TEXT,"Official Page")assertelementisnotNoneassertelement.get_attribute("href")=="https://www.selenium.dev/"driver.quit()deftest_tag_name(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.TAG_NAME,"a")assertelementisnotNoneassertelement.get_attribute("href")=="https://www.selenium.dev/"driver.quit()deftest_xpath(driver):driver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")element=driver.find_element(By.XPATH,"//input[@value='f']")assertelementisnotNoneassertelement.get_attribute("type")=="radio"driver.quit()
executable_path
Deprecated in Selenium 4 in favour of a Service object.
In Python, the executable_path argument to the driver constructor is the outdated form.
A path belongs on a Service.
Most projects do not need one at all, because Selenium Manager finds the driver;
see driver management above.
See the upgrade guide
and Driver service.
# Outdated — do not usedriver=webdriver.Chrome(executable_path="/path/to/chromedriver",options=options)
Current form, when a specific driver binary is really needed:
Temporary by design.
The CDP pages describe Selenium’s Chrome DevTools Protocol
support as temporary until WebDriver BiDi is implemented.
Firefox CDP support was deprecated in 4.27 and 4.28 and fully removed in 4.29.
The Chrome DevTools Protocol is Chromium-only and has no stable API between browser versions.
WebDriver BiDi is the W3C standard that replaces it,
and it works across browsers.
// Outdated — do not useDevToolsdevTools=((HasDevTools)driver).getDevTools();devTools.createSession();devTools.send(Log.enable());devTools.addListener(Log.entryAdded(),entry->System.out.println(entry.getText()));
# Outdated — do not usedriver.execute_cdp_cmd("Log.enable",{})
Current form, listening to console logs with BiDi:
packagedev.selenium.bidirectional.webdriver_bidi;importdev.selenium.BaseTest;importjava.time.Duration;importjava.util.concurrent.*;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.By;importorg.openqa.selenium.bidi.module.LogInspector;importorg.openqa.selenium.bidi.log.ConsoleLogEntry;importorg.openqa.selenium.bidi.log.JavascriptLogEntry;importorg.openqa.selenium.bidi.log.LogLevel;importorg.openqa.selenium.bidi.log.StackTrace;importorg.openqa.selenium.firefox.FirefoxDriver;importorg.openqa.selenium.firefox.FirefoxOptions;importorg.openqa.selenium.support.ui.WebDriverWait;classLogTestextendsBaseTest{@BeforeEachpublicvoidsetup(){FirefoxOptionsoptions=newFirefoxOptions();options.setCapability("webSocketUrl",true);driver=newFirefoxDriver(options);}@TestvoidtestListenToConsoleLog()throwsExecutionException,InterruptedException,TimeoutException{try(LogInspectorlogInspector=newLogInspector(driver)){CompletableFuture<ConsoleLogEntry>future=newCompletableFuture<>();logInspector.onConsoleEntry(future::complete);driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");driver.findElement(By.id("consoleLog")).click();ConsoleLogEntrylogEntry=future.get(5,TimeUnit.SECONDS);Assertions.assertEquals("Hello, world!",logEntry.getText());Assertions.assertEquals(1,logEntry.getArgs().size());Assertions.assertEquals("console",logEntry.getType());Assertions.assertEquals("log",logEntry.getMethod());Assertions.assertEquals("helloWorld",logEntry.getStackTrace().getCallFrames().get(0).getFunctionName());}}@TestvoidtestListenToJavascriptLog()throwsExecutionException,InterruptedException,TimeoutException{try(LogInspectorlogInspector=newLogInspector(driver)){CompletableFuture<JavascriptLogEntry>future=newCompletableFuture<>();logInspector.onJavaScriptLog(future::complete);driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");driver.findElement(By.id("jsException")).click();JavascriptLogEntrylogEntry=future.get(5,TimeUnit.SECONDS);Assertions.assertEquals("Error: Not working",logEntry.getText());Assertions.assertEquals("javascript",logEntry.getType());Assertions.assertEquals(LogLevel.ERROR,logEntry.getLevel());}}@TestvoidtestListenToJavascriptErrorLog()throwsExecutionException,InterruptedException,TimeoutException{try(LogInspectorlogInspector=newLogInspector(driver)){CompletableFuture<JavascriptLogEntry>future=newCompletableFuture<>();logInspector.onJavaScriptException(future::complete);driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");driver.findElement(By.id("jsException")).click();JavascriptLogEntrylogEntry=future.get(5,TimeUnit.SECONDS);Assertions.assertEquals("Error: Not working",logEntry.getText());Assertions.assertEquals("javascript",logEntry.getType());}}@TestvoidtestRetrieveStacktraceForALog()throwsExecutionException,InterruptedException,TimeoutException{try(LogInspectorlogInspector=newLogInspector(driver)){CompletableFuture<JavascriptLogEntry>future=newCompletableFuture<>();logInspector.onJavaScriptException(future::complete);driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");driver.findElement(By.id("logWithStacktrace")).click();JavascriptLogEntrylogEntry=future.get(5,TimeUnit.SECONDS);StackTracestackTrace=logEntry.getStackTrace();Assertions.assertNotNull(stackTrace);Assertions.assertEquals(3,stackTrace.getCallFrames().size());}}@TestvoidtestListenToLogsWithMultipleConsumers()throwsExecutionException,InterruptedException,TimeoutException{try(LogInspectorlogInspector=newLogInspector(driver)){CompletableFuture<JavascriptLogEntry>completableFuture1=newCompletableFuture<>();logInspector.onJavaScriptLog(completableFuture1::complete);CompletableFuture<JavascriptLogEntry>completableFuture2=newCompletableFuture<>();logInspector.onJavaScriptLog(completableFuture2::complete);driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");driver.findElement(By.id("jsException")).click();JavascriptLogEntrylogEntry=completableFuture1.get(5,TimeUnit.SECONDS);Assertions.assertEquals("Error: Not working",logEntry.getText());Assertions.assertEquals("javascript",logEntry.getType());logEntry=completableFuture2.get(5,TimeUnit.SECONDS);Assertions.assertEquals("Error: Not working",logEntry.getText());Assertions.assertEquals("javascript",logEntry.getType());}}}
importpytestfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.waitimportWebDriverWait@pytest.mark.driver_type("bidi")deftest_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)assertlog_entries[0].text=="Hello, world!"@pytest.mark.driver_type("bidi")deftest_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()assertlen(log_entries)==0@pytest.mark.driver_type("bidi")deftest_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)assertlog_entries[0].text=="Error: Not working"@pytest.mark.driver_type("bidi")deftest_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()assertlen(log_entries)==0