The rest of this documentation is organised by API surface: elements, interactions, waits,
BiDi, and so on. That is the right shape for looking something up once you know what it is
called, but most people arrive with a problem rather than a method name.
The guides in this section are organised by task instead. Each one states the problem,
describes the approach the Selenium project recommends, shows the shortest working example
for each language binding, lists the errors you are most likely to hit along the way, and
links to the reference pages that cover the detail. They do not replace the reference pages;
they are the fastest route into them.
If you are new to Selenium altogether, start with
Getting started and come back here
once you have a first script running.
1 - Waiting for things to happen
Synchronising your code with the page using explicit waits and expected conditions, and why a fixed sleep is the wrong tool.
Your script clicks a button, and the next line fails because the element it needs has not
appeared yet. Run it again and it passes. Modern applications update the page asynchronously,
so the browser and your code are in a race, and the loser is a flaky test.
Recommended approach
Use an explicit wait: a loop that polls the application for a specific condition and
continues as soon as that condition is true, or raises a timeout error if it never is. You
decide what to wait for at each point where synchronisation matters, so the wait is exactly as
long as it needs to be and no longer.
Most bindings ship a library of ready-made expected conditions (element visible, title
contains, alert present, and so on) that you can pass to the wait instead of writing your own
lambda. Each of them is a function that is called repeatedly until it returns a truthy value.
A fixed sleep is the first thing many people reach for, and it is nearly always wrong. It is
either too short, and the test fails on a slow machine, or too long, and every test in the
suite pays the full price every time. Likewise, do not combine an implicit wait with explicit
waits: the two timeouts add up in ways that are hard to predict.
This example waits for an element that is revealed a couple of seconds after a click:
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Waits'dolet(:driver){start_session}it'fails'dodriver.get'https://www.selenium.dev/selenium/web/dynamic.html'driver.find_element(id:'adder').clickexpect{driver.find_element(id:'box0')}.toraise_error(Selenium::WebDriver::Error::NoSuchElementError)endit'sleeps'dodriver.get'https://www.selenium.dev/selenium/web/dynamic.html'driver.find_element(id:'adder').clicksleep1added=driver.find_element(id:'box0')expect(added.dom_attribute(:class)).toeq('redbox')endit'implicit'dodriver.manage.timeouts.implicit_wait=2driver.get'https://www.selenium.dev/selenium/web/dynamic.html'driver.find_element(id:'adder').clickadded=driver.find_element(id:'box0')expect(added.dom_attribute(:class)).toeq('redbox')endit'explicit'dodriver.get'https://www.selenium.dev/selenium/web/dynamic.html'revealed=driver.find_element(id:'revealed')driver.find_element(id:'reveal').clickwait=Selenium::WebDriver::Wait.newwait.until{revealed.displayed?}revealed.send_keys('Displayed')expect(revealed.property(:value)).toeq('Displayed')endit'options with explicit'dodriver.get'https://www.selenium.dev/selenium/web/dynamic.html'revealed=driver.find_element(id:'revealed')driver.find_element(id:'reveal').clickerrors=[Selenium::WebDriver::Error::NoSuchElementError,Selenium::WebDriver::Error::ElementNotInteractableError]wait=Selenium::WebDriver::Wait.new(timeout:2,interval:0.3,ignore:errors)wait.until{revealed.send_keys('Displayed')||true}expect(revealed.property(:value)).toeq('Displayed')endend
Choosing a locator strategy that survives the next release of the application, and avoiding the ones that do not.
A locator copied out of the browser’s developer tools works today and breaks the first time a
designer moves a div. Tests then fail for reasons that have nothing to do with the behaviour
they were written to check, and the suite stops being trusted.
Recommended approach
Prefer locators that describe what an element is over locators that describe where it
happens to sit in the document, roughly in this order:
id, when the page has stable, unique ids. This is the fastest and most readable choice.
name, for form fields, which tend to keep their names because the server depends on them.
CSS selector, for everything else. A short selector anchored on an id, a data attribute,
or a meaningful class is both fast and expressive.
Relative locators, when the target has no stable attributes of its own but a nearby
element does: find the input below a given label, or the button to the right of a field.
Avoid absolute XPath (/html/body/div[3]/...). It encodes the entire structure of the page, so
any change above the element breaks it, and it is slow in some browsers. XPath itself is fine
when you need it, for example to match on text content, but keep the expression short and
anchored.
If the application does not expose stable attributes, ask for them. A data-test attribute
costs the developers nothing and removes an entire class of failures.
importpytestfromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy# The tests below marked as skipped mirror the HTML snippet shown at the top of the# "Finding web elements" documentation and are illustrative only, matching how the# same examples are shown for the other language bindings:## <ol id="vegetables"># <li class="potatoes">…# <li class="onions">…# <li class="tomatoes"><span>Tomato is a Vegetable</span>…# </ol># <ul id="fruits"># <li class="bananas">…# <li class="apples">…# <li class="tomatoes"><span>Tomato is a Fruit</span>…# </ul>@pytest.mark.skip(reason="illustrative example, not an executable test")deftest_basic_finders(driver):vegetable=driver.find_element(By.CLASS_NAME,'tomatoes')@pytest.mark.skip(reason="illustrative example, not an executable test")deftest_subset_of_dom(driver):fruits=driver.find_element(By.ID,'fruits')fruit=fruits.find_element(By.CLASS_NAME,'tomatoes')@pytest.mark.skip(reason="illustrative example, not an executable test")deftest_optimized_locator(driver):fruit=driver.find_element(By.CSS_SELECTOR,'#fruits .tomatoes')@pytest.mark.skip(reason="illustrative example, not an executable test")deftest_all_matching_elements(driver):plants=driver.find_elements(By.TAG_NAME,'li')deftest_evaluating_shadow_dom():driver=webdriver.Chrome()driver.implicitly_wait(5)driver.get('https://www.selenium.dev/selenium/web/shadowRootPage.html')shadow_host=driver.find_element(By.TAG_NAME,'custom-checkbox-element')shadow_root=shadow_host.shadow_rootassertshadow_rootshadow_content=shadow_root.find_element(By.CSS_SELECTOR,'input[type=checkbox]')assertshadow_host.is_displayed()assertshadow_content.is_displayed()driver.quit()deftest_get_element():driver=webdriver.Chrome()driver.get('https://www.example.com')elements=driver.find_elements(By.TAG_NAME,'p')forelementinelements:print(element.text)assertlen(elements)>0driver.quit()deftest_find_elements_from_element():driver=webdriver.Chrome()driver.get('https://www.example.com')element=driver.find_element(By.TAG_NAME,'div')elements=element.find_elements(By.TAG_NAME,'p')foreinelements:print(e.text)assertlen(elements)>0driver.quit()deftest_get_active_element():driver=webdriver.Chrome()driver.get('https://www.selenium.dev/selenium/web/web-form.html')driver.find_element(By.CSS_SELECTOR,'[name="my-text"]').send_keys('webElement')attr=driver.switch_to.active_element.get_attribute('name')assertattr=='my-text'driver.quit()
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Element Finders'dolet(:driver){start_session}context'without executing finders',skip:'these are just examples, not actual tests'doit'finds the first matching element'dodriver.find_element(class:'tomatoes')endit'uses a subset of the dom to find an element'dofruits=driver.find_element(id:'fruits')fruits.find_element(class:'tomatoes')endit'uses an optimized locator'dodriver.find_element(css:'#fruits .tomatoes')endit'finds all matching elements'dodriver.find_elements(tag_name:'li')endit'gets an element from a collection'doelements=driver.find_elements(:tag_name,'p')elements.each{|e|putse.text}endit'finds element from element'doelement=driver.find_element(:tag_name,'div')elements=element.find_elements(:tag_name,'p')elements.each{|e|putse.text}endit'find active element'dodriver.find_element(css:'[name="q"]').send_keys('webElement')driver.switch_to.active_element.attribute('title')endendend
const{Builder,By}=require('selenium-webdriver');constassert=require('assert');constLOCATORS_PAGE='https://www.selenium.dev/selenium/web/locators_tests/locators.html';describe('Finders',function(){it('finds the first matching element',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);constfirstInput=awaitdriver.findElement(By.className('information'));assert.equal(awaitfirstInput.getAttribute('id'),'fname');awaitdriver.quit();});it('finds an element within a subset of the DOM',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);constform=awaitdriver.findElement(By.tagName('form'));constinput=awaitform.findElement(By.className('information'));assert.equal(awaitinput.getAttribute('id'),'fname');awaitdriver.quit();});it('uses an optimized locator',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);constinput=awaitdriver.findElement(By.css('form .information'));assert.equal(awaitinput.getAttribute('id'),'fname');awaitdriver.quit();});it('finds all matching elements',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);constinputs=awaitdriver.findElements(By.tagName('input'));assert.ok(inputs.length>1);awaitdriver.quit();});it('gets an element from a collection',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);constelements=awaitdriver.findElements(By.tagName('p'));for(constelementofelements){console.log('Paragraph text:'+awaitelement.getText());}assert.ok(elements.length>0);awaitdriver.quit();});it('finds elements from an element',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);constform=awaitdriver.findElement(By.css('form'));constelements=awaitform.findElements(By.css('input'));for(consteofelements){console.log(awaite.getAttribute('value'));}assert.ok(elements.length>0);awaitdriver.quit();});it('gets the active element',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get(LOCATORS_PAGE);awaitdriver.findElement(By.css('#fname')).sendKeys('webElement');constattr=awaitdriver.switchTo().activeElement().getAttribute('name');assert.equal(attr,'fname');awaitdriver.quit();});});
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;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"));}}
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()
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Element Locators',skip:'These are reference following the documentation example'doit'finds element by class name'dodriver.find_element(class:'information')endit'finds element by css selector'dodriver.find_element(css:'#fname')endit'finds element by id'dodriver.find_element(id:'lname')endit'find element by name'dodriver.find_element(name:'newsletter')endit'finds element by link text'dodriver.find_element(link_text:'Selenium Official Page')endit'finds element by partial link text'dodriver.find_element(partial_link_text:'Official Page')endit'finds element by tag name'dodriver.find_element(tag_name:'a')endit'finds element by xpath'dodriver.find_element(xpath:"//input[@value='f']")endcontext'with relative locators'doit'finds element above'dodriver.find_element({relative:{tag_name:'input',above:{id:'password'}}})endit'finds element below'dodriver.find_element({relative:{tag_name:'input',below:{id:'email'}}})endit'finds element to the left'dodriver.find_element({relative:{tag_name:'button',left:{id:'submit'}}})endit'finds element to the right'dodriver.find_element({relative:{tag_name:'button',right:{id:'cancel'}}})endit'finds near element'dodriver.find_element({relative:{tag_name:'input',near:{id:'lbl-email'}}})endit'chains relative locators'dodriver.find_element({relative:{tag_name:'button',below:{id:'email'},right:{id:'cancel'}}})endendend
const{By,Builder}=require('selenium-webdriver');constassert=require("assert");describe('Element Locator Test',function(){it('Check if element can be found by class name',async()=>{letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.className('information'));consttag=awaitelement.getTagName();constid=awaitelement.getAttribute("id");constvalue=awaitelement.getAttribute("value");assert.equal(tag,"input");assert.equal(id,"fname");assert.equal(value,"Jane");awaitdriver.quit();});it('Check if element can be found by css selector',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.css('#fname'));consttag=awaitelement.getTagName();constid=awaitelement.getAttribute("id");constvalue=awaitelement.getAttribute("value");assert.equal(tag,"input");assert.equal(id,"fname");assert.equal(value,"Jane");awaitdriver.quit();});it('Check if element can be found by id',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.id('lname'));consttag=awaitelement.getTagName();constid=awaitelement.getAttribute("id");constvalue=awaitelement.getAttribute("value");assert.equal(tag,"input");assert.equal(id,"lname");assert.equal(value,"Doe");awaitdriver.quit();});it('Check if element can be found by name',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.name("newsletter"));consttag=awaitelement.getTagName();consttype=awaitelement.getAttribute("type");constvalue=awaitelement.getAttribute("value");assert.equal(tag,"input");assert.equal(type,"checkbox");assert.equal(value,"1");awaitdriver.quit();});it('Check if element can be found by link text',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.linkText("Selenium Official Page"));consttag=awaitelement.getTagName();consthref=awaitelement.getAttribute("href");assert.equal(tag,"a");assert.equal(href,"https://www.selenium.dev/");awaitdriver.quit();});it('Check if element can be found by partial link text',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.partialLinkText("Official Page"));consttag=awaitelement.getTagName();consthref=awaitelement.getAttribute("href");assert.equal(tag,"a");assert.equal(href,"https://www.selenium.dev/");awaitdriver.quit();});it('Check if element can be found by tag name',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.tagName("a"));consttag=awaitelement.getTagName();consttext=awaitelement.getText();assert.equal(tag,"a");assert.equal(text,"Selenium Official Page");awaitdriver.quit();});it('Check if element can be found by xpath',asyncfunction(){letdriver=awaitnewBuilder().forBrowser('chrome').build();awaitdriver.get('https://www.selenium.dev/selenium/web/locators_tests/locators.html');constelement=awaitdriver.findElement(By.xpath('//input[@value="f"]'));consttag=awaitelement.getTagName();consttype=awaitelement.getAttribute("type");constvalue=awaitelement.getAttribute("value");assert.equal(tag,"input");assert.equal(type,"radio");assert.equal(value,"f");awaitdriver.quit();});});
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Element Locators',skip:'These are reference following the documentation example'doit'finds element by class name'dodriver.find_element(class:'information')endit'finds element by css selector'dodriver.find_element(css:'#fname')endit'finds element by id'dodriver.find_element(id:'lname')endit'find element by name'dodriver.find_element(name:'newsletter')endit'finds element by link text'dodriver.find_element(link_text:'Selenium Official Page')endit'finds element by partial link text'dodriver.find_element(partial_link_text:'Official Page')endit'finds element by tag name'dodriver.find_element(tag_name:'a')endit'finds element by xpath'dodriver.find_element(xpath:"//input[@value='f']")endcontext'with relative locators'doit'finds element above'dodriver.find_element({relative:{tag_name:'input',above:{id:'password'}}})endit'finds element below'dodriver.find_element({relative:{tag_name:'input',below:{id:'email'}}})endit'finds element to the left'dodriver.find_element({relative:{tag_name:'button',left:{id:'submit'}}})endit'finds element to the right'dodriver.find_element({relative:{tag_name:'button',right:{id:'cancel'}}})endit'finds near element'dodriver.find_element({relative:{tag_name:'input',near:{id:'lbl-email'}}})endit'chains relative locators'dodriver.find_element({relative:{tag_name:'button',below:{id:'email'},right:{id:'cancel'}}})endendend
Common errors
NoSuchElementException:
nothing matched. Check the locator, check that you are in the right frame, and check that the
element exists yet (see Waiting).
InvalidSelectorException:
the CSS or XPath expression is malformed, or an XPath expression returns something that is not an element.
Getting past a login once, answering HTTP basic authentication prompts, and reusing a signed-in state across tests without driving the login form every time.
Almost every test starts behind a login. Driving the login form in each test is slow, it makes
every test depend on the login page working, and some forms (two-factor prompts, third-party
identity providers, CAPTCHAs) cannot be automated at all. HTTP basic authentication is a
different problem again: the browser shows a native dialog that WebDriver cannot see.
Recommended approach
Log in through the user interface in exactly one test, the one that tests the login form.
Everywhere else, establish the session some other way and start the test already signed in.
For cookie-based sessions, navigate to the application’s domain, add the session cookie with
WebDriver’s cookie API, and reload. The cookie must be added while the browser is on a page in
the domain the cookie belongs to, otherwise the browser rejects it. Where the cookie comes from
is up to you: an API call that logs in, a fixture created on the server, or a value captured
from a single interactive login.
For HTTP basic authentication, use the network module of WebDriver BiDi. Register a handler
for the authRequired phase and answer it with the credentials; the browser never shows the
dialog. Embedding credentials in the URL (https://user:pass@host/) is blocked by modern
browsers and should not be relied on.
Keep tests independent: each test should set up the state it needs rather than inheriting it
from the one before, and a fresh browser per test is the simplest way to guarantee that.
Add a cookie to the current browsing context:
driver.get("https://www.selenium.dev/selenium/web/blank.html");// Add cookie into current browser contextdriver.manage().addCookie(newCookie("key","value"));
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.packagedev.selenium.interactions;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Test;importorg.junit.jupiter.api.Assertions;importorg.openqa.selenium.Cookie;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.chrome.ChromeDriver;importjava.util.Set;publicclassCookiesTest{WebDriverdriver=newChromeDriver();@AfterEachfinalvoidcloseBrowser(){if(driver!=null){driver.quit();}}@TestpublicvoidaddCookie(){driver.get("https://www.selenium.dev/selenium/web/blank.html");// Add cookie into current browser contextdriver.manage().addCookie(newCookie("key","value"));}@TestpublicvoidgetNamedCookie(){driver.get("https://www.selenium.dev/selenium/web/blank.html");// Add cookie into current browser contextdriver.manage().addCookie(newCookie("foo","bar"));// Get cookie details with named cookie 'foo'Cookiecookie=driver.manage().getCookieNamed("foo");Assertions.assertEquals(cookie.getValue(),"bar");}@TestpublicvoidgetAllCookies(){driver.get("https://www.selenium.dev/selenium/web/blank.html");// Add cookies into current browser contextdriver.manage().addCookie(newCookie("test1","cookie1"));driver.manage().addCookie(newCookie("test2","cookie2"));// Get cookiesSet<Cookie>cookies=driver.manage().getCookies();for(Cookiecookie:cookies){if(cookie.getName().equals("test1")){Assertions.assertEquals(cookie.getValue(),"cookie1");}if(cookie.getName().equals("test2")){Assertions.assertEquals(cookie.getValue(),"cookie2");}}}@TestpublicvoiddeleteCookieNamed(){driver.get("https://www.selenium.dev/selenium/web/blank.html");driver.manage().addCookie(newCookie("test1","cookie1"));// delete cookie nameddriver.manage().deleteCookieNamed("test1");}@TestpublicvoiddeleteCookieObject(){driver.get("https://www.selenium.dev/selenium/web/blank.html");Cookiecookie=newCookie("test2","cookie2");driver.manage().addCookie(cookie);/*
Selenium Java bindings also provides a way to delete
cookie by passing cookie object of current browsing context
*/driver.manage().deleteCookie(cookie);}@TestpublicvoiddeleteAllCookies(){driver.get("https://www.selenium.dev/selenium/web/blank.html");// Add cookies into current browser contextdriver.manage().addCookie(newCookie("test1","cookie1"));driver.manage().addCookie(newCookie("test2","cookie2"));// Delete All cookiesdriver.manage().deleteAllCookies();}@TestpublicvoidsameSiteCookie(){driver.get("http://www.example.com");Cookiecookie=newCookie.Builder("key","value").sameSite("Strict").build();Cookiecookie1=newCookie.Builder("key","value").sameSite("Lax").build();driver.manage().addCookie(cookie);driver.manage().addCookie(cookie1);System.out.println(cookie.getSameSite());System.out.println(cookie1.getSameSite());}}
driver=webdriver.Chrome()driver.get("http://www.example.com")# Adds the cookie into current browser contextdriver.add_cookie({"name":"key","value":"value"})
fromseleniumimportwebdriverdeftest_add_cookie():driver=webdriver.Chrome()driver.get("http://www.example.com")# Adds the cookie into current browser contextdriver.add_cookie({"name":"key","value":"value"})deftest_get_named_cookie():driver=webdriver.Chrome()driver.get("http://www.example.com")# Adds the cookie into current browser contextdriver.add_cookie({"name":"foo","value":"bar"})# Get cookie details with named cookie 'foo'print(driver.get_cookie("foo"))deftest_get_all_cookies():driver=webdriver.Chrome()driver.get("http://www.example.com")driver.add_cookie({"name":"test1","value":"cookie1"})driver.add_cookie({"name":"test2","value":"cookie2"})# Get all available cookiesprint(driver.get_cookies())deftest_delete_cookie():driver=webdriver.Chrome()driver.get("http://www.example.com")driver.add_cookie({"name":"test1","value":"cookie1"})driver.add_cookie({"name":"test2","value":"cookie2"})# Delete cookie with name 'test1'driver.delete_cookie("test1")deftest_delete_all_cookies():driver=webdriver.Chrome()driver.get("http://www.example.com")driver.add_cookie({"name":"test1","value":"cookie1"})driver.add_cookie({"name":"test2","value":"cookie2"})# Delete all cookiesdriver.delete_all_cookies()deftest_same_side_cookie_attr():driver=webdriver.Chrome()driver.get("http://www.example.com")# Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'driver.add_cookie({"name":"foo","value":"value","sameSite":"Strict"})driver.add_cookie({"name":"foo1","value":"value","sameSite":"Lax"})cookie1=driver.get_cookie("foo")cookie2=driver.get_cookie("foo1")print(cookie1)print(cookie2)
driver.Url="https://www.selenium.dev/selenium/web/blank.html";// Add cookie into current browser contextdriver.Manage().Cookies.AddCookie(newCookie("key","value"));
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.usingSystem;usingMicrosoft.VisualStudio.TestTools.UnitTesting;usingOpenQA.Selenium;usingOpenQA.Selenium.Chrome;namespaceSeleniumDocs.Interactions{[TestClass]publicclassCookiesTest{WebDriverdriver=newChromeDriver(); [TestMethod]publicvoidaddCookie(){driver.Url="https://www.selenium.dev/selenium/web/blank.html";// Add cookie into current browser contextdriver.Manage().Cookies.AddCookie(newCookie("key","value"));driver.Quit();} [TestMethod]publicvoidgetNamedCookie(){driver.Url="https://www.selenium.dev/selenium/web/blank.html";// Add cookie into current browser contextdriver.Manage().Cookies.AddCookie(newCookie("foo","bar"));// Get cookie details with named cookie 'foo'Cookiecookie=driver.Manage().Cookies.GetCookieNamed("foo");Assert.AreEqual(cookie.Value,"bar");driver.Quit();} [TestMethod]publicvoidgetAllCookies(){driver.Url="https://www.selenium.dev/selenium/web/blank.html";// Add cookies into current browser contextdriver.Manage().Cookies.AddCookie(newCookie("test1","cookie1"));driver.Manage().Cookies.AddCookie(newCookie("test2","cookie2"));// Get cookiesvarcookies=driver.Manage().Cookies.AllCookies;foreach(varcookieincookies){if(cookie.Name.Equals("test1")){Assert.AreEqual("cookie1",cookie.Value);}if(cookie.Name.Equals("test2")){Assert.AreEqual("cookie2",cookie.Value);}}driver.Quit();} [TestMethod]publicvoiddeleteCookieNamed(){driver.Url="https://www.selenium.dev/selenium/web/blank.html";driver.Manage().Cookies.AddCookie(newCookie("test1","cookie1"));// delete cookie nameddriver.Manage().Cookies.DeleteCookieNamed("test1");driver.Quit();} [TestMethod]publicvoiddeleteCookieObject(){driver.Url="https://www.selenium.dev/selenium/web/blank.html";Cookiecookie=newCookie("test2","cookie2");driver.Manage().Cookies.AddCookie(cookie);/*
Selenium CSharp bindings also provides a way to delete
cookie by passing cookie object of current browsing context
*/driver.Manage().Cookies.DeleteCookie(cookie);driver.Quit();} [TestMethod]publicvoiddeleteAllCookies(){driver.Url="https://www.selenium.dev/selenium/web/blank.html";// Add cookies into current browser contextdriver.Manage().Cookies.AddCookie(newCookie("test1","cookie1"));driver.Manage().Cookies.AddCookie(newCookie("test2","cookie2"));// Delete All cookiesdriver.Manage().Cookies.DeleteAllCookies();driver.Quit();}}}
driver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'# Add cookie into current browser contextdriver.manage.add_cookie(name:'key',value:'value')
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Cookies'dolet(:driver){start_session}it'adds a cookie'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'# Add cookie into current browser contextdriver.manage.add_cookie(name:'key',value:'value')# Verify cookie was addedexpect(driver.manage.cookie_named('key')[:value]).toeq('value')endit'gets a named cookie'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'# Add cookie into current browser contextdriver.manage.add_cookie(name:'foo',value:'bar')# Get cookie details with named cookie 'foo'cookie=driver.manage.cookie_named('foo')expect(cookie[:value]).toeq('bar')endit'gets all cookies'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'# Add cookies into current browser contextdriver.manage.add_cookie(name:'test1',value:'cookie1')driver.manage.add_cookie(name:'test2',value:'cookie2')# Get cookiescookies=driver.manage.all_cookies# Verify both cookies exist with correct valuestest1_cookie=cookies.find{|c|c[:name]=='test1'}test2_cookie=cookies.find{|c|c[:name]=='test2'}expect(test1_cookie[:value]).toeq('cookie1')expect(test2_cookie[:value]).toeq('cookie2')endit'deletes a cookie by name'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'driver.manage.add_cookie(name:'test1',value:'cookie1')# Delete cookie nameddriver.manage.delete_cookie('test1')# Verify cookie is deletedexpect{driver.manage.cookie_named('test1')}.toraise_error(Selenium::WebDriver::Error::NoSuchCookieError)endit'deletes all cookies'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'# Add cookies into current browser contextdriver.manage.add_cookie(name:'test1',value:'cookie1')driver.manage.add_cookie(name:'test2',value:'cookie2')# Delete All cookiesdriver.manage.delete_all_cookies# Verify all cookies are deletedexpect(driver.manage.all_cookies.size).toeq(0)endend
awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// set a cookie on the current domain
awaitdriver.manage().addCookie({name:'key',value:'value'});
const{Browser,Builder}=require("selenium-webdriver");constassert=require('assert')describe('Cookies',function(){letdriver;before(asyncfunction(){driver=newBuilder().forBrowser(Browser.CHROME).build();});after(async()=>awaitdriver.quit());it('Create a cookie',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// set a cookie on the current domain
awaitdriver.manage().addCookie({name:'key',value:'value'});});it('Create cookies with sameSite',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
awaitdriver.manage().addCookie({name:'key',value:'value',sameSite:'Strict'});awaitdriver.manage().addCookie({name:'key',value:'value',sameSite:'Lax'});});it('Read cookie',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// set a cookie on the current domain
awaitdriver.manage().addCookie({name:'foo',value:'bar'});// Get cookie details with named cookie 'foo'
awaitdriver.manage().getCookie('foo').then(function(cookie){assert.equal(cookie.value,'bar');});});it('Read all cookies',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// Add few cookies
awaitdriver.manage().addCookie({name:'test1',value:'cookie1'});awaitdriver.manage().addCookie({name:'test2',value:'cookie2'});// Get all Available cookies
awaitdriver.manage().getCookies().then(function(cookies){assert.equal(cookies.filter(cookie=>cookie.name.startsWith('test')).length,2);});});it('Delete a cookie',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// Add few cookies
awaitdriver.manage().addCookie({name:'test1',value:'cookie1'});awaitdriver.manage().addCookie({name:'test2',value:'cookie2'});// Delete a cookie with name 'test1'
awaitdriver.manage().deleteCookie('test1');// Get all Available cookies
awaitdriver.manage().getCookies().then(function(cookies){assert.equal(cookies.filter(cookie=>cookie.name.startsWith('test')).length,1);});});it('Delete all cookies',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// Add few cookies
awaitdriver.manage().addCookie({name:'test1',value:'cookie1'});awaitdriver.manage().addCookie({name:'test2',value:'cookie2'});// Delete all cookies
awaitdriver.manage().deleteAllCookies();});});
Answer a basic authentication challenge with BiDi:
packagedev.selenium.bidirectional.webdriver_bidi;importdev.selenium.BaseTest;importjava.time.Duration;importjava.time.temporal.ChronoUnit;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Disabled;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.openqa.selenium.TimeoutException;importorg.openqa.selenium.UsernameAndPassword;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.bidi.module.Network;importorg.openqa.selenium.bidi.network.AddInterceptParameters;importorg.openqa.selenium.bidi.network.InterceptPhase;importorg.openqa.selenium.firefox.FirefoxDriver;importorg.openqa.selenium.firefox.FirefoxOptions;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;classNetworkCommandsTestextendsBaseTest{@BeforeEachpublicvoidsetup(){FirefoxOptionsoptions=newFirefoxOptions();options.setCapability("webSocketUrl",true);driver=newFirefoxDriver(options);wait=newWebDriverWait(driver,Duration.ofSeconds(10));}@TestvoidcanAddIntercept(){try(Networknetwork=newNetwork(driver)){Stringintercept=network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));Assertions.assertNotNull(intercept);}}@TestvoidcanRemoveIntercept(){try(Networknetwork=newNetwork(driver)){Stringintercept=network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));Assertions.assertNotNull(intercept);network.removeIntercept(intercept);}}@TestvoidcanContinueWithAuthCredentials(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->network.continueWithAuth(responseDetails.getRequest().getRequestId(),newUsernameAndPassword("admin","admin")));driver.get("https://the-internet.herokuapp.com/basic_auth");StringsuccessMessage="Congratulations! You must have the proper credentials.";WebElementelementMessage=driver.findElement(By.tagName("p"));Assertions.assertEquals(successMessage,elementMessage.getText());}}@TestvoidcanContinueWithoutAuthCredentials(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->// Does not handle the alertnetwork.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));driver.get("https://the-internet.herokuapp.com/basic_auth");Alertalert=wait.until(ExpectedConditions.alertIsPresent());alert.dismiss();Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));}}@TestvoidcanCancelAuth(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->// Does not handle the alertnetwork.cancelAuth(responseDetails.getRequest().getRequestId()));driver.get("https://the-internet.herokuapp.com/basic_auth");Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));}}@TestvoidcanFailRequest(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));network.onBeforeRequestSent(responseDetails->network.failRequest(responseDetails.getRequest().getRequestId()));driver.manage().timeouts().pageLoadTimeout(Duration.of(5,ChronoUnit.SECONDS));Assertions.assertThrows(TimeoutException.class,()->driver.get("https://the-internet.herokuapp.com/basic_auth"));}}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.importpytestfromselenium.common.exceptionsimportWebDriverException@pytest.mark.driver_type("bidi")deftest_add_intercept(driver):# _add_intercept is currently the available Python API for BiDi network intercepts.# This will be updated when a public API is stabilized.intercept=driver.network._add_intercept()assertinterceptisnotNonedriver.network._remove_intercept(intercept["intercept"])@pytest.mark.driver_type("bidi")deftest_remove_intercept(driver):# _add_intercept/_remove_intercept are currently the available Python APIs.# These will be updated when a public API is stabilized.intercept=driver.network._add_intercept()driver.network._remove_intercept(intercept["intercept"])assertdriver.network.intercepts==[]@pytest.mark.driver_type("bidi")deftest_fail_request(driver):fromselenium.webdriver.common.bidi.browsing_contextimportReadinessStatefromselenium.webdriver.common.bidi.networkimportRequestdefblock_request(request:Request):request.fail()driver.network.add_request_handler(["**/blank.html"],block_request)try:withpytest.raises(WebDriverException):driver.browsing_context.navigate(context=driver.current_window_handle,url="https://www.selenium.dev/selenium/web/blank.html",wait=ReadinessState.COMPLETE,)finally:driver.network.clear_request_handlers()@pytest.mark.driver_type("bidi")deftest_add_and_remove_request_handler(driver):fromselenium.webdriver.common.bidi.networkimportRequestrequests=[]defcallback(request:Request):requests.append(request)callback_id=driver.network.add_request_handler("before_request",callback)assertcallback_idisnotNonedriver.network.remove_request_handler("before_request",callback_id)driver.get("https://www.selenium.dev/selenium/web/blank.html")assertnotrequests
constassert=require("assert")constfirefox=require('selenium-webdriver/firefox')const{Network}=require('selenium-webdriver/bidi/network')const{until,By,Builder}=require('selenium-webdriver')const{AddInterceptParameters}=require("selenium-webdriver/bidi/addInterceptParameters");const{InterceptPhase}=require("selenium-webdriver/bidi/interceptPhase");describe('Network commands',function(){letdriverletnetworkbeforeEach(asyncfunction(){driver=newBuilder().forBrowser('firefox').setFirefoxOptions(newfirefox.Options().enableBidi()).build()network=awaitNetwork(driver)})afterEach(asyncfunction(){awaitnetwork.close()awaitdriver.quit()})it('can add intercept',asyncfunction(){constintercept=awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))assert.notEqual(intercept,null)})it('can remove intercept',asyncfunction(){constnetwork=awaitNetwork(driver)constintercept=awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))assert.notEqual(intercept,null)awaitnetwork.removeIntercept(intercept)})it('can continue with auth credentials ',asyncfunction(){awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED))awaitnetwork.authRequired(async(event)=>{awaitnetwork.continueWithAuth(event.request.request,'admin','admin')})awaitdriver.get('https://the-internet.herokuapp.com/basic_auth')constsuccessMessage='Congratulations! You must have the proper credentials.'letelementMessage=awaitdriver.findElement(By.tagName('p')).getText()assert.equal(elementMessage,successMessage)})it('can continue without auth credentials ',asyncfunction(){awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED))awaitnetwork.authRequired(async(event)=>{awaitnetwork.continueWithAuthNoCredentials(event.request.request)})awaitdriver.get('https://the-internet.herokuapp.com/basic_auth')constalert=awaitdriver.wait(until.alertIsPresent())awaitalert.dismiss()letsource=awaitdriver.getPageSource()assert.equal(source.includes('Not authorized'),true)})it('can cancel auth ',asyncfunction(){awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED))awaitnetwork.authRequired(async(event)=>{awaitnetwork.cancelAuth(event.request.request)})awaitdriver.get('https://the-internet.herokuapp.com/basic_auth')letsource=awaitdriver.getPageSource()assert.equal(source.includes('Not authorized'),true)})})
Common errors
InvalidCookieDomainException:
the browser is not on a page in the cookie’s domain. Navigate there first, then add the cookie.
UnableToSetCookieException:
the cookie attributes were rejected, for example a Secure cookie on an http:// page.
UnhandledAlertException:
a basic authentication dialog is open and blocking the session. Handle it with BiDi before navigating.
Uploading a file through a form without touching the operating system’s file dialog, and why downloading through the browser is not the right way to test a download.
Clicking a file input opens the operating system’s file chooser, which is outside the browser
and invisible to WebDriver. Clicking a download link starts a download the API cannot watch:
there is no event for “finished”, no progress, and no portable way to find the file afterwards.
Recommended approach
Uploads. Do not click the input. Send the absolute path of the file to the
<input type="file"> element with sendKeys, then submit the form as usual. The browser
attaches the file exactly as if it had been chosen through the dialog. The path must exist on
the machine where the browser is running; when the browser is remote, on a Grid, set a local
file detector so the client uploads the file to the node first.
Downloads. Testing a download through the browser is discouraged. The browser’s download
behaviour is configurable per browser and per platform, the file lands in a directory you then
have to poll, and none of this is what a user actually cares about. Instead, use Selenium to
get to the point where the download link exists, read its href (and any cookies the request
needs), and fetch it with an HTTP client in your test language. That gives you the bytes
directly, with a proper status code, and no polling.
If you are running on Selenium Grid and really need the browser to perform the download, Grid
can be configured to collect downloaded files from the node and the client can retrieve them;
see the remote WebDriver page below.
const{Browser,By,until,Builder}=require("selenium-webdriver");constpath=require("path");constassert=require('node:assert');describe('File Upload Test',function(){letdriver;before(asyncfunction(){driver=newBuilder().forBrowser(Browser.CHROME).build();});after(async()=>awaitdriver.quit());it('Should be able to upload a file successfully',asyncfunction(){constimage=path.resolve('./test/resources/selenium-snapshot.png')awaitdriver.manage().setTimeouts({implicit:5000});// Navigate to URL
awaitdriver.get('https://the-internet.herokuapp.com/upload');// Upload snapshot
awaitdriver.findElement(By.id("file-upload")).sendKeys(image);awaitdriver.findElement(By.id("file-submit")).submit();constrevealed=awaitdriver.findElement(By.id('uploaded-files'))awaitdriver.wait(until.elementIsVisible(revealed),2000);constdata=awaitdriver.findElement(By.css('h3'));assert.equal(awaitdata.getText(),`File Uploaded!`);});});
Common errors
InvalidArgumentException:
the path does not exist on the machine running the browser. Use an absolute path, and a file
detector when the browser is remote.
ElementNotInteractableException:
the file input is hidden behind a styled button. Sending keys to a hidden file input is
allowed in most browsers; if it is refused, check the strictFileInteractability capability.
Reading, accepting, dismissing and typing into JavaScript alerts, confirms and prompts, and deciding what should happen to a dialog your test did not expect.
A page calls alert(), confirm() or prompt(), the browser shows a native dialog, and
every subsequent WebDriver command fails until something closes it. If the dialog appears when
your test is not expecting it, the failure is an unexpected alert open error several lines
away from the cause.
Recommended approach
All three dialogs are handled through the same object: switch to the alert, then read its text,
accept it, dismiss it, or send keys to it. alert() can only be accepted; confirm() returns
true to the page when accepted and false when dismissed; prompt() additionally accepts typed
text before being accepted.
Treat the dialog like any other asynchronous event and wait for it. The bindings ship an
alertIsPresent expected condition that returns the alert as soon as it exists, which is both
safer and simpler than switching and catching the error.
For dialogs that may appear when no test code is ready to handle them, set the
unhandledPromptBehavior capability when starting the session. dismiss and accept close
the dialog silently; dismiss and notify (the default) and accept and notify close it and
raise an error so you find out; ignore leaves it open for you to handle. Recent drivers close
beforeunload prompts automatically.
With WebDriver BiDi enabled, the browsing context module also emits userPromptOpened and
userPromptClosed events, so a test can react to a dialog the moment it appears rather than
discovering it on the next command.
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.packagedev.selenium.interactions;importdev.selenium.BaseTest;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.openqa.selenium.JavascriptExecutor;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeDriver;importorg.openqa.selenium.chrome.ChromeOptions;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;importjava.time.Duration;import staticorg.junit.jupiter.api.Assertions.assertEquals;publicclassAlertsTestextendsBaseTest{@BeforeEachpublicvoidcreateSession(){driver=newChromeDriver();wait=newWebDriverWait(driver,Duration.ofSeconds(10));}@TestpublicvoidalertInformationTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("alert")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("cheese",alert.getText());alert.accept();}@TestpublicvoidalertEmptyInformationTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("empty-alert")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("",alert.getText());alert.accept();}@TestpublicvoidpromptDisplayAndInputTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("prompt")).click();//Wait for the alert to be displayed and store it in a variablewait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Enter something",alert.getText());alert.sendKeys("Selenium");alert.accept();}@TestpublicvoidpromptDefaultInputTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("prompt-with-default")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Enter something",alert.getText());alert.accept();}@TestpublicvoidmultiplePromptInputsTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("double-prompt")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert1=driver.switchTo().alert();Assertions.assertEquals("First",alert1.getText());alert1.sendKeys("first");alert1.accept();Alertalert2=driver.switchTo().alert();Assertions.assertEquals("Second",alert2.getText());alert2.sendKeys("second");alert2.accept();}@TestpublicvoidslowAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("slow-alert")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Slow",alert.getText());alert.accept();}@TestpublicvoidconfirmationAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("confirm")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Are you sure?",alert.getText());alert.accept();Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));}@TestpublicvoidiframeAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");WebElementiframe=driver.findElement(By.name("iframeWithAlert"));driver.switchTo().frame(iframe);driver.findElement(By.id("alertInFrame")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("framed cheese",alert.getText());alert.accept();}@TestpublicvoidnestedIframeAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");WebElementiframe1=driver.findElement(By.name("iframeWithIframe"));driver.switchTo().frame(iframe1);WebElementiframe2=driver.findElement(By.name("iframeWithAlert"));driver.switchTo().frame(iframe2);driver.findElement(By.id("alertInFrame")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("framed cheese",alert.getText());alert.accept();}@TestpublicvoidtestForAlerts(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.addArguments("disable-search-engine-choice-screen");WebDriverdriver=newChromeDriver(chromeOptions);driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");JavascriptExecutorjs=(JavascriptExecutor)driver;js.executeScript("alert('Sample Alert');");WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(30));wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();assertEquals("Sample Alert",alert.getText());alert.accept();js.executeScript("confirm('Are you sure?');");wait=newWebDriverWait(driver,Duration.ofSeconds(30));wait.until(ExpectedConditions.alertIsPresent());alert=driver.switchTo().alert();assertEquals("Are you sure?",alert.getText());alert.dismiss();js.executeScript("prompt('What is your name?');");wait=newWebDriverWait(driver,Duration.ofSeconds(30));wait.until(ExpectedConditions.alertIsPresent());alert=driver.switchTo().alert();assertEquals("What is your name?",alert.getText());alert.sendKeys("Selenium");alert.accept();driver.quit();}}
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitglobalurlurl="https://www.selenium.dev/documentation/webdriver/interactions/alerts/"deftest_alert_popup():driver=webdriver.Chrome()driver.get(url)element=driver.find_element(By.LINK_TEXT,"See an example alert")element.click()wait=WebDriverWait(driver,timeout=2)alert=wait.until(lambdad:d.switch_to.alert)text=alert.textalert.accept()asserttext=="Sample alert"driver.quit()deftest_confirm_popup():driver=webdriver.Chrome()driver.get(url)element=driver.find_element(By.LINK_TEXT,"See a sample confirm")driver.execute_script("arguments[0].click();",element)wait=WebDriverWait(driver,timeout=2)alert=wait.until(lambdad:d.switch_to.alert)text=alert.textalert.dismiss()asserttext=="Are you sure?"driver.quit()deftest_prompt_popup():driver=webdriver.Chrome()driver.get(url)element=driver.find_element(By.LINK_TEXT,"See a sample prompt")driver.execute_script("arguments[0].click();",element)wait=WebDriverWait(driver,timeout=2)alert=wait.until(lambdad:d.switch_to.alert)alert.send_keys("Selenium")text=alert.textalert.accept()asserttext=="What is your tool of choice?"driver.quit()
alert=driver.switch_to.alert# Get the text of the alertalert.text# Press on Cancel buttonalert.dismiss
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Alerts'dolet(:driver){start_session}beforedodriver.navigate.to'https://selenium.dev'endit'interacts with an alert'dodriver.execute_script'alert("Hello, World!")'# Store the alert reference in a variablealert=driver.switch_to.alert# Get the text of the alertalert.text# Press on Cancel buttonalert.dismissendit'interacts with a confirm'dodriver.execute_script'confirm("Are you sure?")'# Store the alert reference in a variablealert=driver.switch_to.alert# Get the text of the alertalert.text# Press on Cancel buttonalert.dismissendit'interacts with a prompt'dodriver.execute_script'prompt("What is your name?")'# Store the alert reference in a variablealert=driver.switch_to.alert# Type a messagealert.send_keys('selenium')# Press on Ok buttonalert.acceptendend
const{By,Builder,until}=require('selenium-webdriver');constassert=require("node:assert");describe('Interactions - Alerts',function(){letdriver;before(asyncfunction(){driver=awaitnewBuilder().forBrowser('chrome').build();});after(async()=>awaitdriver.quit());it('Should be able to getText from alert and accept',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');awaitdriver.findElement(By.id("alert")).click();awaitdriver.wait(until.alertIsPresent());letalert=awaitdriver.switchTo().alert();letalertText=awaitalert.getText();awaitalert.accept();// Verify
assert.equal(alertText,"cheese");});it('Should be able to getText from alert and dismiss',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');awaitdriver.findElement(By.id("confirm")).click();awaitdriver.wait(until.alertIsPresent());letalert=awaitdriver.switchTo().alert();letalertText=awaitalert.getText();awaitalert.dismiss();// Verify
assert.equal(alertText,"Are you sure?");});it('Should be able to enter text in alert prompt',asyncfunction(){lettext='Selenium';awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');awaitdriver.findElement(By.id("prompt")).click();awaitdriver.wait(until.alertIsPresent());letalert=awaitdriver.switchTo().alert();//Type your message
awaitalert.sendKeys(text);awaitalert.accept();letenteredText=awaitdriver.findElement(By.id('text'));assert.equal(awaitenteredText.getText(),text);});});
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.packagedev.selenium.interactions;importdev.selenium.BaseTest;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.openqa.selenium.JavascriptExecutor;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeDriver;importorg.openqa.selenium.chrome.ChromeOptions;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;importjava.time.Duration;import staticorg.junit.jupiter.api.Assertions.assertEquals;publicclassAlertsTestextendsBaseTest{@BeforeEachpublicvoidcreateSession(){driver=newChromeDriver();wait=newWebDriverWait(driver,Duration.ofSeconds(10));}@TestpublicvoidalertInformationTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("alert")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("cheese",alert.getText());alert.accept();}@TestpublicvoidalertEmptyInformationTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("empty-alert")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("",alert.getText());alert.accept();}@TestpublicvoidpromptDisplayAndInputTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("prompt")).click();//Wait for the alert to be displayed and store it in a variablewait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Enter something",alert.getText());alert.sendKeys("Selenium");alert.accept();}@TestpublicvoidpromptDefaultInputTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("prompt-with-default")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Enter something",alert.getText());alert.accept();}@TestpublicvoidmultiplePromptInputsTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("double-prompt")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert1=driver.switchTo().alert();Assertions.assertEquals("First",alert1.getText());alert1.sendKeys("first");alert1.accept();Alertalert2=driver.switchTo().alert();Assertions.assertEquals("Second",alert2.getText());alert2.sendKeys("second");alert2.accept();}@TestpublicvoidslowAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("slow-alert")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Slow",alert.getText());alert.accept();}@TestpublicvoidconfirmationAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");driver.findElement(By.id("confirm")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("Are you sure?",alert.getText());alert.accept();Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));}@TestpublicvoidiframeAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");WebElementiframe=driver.findElement(By.name("iframeWithAlert"));driver.switchTo().frame(iframe);driver.findElement(By.id("alertInFrame")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("framed cheese",alert.getText());alert.accept();}@TestpublicvoidnestedIframeAlertTest(){driver.get("https://www.selenium.dev/selenium/web/alerts.html#");WebElementiframe1=driver.findElement(By.name("iframeWithIframe"));driver.switchTo().frame(iframe1);WebElementiframe2=driver.findElement(By.name("iframeWithAlert"));driver.switchTo().frame(iframe2);driver.findElement(By.id("alertInFrame")).click();wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();Assertions.assertEquals("framed cheese",alert.getText());alert.accept();}@TestpublicvoidtestForAlerts(){ChromeOptionschromeOptions=getDefaultChromeOptions();chromeOptions.addArguments("disable-search-engine-choice-screen");WebDriverdriver=newChromeDriver(chromeOptions);driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");JavascriptExecutorjs=(JavascriptExecutor)driver;js.executeScript("alert('Sample Alert');");WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(30));wait.until(ExpectedConditions.alertIsPresent());Alertalert=driver.switchTo().alert();assertEquals("Sample Alert",alert.getText());alert.accept();js.executeScript("confirm('Are you sure?');");wait=newWebDriverWait(driver,Duration.ofSeconds(30));wait.until(ExpectedConditions.alertIsPresent());alert=driver.switchTo().alert();assertEquals("Are you sure?",alert.getText());alert.dismiss();js.executeScript("prompt('What is your name?');");wait=newWebDriverWait(driver,Duration.ofSeconds(30));wait.until(ExpectedConditions.alertIsPresent());alert=driver.switchTo().alert();assertEquals("What is your name?",alert.getText());alert.sendKeys("Selenium");alert.accept();driver.quit();}}
alert=wait.until(lambdad:d.switch_to.alert)alert.send_keys("Selenium")text=alert.textalert.accept()asserttext=="What is your tool of choice?"
fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitglobalurlurl="https://www.selenium.dev/documentation/webdriver/interactions/alerts/"deftest_alert_popup():driver=webdriver.Chrome()driver.get(url)element=driver.find_element(By.LINK_TEXT,"See an example alert")element.click()wait=WebDriverWait(driver,timeout=2)alert=wait.until(lambdad:d.switch_to.alert)text=alert.textalert.accept()asserttext=="Sample alert"driver.quit()deftest_confirm_popup():driver=webdriver.Chrome()driver.get(url)element=driver.find_element(By.LINK_TEXT,"See a sample confirm")driver.execute_script("arguments[0].click();",element)wait=WebDriverWait(driver,timeout=2)alert=wait.until(lambdad:d.switch_to.alert)text=alert.textalert.dismiss()asserttext=="Are you sure?"driver.quit()deftest_prompt_popup():driver=webdriver.Chrome()driver.get(url)element=driver.find_element(By.LINK_TEXT,"See a sample prompt")driver.execute_script("arguments[0].click();",element)wait=WebDriverWait(driver,timeout=2)alert=wait.until(lambdad:d.switch_to.alert)alert.send_keys("Selenium")text=alert.textalert.accept()asserttext=="What is your tool of choice?"driver.quit()
alert=driver.switch_to.alert# Type a messagealert.send_keys('selenium')# Press on Ok buttonalert.accept
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Alerts'dolet(:driver){start_session}beforedodriver.navigate.to'https://selenium.dev'endit'interacts with an alert'dodriver.execute_script'alert("Hello, World!")'# Store the alert reference in a variablealert=driver.switch_to.alert# Get the text of the alertalert.text# Press on Cancel buttonalert.dismissendit'interacts with a confirm'dodriver.execute_script'confirm("Are you sure?")'# Store the alert reference in a variablealert=driver.switch_to.alert# Get the text of the alertalert.text# Press on Cancel buttonalert.dismissendit'interacts with a prompt'dodriver.execute_script'prompt("What is your name?")'# Store the alert reference in a variablealert=driver.switch_to.alert# Type a messagealert.send_keys('selenium')# Press on Ok buttonalert.acceptendend
letalert=awaitdriver.switchTo().alert();//Type your message
awaitalert.sendKeys(text);awaitalert.accept();
const{By,Builder,until}=require('selenium-webdriver');constassert=require("node:assert");describe('Interactions - Alerts',function(){letdriver;before(asyncfunction(){driver=awaitnewBuilder().forBrowser('chrome').build();});after(async()=>awaitdriver.quit());it('Should be able to getText from alert and accept',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');awaitdriver.findElement(By.id("alert")).click();awaitdriver.wait(until.alertIsPresent());letalert=awaitdriver.switchTo().alert();letalertText=awaitalert.getText();awaitalert.accept();// Verify
assert.equal(alertText,"cheese");});it('Should be able to getText from alert and dismiss',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');awaitdriver.findElement(By.id("confirm")).click();awaitdriver.wait(until.alertIsPresent());letalert=awaitdriver.switchTo().alert();letalertText=awaitalert.getText();awaitalert.dismiss();// Verify
assert.equal(alertText,"Are you sure?");});it('Should be able to enter text in alert prompt',asyncfunction(){lettext='Selenium';awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');awaitdriver.findElement(By.id("prompt")).click();awaitdriver.wait(until.alertIsPresent());letalert=awaitdriver.switchTo().alert();//Type your message
awaitalert.sendKeys(text);awaitalert.accept();letenteredText=awaitdriver.findElement(By.id('text'));assert.equal(awaitenteredText.getText(),text);});});
Decide up front what happens to an unexpected dialog:
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.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.");}}
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
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Chrome'dodescribe'Driver Options'dolet(:chrome_location){driver_finder&&ENV.fetch('CHROME_BIN',nil)}let(:url){'https://www.selenium.dev/selenium/web/'}it'page load strategy normal'dooptions=Selenium::WebDriver::Options.chromeoptions.page_load_strategy=:normaldriver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'page load strategy eager'dooptions=Selenium::WebDriver::Options.chromeoptions.page_load_strategy=:eagerdriver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'page load strategy none'dooptions=Selenium::WebDriver::Options.chromeoptions.page_load_strategy=:nonedriver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets remote capabilities',skip:'this is example code that will not execute'dooptions=Selenium::WebDriver::Options.firefoxoptions.platform_name='Windows 10'options.browser_version='latest'cloud_options={}cloud_options[:build]=my_test_buildcloud_options[:name]=my_test_nameoptions.add_option('cloud:options',cloud_options)driver=Selenium::WebDriver.for:remote,capabilities:optionsdriver.get(url)driver.quitendit'accepts untrusted certificates'dooptions=Selenium::WebDriver::Options.chromeoptions.accept_insecure_certs=truedriver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets unhandled prompt behavior'dooptions=Selenium::WebDriver::Options.chromeoptions.unhandled_prompt_behavior=:acceptdriver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets window rect'dooptions=Selenium::WebDriver::Options.firefoxoptions.set_window_rect=truedriver=Selenium::WebDriver.for:firefox,options:optionsdriver.get(url)driver.quitendit'sets strict file interactability'dooptions=Selenium::WebDriver::Options.chromeoptions.strict_file_interactability=truedriver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets the proxy'dooptions=Selenium::WebDriver::Options.chromeoptions.proxy=Selenium::WebDriver::Proxy.new(http:'myproxy.com:8080')driver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets the implicit timeout'dooptions=Selenium::WebDriver::Options.chromeoptions.timeouts={implicit:1}driver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets the page load timeout'dooptions=Selenium::WebDriver::Options.chromeoptions.timeouts={page_load:400_000}driver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets the script timeout'dooptions=Selenium::WebDriver::Options.chromeoptions.timeouts={script:40_000}driver=Selenium::WebDriver.for:chrome,options:optionsdriver.get(url)driver.quitendit'sets capabilities in the pre-selenium 4 way',skip:'this is example code that will not execute'docaps=Selenium::WebDriver::Remote::Capabilities.firefoxcaps[:platform]='Windows 10'caps[:version]='92'caps[:build]=my_test_buildcaps[:name]=my_test_namedriver=Selenium::WebDriver.for:remote,url:cloud_url,desired_capabilities:capsdriver.get(url)driver.quitendendend
Common errors
NoAlertPresentException:
you switched to an alert before it appeared, or the session’s prompt handler already closed it.
Wait for it with alertIsPresent, and check unhandledPromptBehavior.
UnhandledAlertException:
a dialog opened that nothing handled, and the driver closed it before running your command.
Either handle the dialog in the test or change the prompt handler.
Reaching elements inside an iframe, following a link that opens a new tab or window, and getting back to where you started.
The element is plainly visible on the page, the locator is correct, and findElement still
reports that it does not exist. The element is inside an <iframe>, or on a tab the link just
opened, and WebDriver is still looking at the document it started in.
Recommended approach
WebDriver always has exactly one current browsing context: one window or tab, and within it
one frame. Commands only see that context. Switching is explicit, and you are responsible for
switching back.
Frames. Locate the <iframe> element like any other element and switch to it. You can also
switch by the frame’s name or id, or by index, but a located element is the least
ambiguous. When you are done, switch to the default content to return to the top-level
document. A frame reference goes stale when the page reloads, so switch again after navigation.
Windows and tabs. Each window or tab has a handle, an opaque string. Record the current
handle before clicking a link that opens a new one, wait until the number of handles grows,
switch to the handle you have not seen before, and switch back to the original handle when
you are finished. WebDriver makes no distinction between a tab and a window. If you just need
a clean tab, open one yourself with newWindow; it is created already switched to.
Closing the current window leaves the session pointing at nothing, so switch to another
handle immediately after close. Call quit, not close, at the end of the test; it closes
every window and ends the session.
Switch into a frame using a located element:
WebElementiframe=driver.findElement(By.id("iframe1"));//Switch to the framedriver.switchTo().frame(iframe);
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.packagedev.selenium.interactions;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.*;importorg.openqa.selenium.chrome.ChromeDriver;importjava.time.Duration;import staticorg.junit.jupiter.api.Assertions.assertEquals;publicclassFramesTest{@TestpublicvoidinformationWithElements(){WebDriverdriver=newChromeDriver();driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));// Navigate to Urldriver.get("https://www.selenium.dev/selenium/web/iframes.html");//switch To IFrame using Web ElementWebElementiframe=driver.findElement(By.id("iframe1"));//Switch to the framedriver.switchTo().frame(iframe);assertEquals(true,driver.getPageSource().contains("We Leave From Here"));//Now we can type text into email fieldWebElementemailE=driver.findElement(By.id("email"));emailE.sendKeys("admin@selenium.dev");emailE.clear();driver.switchTo().defaultContent();//switch To IFrame using name or idWebElementiframe1=driver.findElement(By.name("iframe1-name"));//Switch to the framedriver.switchTo().frame(iframe1);assertEquals(true,driver.getPageSource().contains("We Leave From Here"));WebElementemail=driver.findElement(By.id("email"));//Now we can type text into email fieldemail.sendKeys("admin@selenium.dev");email.clear();driver.switchTo().defaultContent();//switch To IFrame using indexdriver.switchTo().frame(0);assertEquals(true,driver.getPageSource().contains("We Leave From Here"));//leave framedriver.switchTo().defaultContent();assertEquals(true,driver.getPageSource().contains("This page has iframes"));//quit the browserdriver.quit();}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy#set chrome and launch web pagedriver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/iframes.html")# --- Switch to iframe using WebElement ---iframe=driver.find_element(By.ID,"iframe1")driver.switch_to.frame(iframe)assert"We Leave From Here"indriver.page_sourceemail_element=driver.find_element(By.ID,"email")email_element.send_keys("admin@selenium.dev")email_element.clear()driver.switch_to.default_content()# --- Switch to iframe using name or ID ---iframe1=driver.find_element(By.NAME,"iframe1-name")# (This line doesn't switch, just locates)driver.switch_to.frame(iframe1)assert"We Leave From Here"indriver.page_sourceemail=driver.find_element(By.ID,"email")email.send_keys("admin@selenium.dev")email.clear()driver.switch_to.default_content()# --- Switch to iframe using index ---driver.switch_to.frame(0)assert"We Leave From Here"indriver.page_source# --- Final page content check ---driver.switch_to.default_content()assert"This page has iframes"indriver.page_source#quit the driverdriver.quit()#demo code for conference
IWebElementiframe=driver.FindElement(By.Id("iframe1"));//Switch to the framedriver.SwitchTo().Frame(iframe);
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.usingSystem;usingMicrosoft.VisualStudio.TestTools.UnitTesting;usingOpenQA.Selenium;usingOpenQA.Selenium.Chrome;usingSystem.Collections.Generic;namespaceSeleniumDocs.Interactions{ [TestClass]publicclassFramesTest{ [TestMethod]publicvoidTestFrames(){WebDriverdriver=newChromeDriver();driver.Manage().Timeouts().ImplicitWait=TimeSpan.FromMilliseconds(500);// Navigate to Urldriver.Url="https://www.selenium.dev/selenium/web/iframes.html";//switch To IFrame using Web ElementIWebElementiframe=driver.FindElement(By.Id("iframe1"));//Switch to the framedriver.SwitchTo().Frame(iframe);Assert.AreEqual(true,driver.PageSource.Contains("We Leave From Here"));//Now we can type text into email fieldIWebElementemailE=driver.FindElement(By.Id("email"));emailE.SendKeys("admin@selenium.dev");emailE.Clear();driver.SwitchTo().DefaultContent();//switch To IFrame using name or idIWebElementiframe1=driver.FindElement(By.Name("iframe1-name"));//Switch to the framedriver.SwitchTo().Frame(iframe1);Assert.AreEqual(true,driver.PageSource.Contains("We Leave From Here"));IWebElementemail=driver.FindElement(By.Id("email"));//Now we can type text into email fieldemail.SendKeys("admin@selenium.dev");email.Clear();driver.SwitchTo().DefaultContent();//switch To IFrame using indexdriver.SwitchTo().Frame(0);Assert.AreEqual(true,driver.PageSource.Contains("We Leave From Here"));//leave framedriver.SwitchTo().DefaultContent();Assert.AreEqual(true,driver.PageSource.Contains("This page has iframes"));//quit the browserdriver.Quit();}}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Frames'dolet(:driver){start_session}it'performs iframe switching operations'dodriver.navigate.to'https://www.selenium.dev/selenium/web/iframes.html'# --- Switch to iframe using WebElement ---iframe=driver.find_element(:id,'iframe1')driver.switch_to.frame(iframe)expect(driver.page_source).toinclude('We Leave From Here')email_element=driver.find_element(:id,'email')email_element.send_keys('admin@selenium.dev')email_element.cleardriver.switch_to.default_content# --- Switch to iframe using name or ID ---iframe1=driver.find_element(:name,'iframe1-name')driver.switch_to.frame(iframe1)expect(driver.page_source).toinclude('We Leave From Here')email=driver.find_element(:id,'email')email.send_keys('admin@selenium.dev')email.cleardriver.switch_to.default_content# --- Switch to iframe using index ---driver.switch_to.frame(0)expect(driver.page_source).toinclude('We Leave From Here')# --- Final page content check ---driver.switch_to.default_contentexpect(driver.page_source).toinclude('This page has iframes')endend
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.packagedev.selenium.interactions;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.*;importorg.openqa.selenium.chrome.ChromeDriver;importjava.time.Duration;import staticorg.junit.jupiter.api.Assertions.assertEquals;publicclassFramesTest{@TestpublicvoidinformationWithElements(){WebDriverdriver=newChromeDriver();driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));// Navigate to Urldriver.get("https://www.selenium.dev/selenium/web/iframes.html");//switch To IFrame using Web ElementWebElementiframe=driver.findElement(By.id("iframe1"));//Switch to the framedriver.switchTo().frame(iframe);assertEquals(true,driver.getPageSource().contains("We Leave From Here"));//Now we can type text into email fieldWebElementemailE=driver.findElement(By.id("email"));emailE.sendKeys("admin@selenium.dev");emailE.clear();driver.switchTo().defaultContent();//switch To IFrame using name or idWebElementiframe1=driver.findElement(By.name("iframe1-name"));//Switch to the framedriver.switchTo().frame(iframe1);assertEquals(true,driver.getPageSource().contains("We Leave From Here"));WebElementemail=driver.findElement(By.id("email"));//Now we can type text into email fieldemail.sendKeys("admin@selenium.dev");email.clear();driver.switchTo().defaultContent();//switch To IFrame using indexdriver.switchTo().frame(0);assertEquals(true,driver.getPageSource().contains("We Leave From Here"));//leave framedriver.switchTo().defaultContent();assertEquals(true,driver.getPageSource().contains("This page has iframes"));//quit the browserdriver.quit();}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy#set chrome and launch web pagedriver=webdriver.Chrome()driver.get("https://www.selenium.dev/selenium/web/iframes.html")# --- Switch to iframe using WebElement ---iframe=driver.find_element(By.ID,"iframe1")driver.switch_to.frame(iframe)assert"We Leave From Here"indriver.page_sourceemail_element=driver.find_element(By.ID,"email")email_element.send_keys("admin@selenium.dev")email_element.clear()driver.switch_to.default_content()# --- Switch to iframe using name or ID ---iframe1=driver.find_element(By.NAME,"iframe1-name")# (This line doesn't switch, just locates)driver.switch_to.frame(iframe1)assert"We Leave From Here"indriver.page_sourceemail=driver.find_element(By.ID,"email")email.send_keys("admin@selenium.dev")email.clear()driver.switch_to.default_content()# --- Switch to iframe using index ---driver.switch_to.frame(0)assert"We Leave From Here"indriver.page_source# --- Final page content check ---driver.switch_to.default_content()assert"This page has iframes"indriver.page_source#quit the driverdriver.quit()#demo code for conference
// Licensed to the Software Freedom Conservancy (SFC) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The SFC licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing,// software distributed under the License is distributed on an// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY// KIND, either express or implied. See the License for the// specific language governing permissions and limitations// under the License.usingSystem;usingMicrosoft.VisualStudio.TestTools.UnitTesting;usingOpenQA.Selenium;usingOpenQA.Selenium.Chrome;usingSystem.Collections.Generic;namespaceSeleniumDocs.Interactions{ [TestClass]publicclassFramesTest{ [TestMethod]publicvoidTestFrames(){WebDriverdriver=newChromeDriver();driver.Manage().Timeouts().ImplicitWait=TimeSpan.FromMilliseconds(500);// Navigate to Urldriver.Url="https://www.selenium.dev/selenium/web/iframes.html";//switch To IFrame using Web ElementIWebElementiframe=driver.FindElement(By.Id("iframe1"));//Switch to the framedriver.SwitchTo().Frame(iframe);Assert.AreEqual(true,driver.PageSource.Contains("We Leave From Here"));//Now we can type text into email fieldIWebElementemailE=driver.FindElement(By.Id("email"));emailE.SendKeys("admin@selenium.dev");emailE.Clear();driver.SwitchTo().DefaultContent();//switch To IFrame using name or idIWebElementiframe1=driver.FindElement(By.Name("iframe1-name"));//Switch to the framedriver.SwitchTo().Frame(iframe1);Assert.AreEqual(true,driver.PageSource.Contains("We Leave From Here"));IWebElementemail=driver.FindElement(By.Id("email"));//Now we can type text into email fieldemail.SendKeys("admin@selenium.dev");email.Clear();driver.SwitchTo().DefaultContent();//switch To IFrame using indexdriver.SwitchTo().Frame(0);Assert.AreEqual(true,driver.PageSource.Contains("We Leave From Here"));//leave framedriver.SwitchTo().DefaultContent();Assert.AreEqual(true,driver.PageSource.Contains("This page has iframes"));//quit the browserdriver.Quit();}}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Frames'dolet(:driver){start_session}it'performs iframe switching operations'dodriver.navigate.to'https://www.selenium.dev/selenium/web/iframes.html'# --- Switch to iframe using WebElement ---iframe=driver.find_element(:id,'iframe1')driver.switch_to.frame(iframe)expect(driver.page_source).toinclude('We Leave From Here')email_element=driver.find_element(:id,'email')email_element.send_keys('admin@selenium.dev')email_element.cleardriver.switch_to.default_content# --- Switch to iframe using name or ID ---iframe1=driver.find_element(:name,'iframe1-name')driver.switch_to.frame(iframe1)expect(driver.page_source).toinclude('We Leave From Here')email=driver.find_element(:id,'email')email.send_keys('admin@selenium.dev')email.cleardriver.switch_to.default_content# --- Switch to iframe using index ---driver.switch_to.frame(0)expect(driver.page_source).toinclude('We Leave From Here')# --- Final page content check ---driver.switch_to.default_contentexpect(driver.page_source).toinclude('This page has iframes')endend
Follow a link into a new window and switch to it:
//click on link to open a new windowdriver.findElement(By.linkText("Open new window")).click();//fetch handles of all windows, there will be two, [0]- default, [1] - new windowObject[]windowHandles=driver.getWindowHandles().toArray();driver.switchTo().window((String)windowHandles[1]);//assert on title of new windowStringtitle=driver.getTitle();assertEquals("Simple Page",title);
packagedev.selenium.interactions;importorg.openqa.selenium.*;importorg.openqa.selenium.chrome.ChromeDriver;importjava.time.Duration;importorg.junit.jupiter.api.Test;import staticorg.junit.jupiter.api.Assertions.*;publicclassWindowsTest{@TestpublicvoidwindowsExampleCode(){WebDriverdriver=newChromeDriver();driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));// Navigate to Urldriver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");//fetch handle of thisStringcurrHandle=driver.getWindowHandle();assertNotNull(currHandle);//click on link to open a new windowdriver.findElement(By.linkText("Open new window")).click();//fetch handles of all windows, there will be two, [0]- default, [1] - new windowObject[]windowHandles=driver.getWindowHandles().toArray();driver.switchTo().window((String)windowHandles[1]);//assert on title of new windowStringtitle=driver.getTitle();assertEquals("Simple Page",title);//closing current windowdriver.close();//Switch back to the old tab or windowdriver.switchTo().window((String)windowHandles[0]);//Opens a new tab and switches to new tabdriver.switchTo().newWindow(WindowType.TAB);assertEquals("",driver.getTitle());//Opens a new window and switches to new windowdriver.switchTo().newWindow(WindowType.WINDOW);assertEquals("",driver.getTitle());//quitting driverdriver.quit();//close all windows}}
original_window_handle=driver.current_window_handledriver.find_element(By.LINK_TEXT,"Open new window").click()wait.until(EC.number_of_windows_to_be(2))new_window_handle=(set(driver.window_handles)-{original_window_handle}).pop()driver.switch_to.window(new_window_handle)
importpytestfromseleniumimportwebdriverfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.common.byimportByfromselenium.webdriver.supportimportexpected_conditionsasECurl="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"@pytest.fixture()defdriver():driver=webdriver.Chrome()yielddriverdriver.quit()deftest_current_window_handle(driver):driver.get(url)current_handle=driver.current_window_handleassertcurrent_handleisnotNonedeftest_switch_to_window(driver):driver.get(url)wait=WebDriverWait(driver,10)original_window_handle=driver.current_window_handledriver.find_element(By.LINK_TEXT,"Open new window").click()wait.until(EC.number_of_windows_to_be(2))new_window_handle=(set(driver.window_handles)-{original_window_handle}).pop()driver.switch_to.window(new_window_handle)assertdriver.current_window_handle==new_window_handledeftest_close_window(driver):driver.get(url)wait=WebDriverWait(driver,10)original_window_handle=driver.current_window_handledriver.find_element(By.LINK_TEXT,"Open new window").click()wait.until(EC.number_of_windows_to_be(2))new_window_handle=(set(driver.window_handles)-{original_window_handle}).pop()driver.switch_to.window(new_window_handle)driver.close()driver.switch_to.window(original_window_handle)assertdriver.current_window_handle==original_window_handleassertlen(driver.window_handles)==1deftest_create_new_window(driver):# Opens a new tab and switches to new tabdriver.switch_to.new_window('tab')assertdriver.title==""# Opens a new window and switches to new windowdriver.switch_to.new_window('window')assertdriver.title==""
//click on link to open a new windowdriver.FindElement(By.LinkText("Open new window")).Click();//fetch handles of all windows, there will be two, [0]- default, [1] - new windowIList<string>windowHandles=newList<string>(driver.WindowHandles);driver.SwitchTo().Window(windowHandles[1]);//assert on title of new windowStringtitle=driver.Title;Assert.AreEqual("Simple Page",title);
usingSystem;usingMicrosoft.VisualStudio.TestTools.UnitTesting;usingOpenQA.Selenium;usingOpenQA.Selenium.Chrome;usingSystem.Collections.Generic;namespaceSeleniumDocs.Interactions{ [TestClass]publicclassWindowsTest{ [TestMethod]publicvoidTestWindowCommands(){WebDriverdriver=newChromeDriver();driver.Manage().Timeouts().ImplicitWait=TimeSpan.FromMilliseconds(500);// Navigate to Urldriver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";//fetch handle of thisStringcurrHandle=driver.CurrentWindowHandle;Assert.IsNotNull(currHandle);//click on link to open a new windowdriver.FindElement(By.LinkText("Open new window")).Click();//fetch handles of all windows, there will be two, [0]- default, [1] - new windowIList<string>windowHandles=newList<string>(driver.WindowHandles);driver.SwitchTo().Window(windowHandles[1]);//assert on title of new windowStringtitle=driver.Title;Assert.AreEqual("Simple Page",title);//closing current windowdriver.Close();//Switch back to the old tab or windowdriver.SwitchTo().Window(windowHandles[0]);//Opens a new tab and switches to new tabdriver.SwitchTo().NewWindow(WindowType.Tab);Assert.AreEqual("",driver.Title);//Opens a new window and switches to new windowdriver.SwitchTo().NewWindow(WindowType.Window);Assert.AreEqual("",driver.Title);//quitting driverdriver.Quit();//close all windows}}}
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Windows'dolet(:driver){start_session}it'opens new tab'dodriver.switch_to.new_window(:tab)expect(driver.window_handles.size).toeq2endit'opens new window'dodriver.switch_to.new_window(:window)expect(driver.window_handles.size).toeq2endend
const{Builder,By}=require('selenium-webdriver');constchrome=require('selenium-webdriver/chrome');constassert=require("node:assert");letopts=newchrome.Options();opts.addArguments('--headless');letstartIndex=0letendIndex=5letpdfMagicNumber='JVBER'letimgMagicNumber='iVBOR'letbase64Codedescribe('Interactions - Windows',function(){letdriver;before(asyncfunction(){driver=awaitnewBuilder().forBrowser('chrome').setChromeOptions(opts).build();});after(async()=>awaitdriver.quit());it('Should be able to print page to pdf',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');letbase64=awaitdriver.printPage({pageRanges:["1-2"]});// page can be saved as a PDF as below
// await fs.writeFileSync('./test.pdf', base64, 'base64');
base64Code=base64.slice(startIndex,endIndex)assert.strictEqual(base64Code,pdfMagicNumber)});it('Should be able to get text using executeScript',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Stores the header element
letheader=awaitdriver.findElement(By.css('h1'));// Executing JavaScript to capture innerText of header element
lettext=awaitdriver.executeScript('return arguments[0].innerText',header);assert.strictEqual(text,`Type Stuff`)});it('Should be able to take Element Screenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');letheader=awaitdriver.findElement(By.css('h1'));// Captures the element screenshot
letencodedString=awaitheader.takeScreenshot(true);// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to takeScreenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Captures the screenshot
letencodedString=awaitdriver.takeScreenshot();// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to switch to newWindow and newTab and close',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');constinitialWindow=awaitdriver.getAllWindowHandles();assert.strictEqual(initialWindow.length,1)// Opens a new tab and switches to new tab
awaitdriver.switchTo().newWindow('tab');constbrowserTabs=awaitdriver.getAllWindowHandles();assert.strictEqual(browserTabs.length,2)// Opens a new window and switches to new window
awaitdriver.switchTo().newWindow('window');constwindows=awaitdriver.getAllWindowHandles();assert.strictEqual(windows.length,3)//Close the tab or window
awaitdriver.close();//Switch back to the old tab or window
awaitdriver.switchTo().window(windows[1]);constwindowsAfterClose=awaitdriver.getAllWindowHandles();assert.strictEqual(windowsAfterClose.length,2);});it('Should be able to getWindow Size',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{width,height}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constwindowWidth=rect.width;constwindowHeight=rect.height;assert.ok(windowWidth>0);assert.ok(windowHeight>0);});it('Should be able to getWindow position',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{x,y}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constx1=rect.x;consty1=rect.y;assert.ok(x1>=0);assert.ok(y1>=0);});});
Common errors
NoSuchElementException:
the element exists but in a different frame or window from the current one.
NoSuchFrameException:
the frame name, id or index did not match, or the frame was removed by a navigation.
NoSuchWindowException:
the window you were in was closed. Switch to a handle that still exists.
Capturing the viewport, a single element or the whole page as an image, and printing a page to PDF.
A test fails on the CI server and the stack trace says an element was not found. What was on
the screen at the time? Without a picture, the first debugging step is to re-run the test
locally and hope it fails the same way. A screenshot taken at the moment of failure turns
that guess into evidence, and the same API is the basis of visual comparison and archiving.
Recommended approach
WebDriver’s screenshot command returns the current viewport as a PNG, Base64-encoded. Every
binding wraps that so you can save it straight to a file. Calling the same command on an
element rather than the driver crops the image to that element’s bounding box, which is the
right choice when you want to compare a component rather than a whole page.
A viewport screenshot captures only what is visible without scrolling. Firefox supports a
full-page screenshot through its own driver API; with WebDriver BiDi enabled, the browsing
context module’s captureScreenshot command works across browsers and can also capture a box
or an element.
To produce a PDF rather than an image, use the print command. It takes a PrintOptions
object for orientation, page ranges, size, margins, scale and whether to print background
graphics, and returns the document Base64-encoded, ready to decode and write to a file.
Attach a screenshot to every failure in your test framework’s teardown hook: it is cheap,
and the one time you need it you will be glad it is there.
const{Builder,By}=require('selenium-webdriver');constchrome=require('selenium-webdriver/chrome');constassert=require("node:assert");letopts=newchrome.Options();opts.addArguments('--headless');letstartIndex=0letendIndex=5letpdfMagicNumber='JVBER'letimgMagicNumber='iVBOR'letbase64Codedescribe('Interactions - Windows',function(){letdriver;before(asyncfunction(){driver=awaitnewBuilder().forBrowser('chrome').setChromeOptions(opts).build();});after(async()=>awaitdriver.quit());it('Should be able to print page to pdf',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');letbase64=awaitdriver.printPage({pageRanges:["1-2"]});// page can be saved as a PDF as below
// await fs.writeFileSync('./test.pdf', base64, 'base64');
base64Code=base64.slice(startIndex,endIndex)assert.strictEqual(base64Code,pdfMagicNumber)});it('Should be able to get text using executeScript',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Stores the header element
letheader=awaitdriver.findElement(By.css('h1'));// Executing JavaScript to capture innerText of header element
lettext=awaitdriver.executeScript('return arguments[0].innerText',header);assert.strictEqual(text,`Type Stuff`)});it('Should be able to take Element Screenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');letheader=awaitdriver.findElement(By.css('h1'));// Captures the element screenshot
letencodedString=awaitheader.takeScreenshot(true);// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to takeScreenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Captures the screenshot
letencodedString=awaitdriver.takeScreenshot();// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to switch to newWindow and newTab and close',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');constinitialWindow=awaitdriver.getAllWindowHandles();assert.strictEqual(initialWindow.length,1)// Opens a new tab and switches to new tab
awaitdriver.switchTo().newWindow('tab');constbrowserTabs=awaitdriver.getAllWindowHandles();assert.strictEqual(browserTabs.length,2)// Opens a new window and switches to new window
awaitdriver.switchTo().newWindow('window');constwindows=awaitdriver.getAllWindowHandles();assert.strictEqual(windows.length,3)//Close the tab or window
awaitdriver.close();//Switch back to the old tab or window
awaitdriver.switchTo().window(windows[1]);constwindowsAfterClose=awaitdriver.getAllWindowHandles();assert.strictEqual(windowsAfterClose.length,2);});it('Should be able to getWindow Size',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{width,height}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constwindowWidth=rect.width;constwindowHeight=rect.height;assert.ok(windowWidth>0);assert.ok(windowHeight>0);});it('Should be able to getWindow position',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{x,y}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constx1=rect.x;consty1=rect.y;assert.ok(x1>=0);assert.ok(y1>=0);});});
Take a screenshot of one element:
letheader=awaitdriver.findElement(By.css('h1'));// Captures the element screenshot
letencodedString=awaitheader.takeScreenshot(true);
const{Builder,By}=require('selenium-webdriver');constchrome=require('selenium-webdriver/chrome');constassert=require("node:assert");letopts=newchrome.Options();opts.addArguments('--headless');letstartIndex=0letendIndex=5letpdfMagicNumber='JVBER'letimgMagicNumber='iVBOR'letbase64Codedescribe('Interactions - Windows',function(){letdriver;before(asyncfunction(){driver=awaitnewBuilder().forBrowser('chrome').setChromeOptions(opts).build();});after(async()=>awaitdriver.quit());it('Should be able to print page to pdf',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');letbase64=awaitdriver.printPage({pageRanges:["1-2"]});// page can be saved as a PDF as below
// await fs.writeFileSync('./test.pdf', base64, 'base64');
base64Code=base64.slice(startIndex,endIndex)assert.strictEqual(base64Code,pdfMagicNumber)});it('Should be able to get text using executeScript',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Stores the header element
letheader=awaitdriver.findElement(By.css('h1'));// Executing JavaScript to capture innerText of header element
lettext=awaitdriver.executeScript('return arguments[0].innerText',header);assert.strictEqual(text,`Type Stuff`)});it('Should be able to take Element Screenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');letheader=awaitdriver.findElement(By.css('h1'));// Captures the element screenshot
letencodedString=awaitheader.takeScreenshot(true);// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to takeScreenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Captures the screenshot
letencodedString=awaitdriver.takeScreenshot();// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to switch to newWindow and newTab and close',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');constinitialWindow=awaitdriver.getAllWindowHandles();assert.strictEqual(initialWindow.length,1)// Opens a new tab and switches to new tab
awaitdriver.switchTo().newWindow('tab');constbrowserTabs=awaitdriver.getAllWindowHandles();assert.strictEqual(browserTabs.length,2)// Opens a new window and switches to new window
awaitdriver.switchTo().newWindow('window');constwindows=awaitdriver.getAllWindowHandles();assert.strictEqual(windows.length,3)//Close the tab or window
awaitdriver.close();//Switch back to the old tab or window
awaitdriver.switchTo().window(windows[1]);constwindowsAfterClose=awaitdriver.getAllWindowHandles();assert.strictEqual(windowsAfterClose.length,2);});it('Should be able to getWindow Size',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{width,height}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constwindowWidth=rect.width;constwindowHeight=rect.height;assert.ok(windowWidth>0);assert.ok(windowHeight>0);});it('Should be able to getWindow position',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{x,y}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constx1=rect.x;consty1=rect.y;assert.ok(x1>=0);assert.ok(y1>=0);});});
packagedev.selenium.browsers;importdev.selenium.BaseTest;importjava.io.File;importjava.io.IOException;importjava.io.PrintStream;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.Test;importorg.junit.jupiter.api.condition.DisabledOnOs;importorg.junit.jupiter.api.condition.OS;importorg.openqa.selenium.By;importorg.openqa.selenium.OutputType;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.firefox.*;importorg.openqa.selenium.remote.service.DriverFinder;publicclassFirefoxTestextendsBaseTest{privateFirefoxDriverdriver;@AfterEachpublicvoidclearProperties(){System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);if(driver!=null){driver.quit();}}@TestpublicvoidbasicOptions(){FirefoxOptionsoptions=newFirefoxOptions();driver=newFirefoxDriver(options);}@Testpublicvoidarguments(){FirefoxOptionsoptions=newFirefoxOptions();options.addArguments("-headless");driver=newFirefoxDriver(options);}@Test@DisabledOnOs(OS.WINDOWS)publicvoidsetBrowserLocation(){FirefoxOptionsoptions=newFirefoxOptions();options.setBinary(getFirefoxLocation());driver=newFirefoxDriver(options);}@TestpublicvoidlogsToFile()throwsIOException{FilelogLocation=getTempFile("logsToFile",".log");FirefoxDriverServiceservice=newGeckoDriverService.Builder().withLogFile(logLocation).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertTrue(fileContent.contains("geckodriver INFO Listening on"));}@TestpublicvoidlogsToConsole()throwsIOException{FilelogLocation=getTempFile("logsToConsole",".log");System.setOut(newPrintStream(logLocation));FirefoxDriverServiceservice=newGeckoDriverService.Builder().withLogOutput(System.out).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertTrue(fileContent.contains("geckodriver INFO Listening on"));}@TestpublicvoidlogsWithLevel()throwsIOException{FilelogLocation=getTempFile("logsWithLevel",".log");System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY,logLocation.getAbsolutePath());FirefoxDriverServiceservice=newGeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));}@TestpublicvoidstopsTruncatingLogs()throwsIOException{FilelogLocation=getTempFile("geckodriver-","log");System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY,logLocation.getAbsolutePath());System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY,FirefoxDriverLogLevel.DEBUG.toString());FirefoxDriverServiceservice=newGeckoDriverService.Builder().withTruncatedLogs(false).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertFalse(fileContent.contains(" ... "));}@TestpublicvoidsetProfileLocation(){FileprofileDirectory=getTempDirectory("profile-");FirefoxDriverServiceservice=newGeckoDriverService.Builder().withProfileRoot(profileDirectory).build();driver=newFirefoxDriver(service);Stringlocation=(String)driver.getCapabilities().getCapability("moz:profile");Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));}@TestpublicvoidinstallAddon(){driver=startFirefoxDriver();PathxpiPath=Paths.get("src/test/resources/extensions/selenium-example.xpi");driver.installExtension(xpiPath);driver.get("https://www.selenium.dev/selenium/web/blank.html");WebElementinjected=driver.findElement(By.id("webextensions-selenium-example"));Assertions.assertEquals("Content injected by webextensions-selenium-example",injected.getText());}@TestpublicvoiduninstallAddon(){driver=startFirefoxDriver();PathxpiPath=Paths.get("src/test/resources/extensions/selenium-example.xpi");Stringid=driver.installExtension(xpiPath);driver.uninstallExtension(id);driver.get("https://www.selenium.dev/selenium/web/blank.html");Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(),0);}@TestpublicvoidinstallUnsignedAddonPath(){driver=startFirefoxDriver();Pathpath=Paths.get("src/test/resources/extensions/selenium-example");driver.installExtension(path,true);driver.get("https://www.selenium.dev/selenium/web/blank.html");WebElementinjected=getLocatedElement(driver,By.id("webextensions-selenium-example"));Assertions.assertEquals("Content injected by webextensions-selenium-example",injected.getText());}privatePathgetFirefoxLocation(){FirefoxOptionsoptions=newFirefoxOptions();options.setBrowserVersion("stable");DriverFinderfinder=newDriverFinder(GeckoDriverService.createDefaultService(),options);returnPath.of(finder.getBrowserPath());}@TestpublicvoidfullPageScreenshot()throwsException{driver=startFirefoxDriver();driver.get("https://www.selenium.dev");Filescreenshot=driver.getFullPageScreenshotAs(OutputType.FILE);FiletargetFile=newFile("full_page_screenshot.png");Files.move(screenshot.toPath(),targetFile.toPath());// Verify the screenshot file existsAssertions.assertTrue(targetFile.exists(),"The full page screenshot file should exist");Files.deleteIfExists(targetFile.toPath());}@TestpublicvoidsetContext(){driver=startFirefoxDriver(newFirefoxOptions().addArguments("-remote-allow-system-access"));driver.setContext(FirefoxCommandContext.CHROME);driver.executeScript("console.log('Inside Chrome context');");// Verify the context is back to "content"Assertions.assertEquals(FirefoxCommandContext.CHROME,driver.getContext(),"The context should be 'chrome'");}@TestpublicvoidfirefoxProfile(){FirefoxProfileprofile=newFirefoxProfile();FirefoxOptionsoptions=newFirefoxOptions();profile.setPreference("javascript.enabled","False");options.setProfile(profile);driver=newFirefoxDriver(options);}}
importosimportsubprocessimportsysimportpytestfromseleniumimportwebdriverdeftest_basic_options():options=webdriver.FirefoxOptions()driver=webdriver.Firefox(options=options)driver.quit()deftest_arguments():options=webdriver.FirefoxOptions()options.add_argument("-headless")driver=webdriver.Firefox(options=options)driver.quit()deftest_set_browser_location(firefox_bin):options=webdriver.FirefoxOptions()options.binary_location=firefox_bindriver=webdriver.Firefox(options=options)driver.quit()deftest_log_to_file(log_path):service=webdriver.FirefoxService(log_output=log_path,service_args=['--log','debug'])driver=webdriver.Firefox(service=service)driver.get("https://www.selenium.dev")withopen(log_path,'r')asfp:assert"geckodriver INFO Listening on"infp.readline()driver.quit()deftest_log_to_stdout(capfd):service=webdriver.FirefoxService(log_output=subprocess.STDOUT)driver=webdriver.Firefox(service=service)out,err=capfd.readouterr()assert"geckodriver INFO Listening on"inoutdriver.quit()deftest_log_level(log_path):service=webdriver.FirefoxService(log_output=log_path,service_args=['--log','debug'])driver=webdriver.Firefox(service=service)withopen(log_path,'r')asf:assert'\tDEBUG'inf.read()driver.quit()deftest_log_truncation(log_path):service=webdriver.FirefoxService(service_args=['--log-no-truncate','--log','debug'],log_output=log_path)driver=webdriver.Firefox(service=service)withopen(log_path,'r')asf:assert' ... 'notinf.read()driver.quit()deftest_profile_location(temp_dir):service=webdriver.FirefoxService(service_args=['--profile-root',temp_dir])driver=webdriver.Firefox(service=service)profile_name=driver.capabilities.get('moz:profile').replace('\\','/').split('/')[-1]assertprofile_nameinos.listdir(temp_dir)driver.quit()deftest_install_addon(firefox_driver,addon_path_xpi):driver=firefox_driverdriver.install_addon(addon_path_xpi)driver.get("https://www.selenium.dev/selenium/web/blank.html")injected=driver.find_element(webdriver.common.by.By.ID,"webextensions-selenium-example")assertinjected.text=="Content injected by webextensions-selenium-example"deftest_uninstall_addon(firefox_driver,addon_path_xpi):driver=firefox_driverid=driver.install_addon(addon_path_xpi)driver.uninstall_addon(id)driver.get("https://www.selenium.dev/selenium/web/blank.html")assertlen(driver.find_elements(webdriver.common.by.By.ID,"webextensions-selenium-example"))==0deftest_install_unsigned_addon_directory(firefox_driver,addon_path_dir):driver=firefox_driverdriver.install_addon(addon_path_dir,temporary=True)driver.get("https://www.selenium.dev/selenium/web/blank.html")injected=driver.find_element(webdriver.common.by.By.ID,"webextensions-selenium-example")assertinjected.text=="Content injected by webextensions-selenium-example"deftest_install_unsigned_addon_directory_slash(firefox_driver,addon_path_dir_slash):driver=firefox_driverdriver.install_addon(addon_path_dir_slash,temporary=True)driver.get("https://www.selenium.dev/selenium/web/blank.html")injected=driver.find_element(webdriver.common.by.By.ID,"webextensions-selenium-example")assertinjected.text=="Content injected by webextensions-selenium-example"deftest_full_page_screenshot(firefox_driver):driver=firefox_driverdriver.get("https://www.selenium.dev")driver.save_full_page_screenshot("full_page_screenshot.png")assertos.path.exists("full_page_screenshot.png")driver.quit()deftest_set_context():options=webdriver.FirefoxOptions()options.add_argument("-remote-allow-system-access")driver=webdriver.Firefox(options=options)withdriver.context(driver.CONTEXT_CHROME):driver.execute_script("console.log('Inside Chrome context');")# Check if the context is back to contentassertdriver.execute("GET_CONTEXT")["value"]=="content"driver.quit()deftest_firefox_profile():fromselenium.webdriver.firefox.optionsimportOptionsfromselenium.webdriver.firefox.firefox_profileimportFirefoxProfileoptions=Options()firefox_profile=FirefoxProfile()firefox_profile.set_preference("javascript.enabled",False)options.profile=firefox_profiledriver=webdriver.Firefox(options=options)driver.quit()
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Firefox'dodescribe'Options'dolet(:firefox_location){driver_finder&&ENV.fetch('FIREFOX_BIN',nil)}it'basic options'dooptions=Selenium::WebDriver::Options.firefox@driver=Selenium::WebDriver.for:firefox,options:optionsendit'add arguments'dooptions=Selenium::WebDriver::Options.firefoxoptions.args<<'-headless'@driver=Selenium::WebDriver.for:firefox,options:optionsendit'sets location of binary'dooptions=Selenium::WebDriver::Options.firefoxoptions.binary=firefox_location@driver=Selenium::WebDriver.for:firefox,options:optionsendenddescribe'Service'dolet(:file_name){Tempfile.new('geckodriver').path}let(:root_directory){Dir.mktmpdir}afterdoFileUtils.rm_f(file_name)FileUtils.rm_rf(root_directory)endit'logs to file'doservice=Selenium::WebDriver::Service.firefoxservice.log=file_name@driver=Selenium::WebDriver.for:firefox,service:serviceexpect(File.readlines(file_name).first).toinclude("geckodriver\tINFO\tListening on")endit'logs to console'doservice=Selenium::WebDriver::Service.firefoxservice.log=$stdoutexpect{@driver=Selenium::WebDriver.for:firefox,service:service}.tooutput(/geckodriver INFO Listening on/).to_stdout_from_any_processendit'sets log level'doservice=Selenium::WebDriver::Service.firefoxservice.log=file_nameservice.args+=%w[--log debug]@driver=Selenium::WebDriver.for:firefox,service:serviceexpect(File.readlines(file_name).grep(/Marionette DEBUG/).any?).toeqtrueendit'stops truncating log lines'doservice=Selenium::WebDriver::Service.firefox(log:file_name,args:%w[--log debug])service.args<<'--log-no-truncate'@driver=Selenium::WebDriver.for:firefox,service:serviceexpect(File.readlines(file_name).grep(/ \.\.\. /).any?).toeqfalseendit'sets default profile location'doservice=Selenium::WebDriver::Service.firefoxservice.args+=['--profile-root',root_directory]@driver=Selenium::WebDriver.for:firefox,service:serviceprofile_location=Dir.new(@driver.capabilities['moz:profile'])expect(profile_location.path.gsub('\\','/')).toinclude(root_directory)endenddescribe'Features'dolet(:driver){start_firefox}it'installs addon'doextension_file_path=File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi',__dir__)driver.install_addon(extension_file_path)driver.get'https://www.selenium.dev/selenium/web/blank.html'injected=driver.find_element(id:'webextensions-selenium-example')expect(injected.text).toeq'Content injected by webextensions-selenium-example'endit'uninstalls addon'doextension_file_path=File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi',__dir__)extension_id=driver.install_addon(extension_file_path)driver.uninstall_addon(extension_id)driver.get'https://www.selenium.dev/selenium/web/blank.html'expect(driver.find_elements(id:'webextensions-selenium-example')).tobe_emptyendit'installs unsigned addon'doextension_dir_path=File.expand_path('../spec_support/extensions/webextensions-selenium-example/',__dir__)driver.install_addon(extension_dir_path,true)driver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'injected=driver.find_element(id:'webextensions-selenium-example')expect(injected.text).toeq'Content injected by webextensions-selenium-example'endit'takes full page screenshot'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'Dir.mktmpdir('screenshot_test')do|dir|screenshot=driver.save_full_page_screenshot(File.join(dir,'screenshot.png'))expect(screenshot).tobe_aFileendendit'sets the context'dodriver.context='content'expect(driver.context).toeq'content'endenddescribe'Profile'doit'creates a new profile'doprofile=Selenium::WebDriver::Firefox::Profile.newprofile['browser.download.dir']='/tmp/webdriver-downloads'options=Selenium::WebDriver::Firefox::Options.new(profile:profile)expect(options.profile).toeq(profile)endenddefdriver_finderoptions=Selenium::WebDriver::Options.firefox(browser_version:'stable')service=Selenium::WebDriver::Service.firefoxfinder=Selenium::WebDriver::DriverFinder.new(options,service)ENV['GECKODRIVER_BIN']=finder.driver_pathENV['FIREFOX_BIN']=finder.browser_pathendend
const{By,until,Builder}=require("selenium-webdriver");constfirefox=require('selenium-webdriver/firefox');constBrowsingContext=require('selenium-webdriver/bidi/browsingContext');constassert=require("assert");describe('Browsing Context',function(){letdriverletstartIndex=0letendIndex=5letpdfMagicNumber='JVBER'letpngMagicNumber='iVBOR'beforeEach(asyncfunction(){driver=newBuilder().forBrowser('firefox').setFirefoxOptions(newfirefox.Options().enableBidi()).build()})afterEach(asyncfunction(){awaitdriver.quit()})it('test create a browsing context for given id',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})assert.equal(browsingContext.id,id)})it('test create a window',asyncfunction(){constbrowsingContext=awaitBrowsingContext(driver,{type:'window',})assert.notEqual(browsingContext.id,null)})it('test create a window with a reference context',asyncfunction(){constbrowsingContext=awaitBrowsingContext(driver,{type:'window',referenceContext:awaitdriver.getWindowHandle(),})assert.notEqual(browsingContext.id,null)})it('test create a tab',asyncfunction(){constbrowsingContext=awaitBrowsingContext(driver,{type:'tab',})assert.notEqual(browsingContext.id,null)})it('test create a tab with a reference context',asyncfunction(){constbrowsingContext=awaitBrowsingContext(driver,{type:'tab',referenceContext:awaitdriver.getWindowHandle(),})assert.notEqual(browsingContext.id,null)})it('test navigate to a url',asyncfunction(){constbrowsingContext=awaitBrowsingContext(driver,{type:'tab',})letinfo=awaitbrowsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')assert.notEqual(browsingContext.id,null)assert.notEqual(info.navigationId,null)assert(info.url.includes('/bidi/logEntryAdded.html'))})it('test navigate to a url with readiness state',asyncfunction(){constbrowsingContext=awaitBrowsingContext(driver,{type:'tab',})constinfo=awaitbrowsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html','complete')assert.notEqual(browsingContext.id,null)assert.notEqual(info.navigationId,null)assert(info.url.includes('/bidi/logEntryAdded.html'))})it('test get tree with a child',asyncfunction(){constbrowsingContextId=awaitdriver.getWindowHandle()constparentWindow=awaitBrowsingContext(driver,{browsingContextId:browsingContextId,})awaitparentWindow.navigate('https://www.selenium.dev/selenium/web/iframes.html','complete')constcontextInfo=awaitparentWindow.getTree()assert.equal(contextInfo.children.length,1)assert.equal(contextInfo.id,browsingContextId)assert(contextInfo.children[0]['url'].includes('formPage.html'))})it('test get tree with depth',asyncfunction(){constbrowsingContextId=awaitdriver.getWindowHandle()constparentWindow=awaitBrowsingContext(driver,{browsingContextId:browsingContextId,})awaitparentWindow.navigate('https://www.selenium.dev/selenium/web/iframes.html','complete')constcontextInfo=awaitparentWindow.getTree(0)assert.equal(contextInfo.children,null)assert.equal(contextInfo.id,browsingContextId)})it('test close a window',asyncfunction(){constwindow1=awaitBrowsingContext(driver,{type:'window'})constwindow2=awaitBrowsingContext(driver,{type:'window'})awaitwindow2.close()assert.doesNotThrow(asyncfunction(){awaitwindow1.getTree()})awaitassert.rejects(window2.getTree(),{message:'no such frame'})})it('test close a tab',asyncfunction(){consttab1=awaitBrowsingContext(driver,{type:'tab'})consttab2=awaitBrowsingContext(driver,{type:'tab'})awaittab2.close()assert.doesNotThrow(asyncfunction(){awaittab1.getTree()})awaitassert.rejects(tab2.getTree(),{message:'no such frame'})})it('can print PDF with all valid parameters',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/printPage.html")constresult=awaitbrowsingContext.printPage({orientation:'landscape',scale:1,background:true,width:30,height:30,top:1,bottom:1,left:1,right:1,shrinkToFit:true,pageRanges:['1-2'],})letbase64Code=result.data.slice(0,5)assert.strictEqual(base64Code,'JVBER')})it('can take box screenshot',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})constresponse=awaitbrowsingContext.captureBoxScreenshot(5,5,10,10)constbase64code=response.slice(0,5)assert.equal(base64code,'iVBOR')})it('can take element screenshot',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/formPage.html")constelement=awaitdriver.findElement(By.id('checky'))constelementId=awaitelement.getId()constresponse=awaitbrowsingContext.captureElementScreenshot(elementId)constbase64code=response.slice(0,5)assert.equal(base64code,'iVBOR')})it('can activate a browsing context',asyncfunction(){constid=awaitdriver.getWindowHandle()constwindow1=awaitBrowsingContext(driver,{browsingContextId:id,})awaitBrowsingContext(driver,{type:'window',})constresult=awaitdriver.executeScript('return document.hasFocus();')assert.equal(result,false)awaitwindow1.activate()constresult2=awaitdriver.executeScript('return document.hasFocus();')assert.equal(result2,true)})it('can handle user prompt',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/alerts.html")awaitdriver.findElement(By.id('alert')).click()awaitdriver.wait(until.alertIsPresent())awaitbrowsingContext.handleUserPrompt()constresult=awaitdriver.getTitle()assert.equal(result,'Testing Alerts')})it('can accept user prompt',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/alerts.html")awaitdriver.findElement(By.id('alert')).click()awaitdriver.wait(until.alertIsPresent())awaitbrowsingContext.handleUserPrompt(true)constresult=awaitdriver.getTitle()assert.equal(result,'Testing Alerts')})it('can dismiss user prompt',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/alerts.html")awaitdriver.findElement(By.id('alert')).click()awaitdriver.wait(until.alertIsPresent())awaitbrowsingContext.handleUserPrompt(false)constresult=awaitdriver.getTitle()assert.equal(result,'Testing Alerts')})it('can pass user text to user prompt',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/alerts.html")awaitdriver.findElement(By.id('prompt')).click()awaitdriver.wait(until.alertIsPresent())constuserText='Selenium automates browsers'awaitbrowsingContext.handleUserPrompt(undefined,userText)constresult=awaitdriver.getPageSource()assert.equal(result.includes(userText),true)})it('can accept user prompt with user text',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/alerts.html")awaitdriver.findElement(By.id('prompt')).click()awaitdriver.wait(until.alertIsPresent())constuserText='Selenium automates browsers'awaitbrowsingContext.handleUserPrompt(true,userText)constresult=awaitdriver.getPageSource()assert.equal(result.includes(userText),true)})it('can dismiss user prompt with user text',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/alerts.html")awaitdriver.findElement(By.id('alert')).click()awaitdriver.wait(until.alertIsPresent())constuserText='Selenium automates browsers'awaitbrowsingContext.handleUserPrompt(false,userText)constresult=awaitdriver.getPageSource()assert.equal(result.includes(userText),false)})it('can set viewport',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitdriver.get("https://www.selenium.dev/selenium/web/blank.html")awaitbrowsingContext.setViewport(250,300)constresult=awaitdriver.executeScript('return [window.innerWidth, window.innerHeight];')assert.equal(result[0],250)assert.equal(result[1],300)})it('can reload a browsing context',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})constresult=awaitbrowsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html','complete')awaitbrowsingContext.reload(undefined,'complete')assert.notEqual(result.navigationId,null)assert(result.url.includes('/bidi/logEntryAdded.html'))})it('can take screenshot',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})constresponse=awaitbrowsingContext.captureScreenshot()constbase64code=response.slice(startIndex,endIndex)assert.equal(base64code,pngMagicNumber)})it('can traverse browser history',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitbrowsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html','complete')awaitdriver.wait(until.elementLocated(By.id('imageButton'))).submit()awaitdriver.wait(until.titleIs('We Arrive Here'),2500)awaitbrowsingContext.traverseHistory(-1)constsource=awaitdriver.getPageSource()assert.equal(source.includes('We Leave From Here'),true)})it('can navigate back in browser history',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitbrowsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html','complete')awaitdriver.wait(until.elementLocated(By.id('imageButton'))).submit()awaitdriver.wait(until.titleIs('We Arrive Here'),2500)awaitbrowsingContext.back()constsource=awaitdriver.getPageSource()assert.equal(source.includes('We Leave From Here'),true)})it('can navigate forward in browser history',asyncfunction(){constid=awaitdriver.getWindowHandle()constbrowsingContext=awaitBrowsingContext(driver,{browsingContextId:id,})awaitbrowsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html','complete')awaitdriver.wait(until.elementLocated(By.id('imageButton'))).submit()awaitdriver.wait(until.titleIs('We Arrive Here'),2500)awaitbrowsingContext.back()constsource=awaitdriver.getPageSource()assert.equal(source.includes('We Leave From Here'),true)awaitbrowsingContext.forward()awaitdriver.wait(until.titleIs('We Arrive Here'),2500)});it('Get All Top level browsing contexts',async()=>{constid=awaitdriver.getWindowHandle()constwindow1=awaitBrowsingContext(driver,{browsingContextId:id,})awaitBrowsingContext(driver,{type:'window'})constres=awaitwindow1.getTopLevelContexts()assert.equal(res.length,2)})})
const{Builder,By}=require('selenium-webdriver');constchrome=require('selenium-webdriver/chrome');constassert=require("node:assert");letopts=newchrome.Options();opts.addArguments('--headless');letstartIndex=0letendIndex=5letpdfMagicNumber='JVBER'letimgMagicNumber='iVBOR'letbase64Codedescribe('Interactions - Windows',function(){letdriver;before(asyncfunction(){driver=awaitnewBuilder().forBrowser('chrome').setChromeOptions(opts).build();});after(async()=>awaitdriver.quit());it('Should be able to print page to pdf',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/alerts.html');letbase64=awaitdriver.printPage({pageRanges:["1-2"]});// page can be saved as a PDF as below
// await fs.writeFileSync('./test.pdf', base64, 'base64');
base64Code=base64.slice(startIndex,endIndex)assert.strictEqual(base64Code,pdfMagicNumber)});it('Should be able to get text using executeScript',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Stores the header element
letheader=awaitdriver.findElement(By.css('h1'));// Executing JavaScript to capture innerText of header element
lettext=awaitdriver.executeScript('return arguments[0].innerText',header);assert.strictEqual(text,`Type Stuff`)});it('Should be able to take Element Screenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');letheader=awaitdriver.findElement(By.css('h1'));// Captures the element screenshot
letencodedString=awaitheader.takeScreenshot(true);// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to takeScreenshot',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');// Captures the screenshot
letencodedString=awaitdriver.takeScreenshot();// save screenshot as below
// await fs.writeFileSync('./image.png', encodedString, 'base64');
base64Code=encodedString.slice(startIndex,endIndex)assert.strictEqual(base64Code,imgMagicNumber)});it('Should be able to switch to newWindow and newTab and close',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');constinitialWindow=awaitdriver.getAllWindowHandles();assert.strictEqual(initialWindow.length,1)// Opens a new tab and switches to new tab
awaitdriver.switchTo().newWindow('tab');constbrowserTabs=awaitdriver.getAllWindowHandles();assert.strictEqual(browserTabs.length,2)// Opens a new window and switches to new window
awaitdriver.switchTo().newWindow('window');constwindows=awaitdriver.getAllWindowHandles();assert.strictEqual(windows.length,3)//Close the tab or window
awaitdriver.close();//Switch back to the old tab or window
awaitdriver.switchTo().window(windows[1]);constwindowsAfterClose=awaitdriver.getAllWindowHandles();assert.strictEqual(windowsAfterClose.length,2);});it('Should be able to getWindow Size',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{width,height}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constwindowWidth=rect.width;constwindowHeight=rect.height;assert.ok(windowWidth>0);assert.ok(windowHeight>0);});it('Should be able to getWindow position',asyncfunction(){awaitdriver.get('https://www.selenium.dev/selenium/web/');// Access each dimension individually
const{x,y}=awaitdriver.manage().window().getRect();// Or store the dimensions and query them later
constrect=awaitdriver.manage().window().getRect();constx1=rect.x;consty1=rect.y;assert.ok(x1>=0);assert.ok(y1>=0);});});
Common errors
ScreenshotException:
the browser could not capture the screen, usually because the window is minimised or the
element is not rendered. Maximise the window or scroll the element into view.
StaleElementReferenceException:
the element being captured was re-rendered between locating it and taking the screenshot.
Watching the requests a page makes, blocking or failing some of them, and answering authentication challenges, using the W3C WebDriver BiDi network module.
You want to assert that the page called an API, fail a request to see how the application
copes, block the analytics beacon that slows every test down, or supply credentials to a
basic authentication challenge. Plain WebDriver only sees the DOM; it has no view of the
traffic behind it.
Recommended approach
Use the network module of WebDriver BiDi. It is part of the W3C standard, it works in every
browser that implements BiDi, and it is the Selenium project’s supported route for anything
that needs to observe or change network traffic.
The module has two halves. Events (beforeRequestSent, responseStarted,
responseCompleted, authRequired) let you subscribe to traffic and record or assert on it.
Intercepts pause requests at a chosen phase so your handler can continue them, fail them,
or, at the authRequired phase, continue them with a username and password. Enable BiDi in
the browser options when starting the session; the reference page shows the capability for
each binding.
Keep interception narrow. Match the URL patterns you care about, remove the intercept when
the test is done, and prefer failing or stubbing an external dependency over letting the test
talk to a live third-party service.
The Chrome DevTools Protocol integration that Selenium offered before BiDi existed is
Chromium-only, tied to specific browser versions, and being phased out. Do not start new work
on it.
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.importpytestfromselenium.common.exceptionsimportWebDriverException@pytest.mark.driver_type("bidi")deftest_add_intercept(driver):# _add_intercept is currently the available Python API for BiDi network intercepts.# This will be updated when a public API is stabilized.intercept=driver.network._add_intercept()assertinterceptisnotNonedriver.network._remove_intercept(intercept["intercept"])@pytest.mark.driver_type("bidi")deftest_remove_intercept(driver):# _add_intercept/_remove_intercept are currently the available Python APIs.# These will be updated when a public API is stabilized.intercept=driver.network._add_intercept()driver.network._remove_intercept(intercept["intercept"])assertdriver.network.intercepts==[]@pytest.mark.driver_type("bidi")deftest_fail_request(driver):fromselenium.webdriver.common.bidi.browsing_contextimportReadinessStatefromselenium.webdriver.common.bidi.networkimportRequestdefblock_request(request:Request):request.fail()driver.network.add_request_handler(["**/blank.html"],block_request)try:withpytest.raises(WebDriverException):driver.browsing_context.navigate(context=driver.current_window_handle,url="https://www.selenium.dev/selenium/web/blank.html",wait=ReadinessState.COMPLETE,)finally:driver.network.clear_request_handlers()@pytest.mark.driver_type("bidi")deftest_add_and_remove_request_handler(driver):fromselenium.webdriver.common.bidi.networkimportRequestrequests=[]defcallback(request:Request):requests.append(request)callback_id=driver.network.add_request_handler("before_request",callback)assertcallback_idisnotNonedriver.network.remove_request_handler("before_request",callback_id)driver.get("https://www.selenium.dev/selenium/web/blank.html")assertnotrequests
constassert=require("assert");constfirefox=require('selenium-webdriver/firefox');const{Network}=require("selenium-webdriver/bidi/network");const{until,Builder}=require("selenium-webdriver");describe('Network events',function(){letdriverbeforeEach(asyncfunction(){driver=newBuilder().forBrowser('firefox').setFirefoxOptions(newfirefox.Options().enableBidi()).build()})afterEach(asyncfunction(){awaitdriver.quit()})it('can listen to event before request is sent',asyncfunction(){letbeforeRequestEvent=[]constnetwork=awaitNetwork(driver)awaitnetwork.beforeRequestSent(function(event){beforeRequestEvent.push(event)})awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html')constcurrentUrl=awaitdriver.getCurrentUrl()constcurrentUrlFound=beforeRequestEvent.some(event=>event.request.url.includes(currentUrl))assert(currentUrlFound,`${currentUrl} was not requested`)})it('can request cookies',asyncfunction(){constnetwork=awaitNetwork(driver)letbeforeRequestEvent=nullawaitnetwork.beforeRequestSent(function(event){beforeRequestEvent=event})awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html')awaitdriver.manage().addCookie({name:'north',value:'biryani',})awaitdriver.navigate().refresh()assert.equal(beforeRequestEvent.request.method,'GET')assert.equal(beforeRequestEvent.request.cookies[0].name,'north')assert.equal(beforeRequestEvent.request.cookies[0].value.value,'biryani')awaitdriver.manage().addCookie({name:'south',value:'dosa',})awaitdriver.navigate().refresh()assert.equal(beforeRequestEvent.request.cookies[1].name,'south')assert.equal(beforeRequestEvent.request.cookies[1].value.value,'dosa')})it('can redirect http equiv',asyncfunction(){letbeforeRequestEvent=[]constnetwork=awaitNetwork(driver)awaitnetwork.beforeRequestSent(function(event){beforeRequestEvent.push(event)})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')awaitdriver.wait(until.urlContains('redirected.html'),1000)assert.equal(beforeRequestEvent[0].request.method,'GET')letredirectedFound=beforeRequestEvent.some(event=>event.request.url.includes('redirected.html'))assert(redirectedFound,'redirected.html was not requested')redirectedFound=beforeRequestEvent.some(event=>event.request.url.includes('redirected_http_equiv.html'))assert(redirectedFound,'redirected_http_equiv.html was not requested')})it('can subscribe to response started',asyncfunction(){letonResponseStarted=[]constnetwork=awaitNetwork(driver)awaitnetwork.responseStarted(function(event){onResponseStarted.push(event)})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')assert.equal(onResponseStarted[0].request.method,'GET')assert.equal(onResponseStarted[0].request.url,awaitdriver.getCurrentUrl())assert.equal(onResponseStarted[0].response.url,awaitdriver.getCurrentUrl())})it('can subscribe to response completed',asyncfunction(){letonResponseCompleted=[]constnetwork=awaitNetwork(driver)awaitnetwork.responseCompleted(function(event){onResponseCompleted.push(event)})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')assert.equal(onResponseCompleted[0].request.method,'GET')assert.equal(onResponseCompleted[0].request.url,awaitdriver.getCurrentUrl())assert.equal(onResponseCompleted[0].response.fromCache,false)assert.equal(onResponseCompleted[0].response.status,200)})})
packagedev.selenium.bidirectional.webdriver_bidi;importdev.selenium.BaseTest;importjava.time.Duration;importjava.time.temporal.ChronoUnit;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Disabled;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.openqa.selenium.TimeoutException;importorg.openqa.selenium.UsernameAndPassword;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.bidi.module.Network;importorg.openqa.selenium.bidi.network.AddInterceptParameters;importorg.openqa.selenium.bidi.network.InterceptPhase;importorg.openqa.selenium.firefox.FirefoxDriver;importorg.openqa.selenium.firefox.FirefoxOptions;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;classNetworkCommandsTestextendsBaseTest{@BeforeEachpublicvoidsetup(){FirefoxOptionsoptions=newFirefoxOptions();options.setCapability("webSocketUrl",true);driver=newFirefoxDriver(options);wait=newWebDriverWait(driver,Duration.ofSeconds(10));}@TestvoidcanAddIntercept(){try(Networknetwork=newNetwork(driver)){Stringintercept=network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));Assertions.assertNotNull(intercept);}}@TestvoidcanRemoveIntercept(){try(Networknetwork=newNetwork(driver)){Stringintercept=network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));Assertions.assertNotNull(intercept);network.removeIntercept(intercept);}}@TestvoidcanContinueWithAuthCredentials(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->network.continueWithAuth(responseDetails.getRequest().getRequestId(),newUsernameAndPassword("admin","admin")));driver.get("https://the-internet.herokuapp.com/basic_auth");StringsuccessMessage="Congratulations! You must have the proper credentials.";WebElementelementMessage=driver.findElement(By.tagName("p"));Assertions.assertEquals(successMessage,elementMessage.getText());}}@TestvoidcanContinueWithoutAuthCredentials(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->// Does not handle the alertnetwork.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));driver.get("https://the-internet.herokuapp.com/basic_auth");Alertalert=wait.until(ExpectedConditions.alertIsPresent());alert.dismiss();Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));}}@TestvoidcanCancelAuth(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->// Does not handle the alertnetwork.cancelAuth(responseDetails.getRequest().getRequestId()));driver.get("https://the-internet.herokuapp.com/basic_auth");Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));}}@TestvoidcanFailRequest(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));network.onBeforeRequestSent(responseDetails->network.failRequest(responseDetails.getRequest().getRequestId()));driver.manage().timeouts().pageLoadTimeout(Duration.of(5,ChronoUnit.SECONDS));Assertions.assertThrows(TimeoutException.class,()->driver.get("https://the-internet.herokuapp.com/basic_auth"));}}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.importpytestfromselenium.common.exceptionsimportWebDriverException@pytest.mark.driver_type("bidi")deftest_add_intercept(driver):# _add_intercept is currently the available Python API for BiDi network intercepts.# This will be updated when a public API is stabilized.intercept=driver.network._add_intercept()assertinterceptisnotNonedriver.network._remove_intercept(intercept["intercept"])@pytest.mark.driver_type("bidi")deftest_remove_intercept(driver):# _add_intercept/_remove_intercept are currently the available Python APIs.# These will be updated when a public API is stabilized.intercept=driver.network._add_intercept()driver.network._remove_intercept(intercept["intercept"])assertdriver.network.intercepts==[]@pytest.mark.driver_type("bidi")deftest_fail_request(driver):fromselenium.webdriver.common.bidi.browsing_contextimportReadinessStatefromselenium.webdriver.common.bidi.networkimportRequestdefblock_request(request:Request):request.fail()driver.network.add_request_handler(["**/blank.html"],block_request)try:withpytest.raises(WebDriverException):driver.browsing_context.navigate(context=driver.current_window_handle,url="https://www.selenium.dev/selenium/web/blank.html",wait=ReadinessState.COMPLETE,)finally:driver.network.clear_request_handlers()@pytest.mark.driver_type("bidi")deftest_add_and_remove_request_handler(driver):fromselenium.webdriver.common.bidi.networkimportRequestrequests=[]defcallback(request:Request):requests.append(request)callback_id=driver.network.add_request_handler("before_request",callback)assertcallback_idisnotNonedriver.network.remove_request_handler("before_request",callback_id)driver.get("https://www.selenium.dev/selenium/web/blank.html")assertnotrequests
packagedev.selenium.bidirectional.webdriver_bidi;importdev.selenium.BaseTest;importjava.time.Duration;importjava.time.temporal.ChronoUnit;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Disabled;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.openqa.selenium.TimeoutException;importorg.openqa.selenium.UsernameAndPassword;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.bidi.module.Network;importorg.openqa.selenium.bidi.network.AddInterceptParameters;importorg.openqa.selenium.bidi.network.InterceptPhase;importorg.openqa.selenium.firefox.FirefoxDriver;importorg.openqa.selenium.firefox.FirefoxOptions;importorg.openqa.selenium.support.ui.ExpectedConditions;importorg.openqa.selenium.support.ui.WebDriverWait;classNetworkCommandsTestextendsBaseTest{@BeforeEachpublicvoidsetup(){FirefoxOptionsoptions=newFirefoxOptions();options.setCapability("webSocketUrl",true);driver=newFirefoxDriver(options);wait=newWebDriverWait(driver,Duration.ofSeconds(10));}@TestvoidcanAddIntercept(){try(Networknetwork=newNetwork(driver)){Stringintercept=network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));Assertions.assertNotNull(intercept);}}@TestvoidcanRemoveIntercept(){try(Networknetwork=newNetwork(driver)){Stringintercept=network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));Assertions.assertNotNull(intercept);network.removeIntercept(intercept);}}@TestvoidcanContinueWithAuthCredentials(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->network.continueWithAuth(responseDetails.getRequest().getRequestId(),newUsernameAndPassword("admin","admin")));driver.get("https://the-internet.herokuapp.com/basic_auth");StringsuccessMessage="Congratulations! You must have the proper credentials.";WebElementelementMessage=driver.findElement(By.tagName("p"));Assertions.assertEquals(successMessage,elementMessage.getText());}}@TestvoidcanContinueWithoutAuthCredentials(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->// Does not handle the alertnetwork.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));driver.get("https://the-internet.herokuapp.com/basic_auth");Alertalert=wait.until(ExpectedConditions.alertIsPresent());alert.dismiss();Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));}}@TestvoidcanCancelAuth(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED));network.onAuthRequired(responseDetails->// Does not handle the alertnetwork.cancelAuth(responseDetails.getRequest().getRequestId()));driver.get("https://the-internet.herokuapp.com/basic_auth");Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));}}@TestvoidcanFailRequest(){try(Networknetwork=newNetwork(driver)){network.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));network.onBeforeRequestSent(responseDetails->network.failRequest(responseDetails.getRequest().getRequestId()));driver.manage().timeouts().pageLoadTimeout(Duration.of(5,ChronoUnit.SECONDS));Assertions.assertThrows(TimeoutException.class,()->driver.get("https://the-internet.herokuapp.com/basic_auth"));}}}
# Licensed to the Software Freedom Conservancy (SFC) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The SFC licenses this file# to you under the Apache License, Version 2.0 (the# "License"); you may not use this file except in compliance# with the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing,# software distributed under the License is distributed on an# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY# KIND, either express or implied. See the License for the# specific language governing permissions and limitations# under the License.importpytestfromselenium.common.exceptionsimportWebDriverException@pytest.mark.driver_type("bidi")deftest_add_intercept(driver):# _add_intercept is currently the available Python API for BiDi network intercepts.# This will be updated when a public API is stabilized.intercept=driver.network._add_intercept()assertinterceptisnotNonedriver.network._remove_intercept(intercept["intercept"])@pytest.mark.driver_type("bidi")deftest_remove_intercept(driver):# _add_intercept/_remove_intercept are currently the available Python APIs.# These will be updated when a public API is stabilized.intercept=driver.network._add_intercept()driver.network._remove_intercept(intercept["intercept"])assertdriver.network.intercepts==[]@pytest.mark.driver_type("bidi")deftest_fail_request(driver):fromselenium.webdriver.common.bidi.browsing_contextimportReadinessStatefromselenium.webdriver.common.bidi.networkimportRequestdefblock_request(request:Request):request.fail()driver.network.add_request_handler(["**/blank.html"],block_request)try:withpytest.raises(WebDriverException):driver.browsing_context.navigate(context=driver.current_window_handle,url="https://www.selenium.dev/selenium/web/blank.html",wait=ReadinessState.COMPLETE,)finally:driver.network.clear_request_handlers()@pytest.mark.driver_type("bidi")deftest_add_and_remove_request_handler(driver):fromselenium.webdriver.common.bidi.networkimportRequestrequests=[]defcallback(request:Request):requests.append(request)callback_id=driver.network.add_request_handler("before_request",callback)assertcallback_idisnotNonedriver.network.remove_request_handler("before_request",callback_id)driver.get("https://www.selenium.dev/selenium/web/blank.html")assertnotrequests
constassert=require("assert")constfirefox=require('selenium-webdriver/firefox')const{Network}=require('selenium-webdriver/bidi/network')const{until,By,Builder}=require('selenium-webdriver')const{AddInterceptParameters}=require("selenium-webdriver/bidi/addInterceptParameters");const{InterceptPhase}=require("selenium-webdriver/bidi/interceptPhase");describe('Network commands',function(){letdriverletnetworkbeforeEach(asyncfunction(){driver=newBuilder().forBrowser('firefox').setFirefoxOptions(newfirefox.Options().enableBidi()).build()network=awaitNetwork(driver)})afterEach(asyncfunction(){awaitnetwork.close()awaitdriver.quit()})it('can add intercept',asyncfunction(){constintercept=awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))assert.notEqual(intercept,null)})it('can remove intercept',asyncfunction(){constnetwork=awaitNetwork(driver)constintercept=awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))assert.notEqual(intercept,null)awaitnetwork.removeIntercept(intercept)})it('can continue with auth credentials ',asyncfunction(){awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED))awaitnetwork.authRequired(async(event)=>{awaitnetwork.continueWithAuth(event.request.request,'admin','admin')})awaitdriver.get('https://the-internet.herokuapp.com/basic_auth')constsuccessMessage='Congratulations! You must have the proper credentials.'letelementMessage=awaitdriver.findElement(By.tagName('p')).getText()assert.equal(elementMessage,successMessage)})it('can continue without auth credentials ',asyncfunction(){awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED))awaitnetwork.authRequired(async(event)=>{awaitnetwork.continueWithAuthNoCredentials(event.request.request)})awaitdriver.get('https://the-internet.herokuapp.com/basic_auth')constalert=awaitdriver.wait(until.alertIsPresent())awaitalert.dismiss()letsource=awaitdriver.getPageSource()assert.equal(source.includes('Not authorized'),true)})it('can cancel auth ',asyncfunction(){awaitnetwork.addIntercept(newAddInterceptParameters(InterceptPhase.AUTH_REQUIRED))awaitnetwork.authRequired(async(event)=>{awaitnetwork.cancelAuth(event.request.request)})awaitdriver.get('https://the-internet.herokuapp.com/basic_auth')letsource=awaitdriver.getPageSource()assert.equal(source.includes('Not authorized'),true)})})
Common errors
TimeoutException:
an intercepted request was never continued or failed, so navigation hung until the page load
timeout. Every intercepted request needs a handler that resolves it.
UnsupportedCommandException:
BiDi was not enabled for the session, or the browser does not implement the command yet.
Capturing the browser’s console output and JavaScript errors with BiDi, and turning up Selenium’s own logging to see what the bindings and the driver are doing.
Something went wrong, and the only evidence is a failed assertion. There are three separate
streams of information that could explain it: what the page wrote to the browser console,
what exception JavaScript threw, and what Selenium itself was sending to and receiving from
the driver. By default you see none of them.
Recommended approach
Browser console and JavaScript errors. With WebDriver BiDi enabled, the log module streams
console entries and uncaught JavaScript exceptions to your test as they happen. Register a
handler before the action you want to observe, then assert on the entries it collects. This
is the cross-browser, standards-based replacement for the old Chromium-only log retrieval,
and it catches errors the page swallowed before a user would have seen them.
Selenium’s own logging. Each binding logs through its language’s standard logging
facility: java.util.logging in Java, the logging module in Python, Selenium’s Log class
in .NET, and Selenium::WebDriver.logger in Ruby. Raising the level to debug shows every
command sent to the driver and every response, which is usually enough to tell whether the
problem is in your code, the driver or the browser. Logs go to the console by default; add a
file handler to keep them with the rest of your test artifacts.
Driver logs. The browser driver (chromedriver, geckodriver, and so on) keeps its own log,
configured through the driver’s service class. Reach for it when the browser fails to start or
crashes mid-session.
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.assertNull(logEntry.getStackTrace());}}@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(4,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
constassert=require("assert");constfirefox=require('selenium-webdriver/firefox');constLogInspector=require('selenium-webdriver/bidi/logInspector');const{Builder}=require("selenium-webdriver");describe('Log Inspector',function(){letdriverbeforeEach(asyncfunction(){driver=newBuilder().forBrowser('firefox').setFirefoxOptions(newfirefox.Options().enableBidi()).build()})afterEach(asyncfunction(){awaitdriver.quit()})it('test listen to console log',asyncfunction(){letlogEntry=nullconstinspector=awaitLogInspector(driver)awaitinspector.onConsoleEntry(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'consoleLog'}).click()assert.equal(logEntry.text,'Hello, world!')assert.equal(logEntry.realm,null)assert.equal(logEntry.type,'console')assert.equal(logEntry.level,'info')assert.equal(logEntry.method,'log')assert.equal(logEntry.stackTrace,null)assert.equal(logEntry.args.length,1)awaitinspector.close()})it('test listen to javascript error log',asyncfunction(){letlogEntry=nullconstinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()assert.equal(logEntry.text,'Error: Not working')assert.equal(logEntry.type,'javascript')assert.equal(logEntry.level,'error')awaitinspector.close()})it('test retrieve stack trace for a log',asyncfunction(){letlogEntry=nullconstinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()conststackTrace=logEntry.stackTraceassert.notEqual(stackTrace,null)assert.equal(stackTrace.callFrames.length,3)awaitinspector.close()})it('test listen to logs with multiple consumers',asyncfunction(){letlogEntry1=nullletlogEntry2=nullconstinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry1=log})awaitinspector.onJavascriptException(function(log){logEntry2=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()assert.equal(logEntry1.text,'Error: Not working')assert.equal(logEntry1.type,'javascript')assert.equal(logEntry1.level,'error')assert.equal(logEntry2.text,'Error: Not working')assert.equal(logEntry2.type,'javascript')assert.equal(logEntry2.level,'error')awaitinspector.close()})})
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.assertNull(logEntry.getStackTrace());}}@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(4,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());}}}
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"
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
constinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()assert.equal(logEntry.text,'Error: Not working')
constassert=require("assert");constfirefox=require('selenium-webdriver/firefox');constLogInspector=require('selenium-webdriver/bidi/logInspector');const{Builder}=require("selenium-webdriver");describe('Log Inspector',function(){letdriverbeforeEach(asyncfunction(){driver=newBuilder().forBrowser('firefox').setFirefoxOptions(newfirefox.Options().enableBidi()).build()})afterEach(asyncfunction(){awaitdriver.quit()})it('test listen to console log',asyncfunction(){letlogEntry=nullconstinspector=awaitLogInspector(driver)awaitinspector.onConsoleEntry(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'consoleLog'}).click()assert.equal(logEntry.text,'Hello, world!')assert.equal(logEntry.realm,null)assert.equal(logEntry.type,'console')assert.equal(logEntry.level,'info')assert.equal(logEntry.method,'log')assert.equal(logEntry.stackTrace,null)assert.equal(logEntry.args.length,1)awaitinspector.close()})it('test listen to javascript error log',asyncfunction(){letlogEntry=nullconstinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()assert.equal(logEntry.text,'Error: Not working')assert.equal(logEntry.type,'javascript')assert.equal(logEntry.level,'error')awaitinspector.close()})it('test retrieve stack trace for a log',asyncfunction(){letlogEntry=nullconstinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()conststackTrace=logEntry.stackTraceassert.notEqual(stackTrace,null)assert.equal(stackTrace.callFrames.length,3)awaitinspector.close()})it('test listen to logs with multiple consumers',asyncfunction(){letlogEntry1=nullletlogEntry2=nullconstinspector=awaitLogInspector(driver)awaitinspector.onJavascriptException(function(log){logEntry1=log})awaitinspector.onJavascriptException(function(log){logEntry2=log})awaitdriver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')awaitdriver.findElement({id:'jsException'}).click()assert.equal(logEntry1.text,'Error: Not working')assert.equal(logEntry1.type,'javascript')assert.equal(logEntry1.level,'error')assert.equal(logEntry2.text,'Error: Not working')assert.equal(logEntry2.type,'javascript')assert.equal(logEntry2.level,'error')awaitinspector.close()})})
packagedev.selenium.troubleshooting;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Path;importjava.util.Arrays;importjava.util.logging.FileHandler;importjava.util.logging.Handler;importjava.util.logging.Level;importjava.util.logging.Logger;importdev.selenium.BaseTest;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.manager.SeleniumManager;importorg.openqa.selenium.remote.RemoteWebDriver;publicclassLoggingTestextendsBaseTest{@AfterEachpublicvoidloggingOff(){Loggerlogger=Logger.getLogger("");logger.setLevel(Level.INFO);Arrays.stream(logger.getHandlers()).forEach(handler->{handler.setLevel(Level.INFO);});}@Testpublicvoidlogging()throwsIOException{Loggerlogger=Logger.getLogger("");logger.setLevel(Level.FINE);Arrays.stream(logger.getHandlers()).forEach(handler->{handler.setLevel(Level.FINE);});Pathoutput=artifactsDir().resolve("selenium.xml");Handlerhandler=newFileHandler(output.toString());logger.addHandler(handler);Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);LoggerlocalLogger=Logger.getLogger(this.getClass().getName());localLogger.warning("this is a warning");localLogger.info("this is useful information");localLogger.fine("this is detailed debug information");byte[]bytes=Files.readAllBytes(output);StringfileContent=newString(bytes);Assertions.assertTrue(fileContent.contains("this is a warning"));Assertions.assertTrue(fileContent.contains("this is useful information"));Assertions.assertTrue(fileContent.contains("this is detailed debug information"));}}
importloggingdeftest_logging(log_path):logger=logging.getLogger('selenium')logger.setLevel(logging.DEBUG)handler=logging.FileHandler(log_path)logger.addHandler(handler)logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)logger.info("this is useful information")logger.warning("this is a warning")logger.debug("this is detailed debug information")withopen(log_path,'r')asfp:assertlen(fp.readlines())==3
usingMicrosoft.VisualStudio.TestTools.UnitTesting;usingOpenQA.Selenium;usingOpenQA.Selenium.Internal.Logging;usingOpenQA.Selenium.Manager;usingOpenQA.Selenium.Remote;usingSystem;usingSystem.IO;namespaceSeleniumDocs.Troubleshooting{ [TestClass]publicclassLoggingTest{privateconststringfilePath="Selenium.log"; [TestMethod]publicvoidLogging(){Log.SetLevel(LogEventLevel.Trace);Log.Handlers.Add(newFileLogHandler(filePath));Log.SetLevel(typeof(RemoteWebDriver),LogEventLevel.Debug);Log.SetLevel(typeof(SeleniumManager),LogEventLevel.Info);Warn("this is a warning");Info("this is useful information");Debug("this is detailed debug information");using(varfileStream=File.Open(filePath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite)){using(varstreamReader=newStreamReader(fileStream)){varfileLogContent=streamReader.ReadToEnd();StringAssert.Contains(fileLogContent,"this is a warning");StringAssert.Contains(fileLogContent,"this is useful information");StringAssert.Contains(fileLogContent,"this is detailed debug information");}}} [TestCleanup]publicvoidTestCleanup(){// reset log to defaultLog.SetLevel(LogEventLevel.Info).Handlers.Clear().Handlers.Add(newTextWriterHandler(Console.Error));}// logging is only for internal usage// hacking it via reflectionprivatevoidDebug(stringmessage){LogMessage("Debug",message);}privatevoidWarn(stringmessage){LogMessage("Warn",message);}privatevoidInfo(stringmessage){LogMessage("Info",message);}privatevoidLogMessage(stringmethodName,stringmessage){vargetLoggerMethod=typeof(Log).GetMethod("GetLogger",System.Reflection.BindingFlags.Static|System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.NonPublic,newType[]{typeof(Type)});varlogger=getLoggerMethod.Invoke(null,newobject[]{typeof(LoggingTest)});varemitMethod=logger.GetType().GetMethod(methodName);emitMethod.Invoke(logger,newobject[]{message});}}}
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Logging'dolet(:file_name){Tempfile.new('logging').path}after{FileUtils.rm_f(file_name)}it'logs things'dologger=Selenium::WebDriver.loggerlogger.level=:debuglogger.output=file_namelogger.ignore(:jwp_caps,:logger_info)logger.allow(%i[selenium_managerexample_id])logger.warn('this is a warning',id::example_id)logger.info('this is useful information',id::example_id)logger.debug('this is detailed debug information',id::example_id)expect(File.readlines(file_name).grep(/\[:example_id\]/).size).toeq3endend
Common errors
JavascriptException:
a script you executed through WebDriver threw. The BiDi log module shows the page’s own
errors, which this exception does not cover.
Running a Selenium suite on a build server: headless browsers, driver management without manual downloads, and when to move to Grid or Docker.
The suite passes on your laptop and fails on the build server. The server has no display, a
different browser version, no driver on the PATH, and a locked-down network. Each of those
is a separate failure with a separate fix, and the error messages rarely say which one you
have hit.
Recommended approach
No display. Run the browser headless. Chrome and Edge take the --headless=new argument,
Firefox takes -headless. The page renders the same way, so only the browser options change.
Keep headless behind a configuration flag so you can still watch a test locally.
No driver. Do not download driver binaries in your pipeline. Selenium Manager, which
ships with Selenium 4.6 and later, detects the installed browser, downloads the matching
driver, and caches it in ~/.cache/selenium; cache that directory between runs. Some hosted
runners pre-install drivers on the PATH, and a stale one there takes precedence over
Selenium Manager, so remove it or keep it current.
Locked-down network. Selenium Manager needs to reach the browser vendors’ download
endpoints the first time. Behind a proxy, set it with the SE_PROXY environment variable or
the Selenium Manager configuration file.
Scale. When one runner starting one browser per test becomes too slow, point the same
tests at a Selenium Grid and run them in parallel without
changing the test code.
Collect a screenshot and the Selenium log on every failure; a CI failure without artifacts
is a re-run waiting to happen.
packagedev.selenium.browsers;importdev.selenium.BaseTest;importjava.io.File;importjava.io.IOException;importjava.io.PrintStream;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.Paths;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.Test;importorg.junit.jupiter.api.condition.DisabledOnOs;importorg.junit.jupiter.api.condition.OS;importorg.openqa.selenium.By;importorg.openqa.selenium.OutputType;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.firefox.*;importorg.openqa.selenium.remote.service.DriverFinder;publicclassFirefoxTestextendsBaseTest{privateFirefoxDriverdriver;@AfterEachpublicvoidclearProperties(){System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);if(driver!=null){driver.quit();}}@TestpublicvoidbasicOptions(){FirefoxOptionsoptions=newFirefoxOptions();driver=newFirefoxDriver(options);}@Testpublicvoidarguments(){FirefoxOptionsoptions=newFirefoxOptions();options.addArguments("-headless");driver=newFirefoxDriver(options);}@Test@DisabledOnOs(OS.WINDOWS)publicvoidsetBrowserLocation(){FirefoxOptionsoptions=newFirefoxOptions();options.setBinary(getFirefoxLocation());driver=newFirefoxDriver(options);}@TestpublicvoidlogsToFile()throwsIOException{FilelogLocation=getTempFile("logsToFile",".log");FirefoxDriverServiceservice=newGeckoDriverService.Builder().withLogFile(logLocation).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertTrue(fileContent.contains("geckodriver INFO Listening on"));}@TestpublicvoidlogsToConsole()throwsIOException{FilelogLocation=getTempFile("logsToConsole",".log");System.setOut(newPrintStream(logLocation));FirefoxDriverServiceservice=newGeckoDriverService.Builder().withLogOutput(System.out).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertTrue(fileContent.contains("geckodriver INFO Listening on"));}@TestpublicvoidlogsWithLevel()throwsIOException{FilelogLocation=getTempFile("logsWithLevel",".log");System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY,logLocation.getAbsolutePath());FirefoxDriverServiceservice=newGeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));}@TestpublicvoidstopsTruncatingLogs()throwsIOException{FilelogLocation=getTempFile("geckodriver-","log");System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY,logLocation.getAbsolutePath());System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY,FirefoxDriverLogLevel.DEBUG.toString());FirefoxDriverServiceservice=newGeckoDriverService.Builder().withTruncatedLogs(false).build();driver=newFirefoxDriver(service);StringfileContent=newString(Files.readAllBytes(logLocation.toPath()));Assertions.assertFalse(fileContent.contains(" ... "));}@TestpublicvoidsetProfileLocation(){FileprofileDirectory=getTempDirectory("profile-");FirefoxDriverServiceservice=newGeckoDriverService.Builder().withProfileRoot(profileDirectory).build();driver=newFirefoxDriver(service);Stringlocation=(String)driver.getCapabilities().getCapability("moz:profile");Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));}@TestpublicvoidinstallAddon(){driver=startFirefoxDriver();PathxpiPath=Paths.get("src/test/resources/extensions/selenium-example.xpi");driver.installExtension(xpiPath);driver.get("https://www.selenium.dev/selenium/web/blank.html");WebElementinjected=driver.findElement(By.id("webextensions-selenium-example"));Assertions.assertEquals("Content injected by webextensions-selenium-example",injected.getText());}@TestpublicvoiduninstallAddon(){driver=startFirefoxDriver();PathxpiPath=Paths.get("src/test/resources/extensions/selenium-example.xpi");Stringid=driver.installExtension(xpiPath);driver.uninstallExtension(id);driver.get("https://www.selenium.dev/selenium/web/blank.html");Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(),0);}@TestpublicvoidinstallUnsignedAddonPath(){driver=startFirefoxDriver();Pathpath=Paths.get("src/test/resources/extensions/selenium-example");driver.installExtension(path,true);driver.get("https://www.selenium.dev/selenium/web/blank.html");WebElementinjected=getLocatedElement(driver,By.id("webextensions-selenium-example"));Assertions.assertEquals("Content injected by webextensions-selenium-example",injected.getText());}privatePathgetFirefoxLocation(){FirefoxOptionsoptions=newFirefoxOptions();options.setBrowserVersion("stable");DriverFinderfinder=newDriverFinder(GeckoDriverService.createDefaultService(),options);returnPath.of(finder.getBrowserPath());}@TestpublicvoidfullPageScreenshot()throwsException{driver=startFirefoxDriver();driver.get("https://www.selenium.dev");Filescreenshot=driver.getFullPageScreenshotAs(OutputType.FILE);FiletargetFile=newFile("full_page_screenshot.png");Files.move(screenshot.toPath(),targetFile.toPath());// Verify the screenshot file existsAssertions.assertTrue(targetFile.exists(),"The full page screenshot file should exist");Files.deleteIfExists(targetFile.toPath());}@TestpublicvoidsetContext(){driver=startFirefoxDriver(newFirefoxOptions().addArguments("-remote-allow-system-access"));driver.setContext(FirefoxCommandContext.CHROME);driver.executeScript("console.log('Inside Chrome context');");// Verify the context is back to "content"Assertions.assertEquals(FirefoxCommandContext.CHROME,driver.getContext(),"The context should be 'chrome'");}@TestpublicvoidfirefoxProfile(){FirefoxProfileprofile=newFirefoxProfile();FirefoxOptionsoptions=newFirefoxOptions();profile.setPreference("javascript.enabled","False");options.setProfile(profile);driver=newFirefoxDriver(options);}}
importosimportsubprocessimportsysimportpytestfromseleniumimportwebdriverdeftest_basic_options():options=webdriver.FirefoxOptions()driver=webdriver.Firefox(options=options)driver.quit()deftest_arguments():options=webdriver.FirefoxOptions()options.add_argument("-headless")driver=webdriver.Firefox(options=options)driver.quit()deftest_set_browser_location(firefox_bin):options=webdriver.FirefoxOptions()options.binary_location=firefox_bindriver=webdriver.Firefox(options=options)driver.quit()deftest_log_to_file(log_path):service=webdriver.FirefoxService(log_output=log_path,service_args=['--log','debug'])driver=webdriver.Firefox(service=service)driver.get("https://www.selenium.dev")withopen(log_path,'r')asfp:assert"geckodriver INFO Listening on"infp.readline()driver.quit()deftest_log_to_stdout(capfd):service=webdriver.FirefoxService(log_output=subprocess.STDOUT)driver=webdriver.Firefox(service=service)out,err=capfd.readouterr()assert"geckodriver INFO Listening on"inoutdriver.quit()deftest_log_level(log_path):service=webdriver.FirefoxService(log_output=log_path,service_args=['--log','debug'])driver=webdriver.Firefox(service=service)withopen(log_path,'r')asf:assert'\tDEBUG'inf.read()driver.quit()deftest_log_truncation(log_path):service=webdriver.FirefoxService(service_args=['--log-no-truncate','--log','debug'],log_output=log_path)driver=webdriver.Firefox(service=service)withopen(log_path,'r')asf:assert' ... 'notinf.read()driver.quit()deftest_profile_location(temp_dir):service=webdriver.FirefoxService(service_args=['--profile-root',temp_dir])driver=webdriver.Firefox(service=service)profile_name=driver.capabilities.get('moz:profile').replace('\\','/').split('/')[-1]assertprofile_nameinos.listdir(temp_dir)driver.quit()deftest_install_addon(firefox_driver,addon_path_xpi):driver=firefox_driverdriver.install_addon(addon_path_xpi)driver.get("https://www.selenium.dev/selenium/web/blank.html")injected=driver.find_element(webdriver.common.by.By.ID,"webextensions-selenium-example")assertinjected.text=="Content injected by webextensions-selenium-example"deftest_uninstall_addon(firefox_driver,addon_path_xpi):driver=firefox_driverid=driver.install_addon(addon_path_xpi)driver.uninstall_addon(id)driver.get("https://www.selenium.dev/selenium/web/blank.html")assertlen(driver.find_elements(webdriver.common.by.By.ID,"webextensions-selenium-example"))==0deftest_install_unsigned_addon_directory(firefox_driver,addon_path_dir):driver=firefox_driverdriver.install_addon(addon_path_dir,temporary=True)driver.get("https://www.selenium.dev/selenium/web/blank.html")injected=driver.find_element(webdriver.common.by.By.ID,"webextensions-selenium-example")assertinjected.text=="Content injected by webextensions-selenium-example"deftest_install_unsigned_addon_directory_slash(firefox_driver,addon_path_dir_slash):driver=firefox_driverdriver.install_addon(addon_path_dir_slash,temporary=True)driver.get("https://www.selenium.dev/selenium/web/blank.html")injected=driver.find_element(webdriver.common.by.By.ID,"webextensions-selenium-example")assertinjected.text=="Content injected by webextensions-selenium-example"deftest_full_page_screenshot(firefox_driver):driver=firefox_driverdriver.get("https://www.selenium.dev")driver.save_full_page_screenshot("full_page_screenshot.png")assertos.path.exists("full_page_screenshot.png")driver.quit()deftest_set_context():options=webdriver.FirefoxOptions()options.add_argument("-remote-allow-system-access")driver=webdriver.Firefox(options=options)withdriver.context(driver.CONTEXT_CHROME):driver.execute_script("console.log('Inside Chrome context');")# Check if the context is back to contentassertdriver.execute("GET_CONTEXT")["value"]=="content"driver.quit()deftest_firefox_profile():fromselenium.webdriver.firefox.optionsimportOptionsfromselenium.webdriver.firefox.firefox_profileimportFirefoxProfileoptions=Options()firefox_profile=FirefoxProfile()firefox_profile.set_preference("javascript.enabled",False)options.profile=firefox_profiledriver=webdriver.Firefox(options=options)driver.quit()
usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingMicrosoft.VisualStudio.TestTools.UnitTesting;usingOpenQA.Selenium;usingOpenQA.Selenium.Firefox;usingOpenQA.Selenium.Internal.Logging;namespaceSeleniumDocs.Browsers{ [TestClass]publicclassFirefoxTest{privateFirefoxDriverdriver;privatestring_logLocation;privatestring_tempPath; [TestCleanup]publicvoidCleanup(){if(!String.IsNullOrEmpty(_logLocation)&&File.Exists(_logLocation)){File.Delete(_logLocation);}if(_tempPath!=null&&File.Exists(_tempPath)){File.Delete(_tempPath);}driver.Quit();} [TestMethod]publicvoidBasicOptions(){varoptions=newFirefoxOptions();driver=newFirefoxDriver(options);} [TestMethod]publicvoidArguments(){varoptions=newFirefoxOptions();options.AddArgument("-headless");driver=newFirefoxDriver(options);} [TestMethod]publicvoidSetBinary(){varoptions=newFirefoxOptions();options.BinaryLocation=GetFirefoxLocation();driver=newFirefoxDriver(options);} [TestMethod]publicvoidLogsToFile(){varservice=FirefoxDriverService.CreateDefaultService();service.LogPath=GetLogLocation();driver=newFirefoxDriver(service);driver.Quit();// Close the Service log file before readingvarlines=File.ReadLines(GetLogLocation());Assert.IsNotNull(lines.FirstOrDefault(line=>line.Contains("geckodriver INFO Listening on")));} [TestMethod]publicvoidLogsToConsole(){TestLogHandlertestLogHandler=newTestLogHandler();ResetGlobalLog();try{Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);varservice=FirefoxDriverService.CreateDefaultService();driver=newFirefoxDriver(service);Assert.IsTrue(testLogHandler.Events.Count>=1);Assert.IsTrue(testLogHandler.Events.Any(e=>e.Message.Contains("geckodriver")));}finally{ResetGlobalLog();}} [TestMethod]publicvoidLogsLevel(){varservice=FirefoxDriverService.CreateDefaultService();service.LogPath=GetLogLocation();service.LogLevel=FirefoxDriverLogLevel.Debug;driver=newFirefoxDriver(service);driver.Quit();// Close the Service log file before readingvarlines=File.ReadLines(GetLogLocation());Assert.IsNotNull(lines.FirstOrDefault(line=>line.Contains("Marionette\tDEBUG")));} [TestMethod]publicvoidStopsTruncatingLogs(){varservice=FirefoxDriverService.CreateDefaultService();service.LogTruncate=false;service.LogLevel=FirefoxDriverLogLevel.Debug;driver=newFirefoxDriver(service);driver.Quit();// Close the Service log file before readingvarlines=File.ReadLines(GetLogLocation());Assert.IsNull(lines.FirstOrDefault(line=>line.Contains(" ... ")));} [TestMethod]publicvoidSetProfileLocation(){varservice=FirefoxDriverService.CreateDefaultService();service.ProfileRoot=GetTempDirectory();driver=newFirefoxDriver(service);stringprofile=(string)driver.Capabilities.GetCapability("moz:profile");string[]directories=profile.Split("/");vardirName=directories.Last();Assert.AreEqual(GetTempDirectory()+dirName,profile);} [TestMethod]publicvoidInstallAddon(){SetWaitingDriver();stringbaseDir=AppDomain.CurrentDomain.BaseDirectory;stringextensionFilePath=Path.Combine(baseDir,"../../../Extensions/webextensions-selenium-example.xpi");driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));driver.Url="https://www.selenium.dev/selenium/web/blank.html";IWebElementinjected=driver.FindElement(By.Id("webextensions-selenium-example"));Assert.AreEqual("Content injected by webextensions-selenium-example",injected.Text);} [TestMethod]publicvoidUnInstallAddon(){driver=newFirefoxDriver();stringbaseDir=AppDomain.CurrentDomain.BaseDirectory;stringextensionFilePath=Path.Combine(baseDir,"../../../Extensions/webextensions-selenium-example.xpi");stringextensionId=driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));driver.UninstallAddOn(extensionId);driver.Url="https://www.selenium.dev/selenium/web/blank.html";Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count,0);} [TestMethod]publicvoidInstallUnsignedAddon(){SetWaitingDriver();stringbaseDir=AppDomain.CurrentDomain.BaseDirectory;stringextensionDirPath=Path.Combine(baseDir,"../../../Extensions/webextensions-selenium-example/");driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath),true);driver.Url="https://www.selenium.dev/selenium/web/blank.html";IWebElementinjected=driver.FindElement(By.Id("webextensions-selenium-example"));Assert.AreEqual("Content injected by webextensions-selenium-example",injected.Text);}privatestringGetLogLocation(){if(string.IsNullOrEmpty(_logLocation)&&!File.Exists(_logLocation)){_logLocation=Path.GetTempFileName();}return_logLocation;}privatestringGetTempDirectory(){if(string.IsNullOrEmpty(_tempPath)&&!File.Exists(_tempPath)){_tempPath=Path.GetTempPath();}return_tempPath;}privatevoidSetWaitingDriver(){driver=newFirefoxDriver();driver.Manage().Timeouts().ImplicitWait=TimeSpan.FromSeconds(2);}privatestaticstringGetFirefoxLocation(){varoptions=newFirefoxOptions(){BrowserVersion="stable"};returnnewDriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();}privatevoidResetGlobalLog(){Log.SetLevel(LogEventLevel.Info);Log.Handlers.Clear().Handlers.Add(newTextWriterHandler(Console.Error));}}}classTestLogHandler:ILogHandler{publicILogHandlerClone(){returnthis;}publicvoidHandle(LogEventlogEvent){Events.Add(logEvent);}publicIList<LogEvent>Events{get;internalset;}=newList<LogEvent>();}
# frozen_string_literal: truerequire'spec_helper'RSpec.describe'Firefox'dodescribe'Options'dolet(:firefox_location){driver_finder&&ENV.fetch('FIREFOX_BIN',nil)}it'basic options'dooptions=Selenium::WebDriver::Options.firefox@driver=Selenium::WebDriver.for:firefox,options:optionsendit'add arguments'dooptions=Selenium::WebDriver::Options.firefoxoptions.args<<'-headless'@driver=Selenium::WebDriver.for:firefox,options:optionsendit'sets location of binary'dooptions=Selenium::WebDriver::Options.firefoxoptions.binary=firefox_location@driver=Selenium::WebDriver.for:firefox,options:optionsendenddescribe'Service'dolet(:file_name){Tempfile.new('geckodriver').path}let(:root_directory){Dir.mktmpdir}afterdoFileUtils.rm_f(file_name)FileUtils.rm_rf(root_directory)endit'logs to file'doservice=Selenium::WebDriver::Service.firefoxservice.log=file_name@driver=Selenium::WebDriver.for:firefox,service:serviceexpect(File.readlines(file_name).first).toinclude("geckodriver\tINFO\tListening on")endit'logs to console'doservice=Selenium::WebDriver::Service.firefoxservice.log=$stdoutexpect{@driver=Selenium::WebDriver.for:firefox,service:service}.tooutput(/geckodriver INFO Listening on/).to_stdout_from_any_processendit'sets log level'doservice=Selenium::WebDriver::Service.firefoxservice.log=file_nameservice.args+=%w[--log debug]@driver=Selenium::WebDriver.for:firefox,service:serviceexpect(File.readlines(file_name).grep(/Marionette DEBUG/).any?).toeqtrueendit'stops truncating log lines'doservice=Selenium::WebDriver::Service.firefox(log:file_name,args:%w[--log debug])service.args<<'--log-no-truncate'@driver=Selenium::WebDriver.for:firefox,service:serviceexpect(File.readlines(file_name).grep(/ \.\.\. /).any?).toeqfalseendit'sets default profile location'doservice=Selenium::WebDriver::Service.firefoxservice.args+=['--profile-root',root_directory]@driver=Selenium::WebDriver.for:firefox,service:serviceprofile_location=Dir.new(@driver.capabilities['moz:profile'])expect(profile_location.path.gsub('\\','/')).toinclude(root_directory)endenddescribe'Features'dolet(:driver){start_firefox}it'installs addon'doextension_file_path=File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi',__dir__)driver.install_addon(extension_file_path)driver.get'https://www.selenium.dev/selenium/web/blank.html'injected=driver.find_element(id:'webextensions-selenium-example')expect(injected.text).toeq'Content injected by webextensions-selenium-example'endit'uninstalls addon'doextension_file_path=File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi',__dir__)extension_id=driver.install_addon(extension_file_path)driver.uninstall_addon(extension_id)driver.get'https://www.selenium.dev/selenium/web/blank.html'expect(driver.find_elements(id:'webextensions-selenium-example')).tobe_emptyendit'installs unsigned addon'doextension_dir_path=File.expand_path('../spec_support/extensions/webextensions-selenium-example/',__dir__)driver.install_addon(extension_dir_path,true)driver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'injected=driver.find_element(id:'webextensions-selenium-example')expect(injected.text).toeq'Content injected by webextensions-selenium-example'endit'takes full page screenshot'dodriver.navigate.to'https://www.selenium.dev/selenium/web/blank.html'Dir.mktmpdir('screenshot_test')do|dir|screenshot=driver.save_full_page_screenshot(File.join(dir,'screenshot.png'))expect(screenshot).tobe_aFileendendit'sets the context'dodriver.context='content'expect(driver.context).toeq'content'endenddescribe'Profile'doit'creates a new profile'doprofile=Selenium::WebDriver::Firefox::Profile.newprofile['browser.download.dir']='/tmp/webdriver-downloads'options=Selenium::WebDriver::Firefox::Options.new(profile:profile)expect(options.profile).toeq(profile)endenddefdriver_finderoptions=Selenium::WebDriver::Options.firefox(browser_version:'stable')service=Selenium::WebDriver::Service.firefoxfinder=Selenium::WebDriver::DriverFinder.new(options,service)ENV['GECKODRIVER_BIN']=finder.driver_pathENV['FIREFOX_BIN']=finder.browser_pathendend
constChrome=require('selenium-webdriver/chrome');const{Browser,Builder}=require("selenium-webdriver");constoptions=newChrome.Options();describe('Should be able to Test Command line arguments',function(){it('headless',asyncfunction(){letdriver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options.addArguments('--headless=new')).build();awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');awaitdriver.quit();});it('exclude switches',asyncfunction(){letdriver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options.excludeSwitches('enable-automation')).build();awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');awaitdriver.quit();});it('Keep browser open - set detach to true ',asyncfunction(){letdriver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options.detachDriver(true)).build();awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');// As tests runs in ci, quitting the driver instance to avoid any failures
awaitdriver.quit();});xit('Start browser from specified location ',asyncfunction(){letdriver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`)).build();awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');awaitdriver.quit();});it('Basic Chrome test',asyncfunction(){constOptions=newChrome.Options();letdriver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(Options).build();awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');awaitdriver.quit();});it('Add Extension',asyncfunction(){constoptions=newChrome.Options();letdriver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx'])).build();awaitdriver.get('https://www.selenium.dev/selenium/web/blank.html');awaitdriver.quit();});});
A minimal GitHub Actions workflow, shown for Python, is a starting point only. The hosted
Ubuntu runner already has Chrome and Firefox installed; the only Selenium-specific step is
installing the binding:
The same shape applies to every binding: check out, install the language toolchain, install
the Selenium package, run the standard test command.
Common errors
Unable to locate driver:
Selenium Manager could not find or download a driver. Check the browser is installed and the
network allows the download.
SessionNotCreatedException:
the driver on the PATH does not match the installed browser, or the browser cannot start
without a display. Remove stale drivers and run headless.
InvalidArgumentException:
a browser option is wrong for this browser or version, for example a user data directory that is already in use by another session.
Test practices: keeping tests independent so they can run in parallel
11 - Running in Docker and Grid
Moving the browser off the machine that runs the tests, with Selenium Grid and the project’s Docker images, so a suite can run in parallel and against several browsers.
A suite that takes an hour because every test starts its own browser on the same machine.
A requirement to test on a browser that is not installed where the tests run. A build server
that must not have a browser on it at all. In each case the browser needs to be somewhere
other than the test process.
Recommended approach
Selenium Grid is a server that accepts WebDriver sessions over HTTP and routes them to
browsers it manages. Your test code changes in exactly one place: instead of constructing a
local driver, construct a remote one with the Grid URL and the browser options. Everything
else stays the same, so a suite can run locally during development and on a Grid in CI with a
single configuration switch.
Standalone mode runs the whole Grid in one process and is the right starting point. It
needs a Java runtime and the Selenium Server jar, listens on http://localhost:4444, and can
use Selenium Manager to fetch drivers for the browsers it finds. Hub and Node spreads
browsers across several machines, and distributed mode separates each Grid component for
large installations.
The quickest way to get a Grid, and the only way to get one with no browser on the host, is
the project’s own Docker images in the
docker-selenium repository. They package the
Grid, a browser and its driver, and are published for each Selenium release. A single
docker run gives you a standalone Grid with Chrome, Firefox or Edge; the repository also has
Docker Compose and Kubernetes examples, video recording, and VNC for watching a session.
When the browser is remote, files to upload must reach the node first, through a file
detector, and downloads must be enabled on the Grid and fetched back through the client. Both
are covered on the remote WebDriver page.
packagedev.selenium.drivers;importdev.selenium.BaseTest;importjava.io.File;importjava.io.IOException;importjava.net.URL;importjava.nio.file.Files;importjava.nio.file.Path;importjava.time.Duration;importjava.util.ArrayList;importjava.util.Comparator;importjava.util.List;importjava.util.Map;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.openqa.selenium.By;importorg.openqa.selenium.HasDownloads;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.chrome.ChromeOptions;importorg.openqa.selenium.chromium.HasCasting;importorg.openqa.selenium.remote.Augmenter;importorg.openqa.selenium.remote.LocalFileDetector;importorg.openqa.selenium.remote.RemoteWebDriver;importorg.openqa.selenium.remote.http.ClientConfig;importorg.openqa.selenium.support.ui.WebDriverWait;publicclassRemoteWebDriverTestextendsBaseTest{URLgridUrl;@BeforeEachpublicvoidstartGrid(){gridUrl=startStandaloneGrid();}@TestpublicvoidrunRemote(){ChromeOptionsoptions=getDefaultChromeOptions();driver=newRemoteWebDriver(gridUrl,options);}@Testpublicvoiduploads(){ChromeOptionsoptions=getDefaultChromeOptions();driver=newRemoteWebDriver(gridUrl,options);driver.get("https://the-internet.herokuapp.com/upload");FileuploadFile=newFile("src/test/resources/selenium-snapshot.png");((RemoteWebDriver)driver).setFileDetector(newLocalFileDetector());WebElementfileInput=driver.findElement(By.cssSelector("input[type=file]"));fileInput.sendKeys(uploadFile.getAbsolutePath());driver.findElement(By.id("file-submit")).click();WebElementfileName=driver.findElement(By.id("uploaded-files"));Assertions.assertEquals("selenium-snapshot.png",fileName.getText());}@Testpublicvoiddownloads()throwsIOException{ChromeOptionsoptions=getDefaultChromeOptions();options.setEnableDownloads(true);driver=newRemoteWebDriver(gridUrl,options);List<String>fileNames=newArrayList<>();fileNames.add("file_1.txt");fileNames.add("file_2.jpg");driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");driver.findElement(By.id("file-1")).click();driver.findElement(By.id("file-2")).click();newWebDriverWait(driver,Duration.ofSeconds(5)).until(d->((HasDownloads)d).getDownloadableFiles().contains("file_2.jpg"));List<String>files=((HasDownloads)driver).getDownloadableFiles();// Sorting them to avoid differences when comparing the filesfileNames.sort(Comparator.naturalOrder());files.sort(Comparator.naturalOrder());Assertions.assertEquals(fileNames,files);StringdownloadableFile=files.get(0);PathtargetDirectory=Files.createTempDirectory("download");((HasDownloads)driver).downloadFile(downloadableFile,targetDirectory);StringfileContent=String.join("",Files.readAllLines(targetDirectory.resolve(downloadableFile)));Assertions.assertEquals("Hello, World!",fileContent);((HasDownloads)driver).deleteDownloadableFiles();Assertions.assertTrue(((HasDownloads)driver).getDownloadableFiles().isEmpty());}@Testpublicvoidaugment(){ChromeOptionsoptions=getDefaultChromeOptions();driver=newRemoteWebDriver(gridUrl,options);driver=newAugmenter().augment(driver);Assertions.assertTrue(driverinstanceofHasCasting);}@TestpublicvoidremoteWebDriverBuilder(){driver=RemoteWebDriver.builder().address(gridUrl).oneOf(getDefaultChromeOptions()).setCapability("ext:options",Map.of("key","value")).config(ClientConfig.defaultConfig()).build();Assertions.assertTrue(driverinstanceofHasCasting);}}
const{Browser,Builder,By}=require('selenium-webdriver')constChrome=require('selenium-webdriver/chrome')constremote=require('selenium-webdriver/remote')constassert=require('node:assert')constfs=require('node:fs')constos=require('node:os')constpath=require('node:path')const{startGrid,stopGrid}=require('./gridServer')asyncfunctionwaitForFile(filePath,timeout){constdeadline=Date.now()+timeoutwhile(!fs.existsSync(filePath)){if(Date.now()>deadline){thrownewError(`Timed out waiting for ${filePath} to be written`)}awaitnewPromise((resolve)=>setTimeout(resolve,100))}}describe('Remote WebDriver Test',function(){letdriverletgridUrlletgridProcessbeforeEach(asyncfunction(){constgrid=awaitstartGrid()gridUrl=grid.urlgridProcess=grid.process})afterEach(asyncfunction(){try{if(driver){awaitdriver.quit()driver=null}}finally{stopGrid(gridProcess)}})it('Basic Example',asyncfunction(){constoptions=newChrome.Options().addArguments('--no-sandbox')driver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options).usingServer(gridUrl).build()})it('Uploads',asyncfunction(){constoptions=newChrome.Options().addArguments('--no-sandbox')driver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options).usingServer(gridUrl).build()awaitdriver.get('https://the-internet.herokuapp.com/upload')constuploadFile=path.resolve('./test/resources/selenium-snapshot.png')awaitdriver.setFileDetector(newremote.FileDetector())awaitdriver.findElement(By.css('input[type=file]')).sendKeys(uploadFile)awaitdriver.findElement(By.id('file-submit')).click()constfileName=awaitdriver.findElement(By.id('uploaded-files')).getText()assert.strictEqual(fileName,'selenium-snapshot.png')})it('Downloads',asyncfunction(){constoptions=newChrome.Options().addArguments('--no-sandbox').enableDownloads()driver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options).usingServer(gridUrl).build()constfileNames=['file_1.txt','file_2.jpg']awaitdriver.get('https://www.selenium.dev/selenium/web/downloads/download.html')awaitdriver.findElement(By.id('file-1')).click()awaitdriver.findElement(By.id('file-2')).click()awaitdriver.wait(async(d)=>{constdownloaded=awaitd.getDownloadableFiles()returnfileNames.every((name)=>downloaded.includes(name))},5000)constfiles=awaitdriver.getDownloadableFiles()assert.deepStrictEqual(files.sort(),fileNames.sort())consttargetDirectory=fs.mkdtempSync(path.join(os.tmpdir(),'downloads-'))constdownloadableFile=files[0]awaitdriver.downloadFile(downloadableFile,targetDirectory)constdownloadedFilePath=path.join(targetDirectory,downloadableFile)awaitwaitForFile(downloadedFilePath,5000)constfileContent=fs.readFileSync(downloadedFilePath,'utf8')assert.strictEqual(fileContent.trim(),'Hello, World!')awaitdriver.deleteDownloadableFiles()assert.deepStrictEqual(awaitdriver.getDownloadableFiles(),[])})it('Browser specific functionalities',asyncfunction(){constoptions=newChrome.Options().addArguments('--no-sandbox')driver=newBuilder().forBrowser(Browser.CHROME).setChromeOptions(options).usingServer(gridUrl).build()assert.ok(driverinstanceofChrome.Driver)})})
Common errors
SessionNotCreatedException:
no node on the Grid can satisfy the requested browser and version. Check the Grid’s status
page at the Grid URL for the capabilities it offers.
InvalidArgumentException:
a local file path was sent to a remote browser. Set a file detector so the file is uploaded.
WebDriverException
with a connection error: the Grid URL is wrong, the server is not running, or a firewall is
between the client and the Grid.
docker-selenium: the project’s Docker images and deployment examples
12 - Debugging a failing test
A short procedure for working out why a Selenium test failed: read the exception, gather evidence, and narrow the cause before changing anything.
A test that used to pass now fails, or passes locally and fails in CI, or fails one run in
five. The temptation is to add a sleep, re-run, and move on. That hides the cause, and the
test comes back.
Recommended approach
Read the exception first. The W3C WebDriver specification defines a fixed set of errors,
and each one points at a specific cause. No such element means the locator matched nothing
in the current frame at that moment. Stale element reference means the page replaced the
element after you found it. Element click intercepted means something was drawn on top of
it. Session not created means the browser never started. The common errors page lists every
one with its likely cause and fixes; start there before reading any code.
Gather evidence at the moment of failure. Add a hook to your test framework that, on
failure, saves a screenshot alongside the Selenium log. The screenshot shows what the page
looked like; the log shows what Selenium sent and what the driver replied. With BiDi enabled
you can also collect the browser console and any JavaScript exceptions, which often explain a
page that looks right but does not respond.
Narrow the cause. Ask, in order:
Is it timing? Most intermittent failures are. Replace any sleep with an explicit wait for
the condition the next line depends on, and check that an implicit wait is not also set.
Is it the locator? Try it in the browser’s developer tools, and check whether the element
is inside a frame or a shadow root.
Is it the environment? A different browser version, a stale driver on the PATH, no
display on the build server, or a blocked download endpoint all produce failures that never
happen locally.
Is it the application? Then the test has found a bug, which is what it was for.
Reproduce before you fix. Run the test on its own, then in the full suite. A test that
only fails in the suite is sharing state with another test, usually through a reused browser
or a cookie left behind.
Common errors
The common errors page
covers each error in detail. The ones you will meet most often:
Running in CI: failures that only happen on the build server
Test practices: the discouraged patterns that cause flaky tests
13 - Migrating from Selenium 3
What changes when a Selenium 3 suite moves to Selenium 4, and where to find the step-by-step upgrade guide.
A suite written against Selenium 3 still compiles, or still installs, but sessions fail to
start, deprecation warnings fill the log, and the driver you used to download by hand no
longer matches the browser. The fix is to upgrade, and for the officially supported
languages the upgrade is usually painless.
Recommended approach
Follow the upgrade guide.
It walks through preparing the test code, updating the dependency for each binding, and the
deprecation messages you may see afterwards. The changes it covers fall into a few groups.
Capabilities. Selenium 4 removed the legacy JSON Wire Protocol and speaks only the W3C
WebDriver standard. Capabilities must be W3C compliant: the standard ones (browserName,
browserVersion, platformName, acceptInsecureCerts, pageLoadStrategy, proxy,
timeouts, unhandledPromptBehavior) are allowed as they are, and anything else, including
browser-specific and cloud-vendor options, needs a vendor prefix. Desired Capabilities are
gone; build the session from the browser’s Options class instead.
Finding elements in Java. The findElementBy* and findElementsBy* convenience methods
were removed. Use findElement(By.id(...)) and the other By locators.
Deprecations by binding. In Java, timeouts take a Duration rather than a number and a
unit, merge on capabilities returns a new object instead of mutating the caller, the legacy
Firefox driver option is deprecated, and BrowserType gives way to Browser. In C#,
AddAdditionalCapability is replaced by AddAdditionalOption. In Python, the driver’s
executable_path argument is deprecated in favour of a Service object, or no path at all.
Drivers. Once on a recent Selenium 4 release you no longer need to download drivers or
use a third-party driver manager: Selenium Manager resolves and installs the matching driver
automatically. Remove any manual driver management from the suite once the upgrade is done.
Older material on the web, and the legacy section of this documentation, describes Selenium 3
ways of working. It is kept for historical reference and should not be used as a basis for
new code.
Common errors
SessionNotCreatedException:
capabilities that are not W3C compliant, or a driver that does not match the browser.