Authentication and sessions
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 context
driver.manage().addCookie(new Cookie("key", "value"));/examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java
// 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.
package dev.selenium.interactions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Set;
public class CookiesTest {
WebDriver driver = new ChromeDriver();
@AfterEach
final void closeBrowser() {
if (driver != null) {
driver.quit();
}
}
@Test
public void addCookie() {
driver.get("https://www.selenium.dev/selenium/web/blank.html");
// Add cookie into current browser context
driver.manage().addCookie(new Cookie("key", "value"));
}
@Test
public void getNamedCookie() {
driver.get("https://www.selenium.dev/selenium/web/blank.html");
// Add cookie into current browser context
driver.manage().addCookie(new Cookie("foo", "bar"));
// Get cookie details with named cookie 'foo'
Cookie cookie = driver.manage().getCookieNamed("foo");
Assertions.assertEquals(cookie.getValue(), "bar");
}
@Test
public void getAllCookies() {
driver.get("https://www.selenium.dev/selenium/web/blank.html");
// Add cookies into current browser context
driver.manage().addCookie(new Cookie("test1", "cookie1"));
driver.manage().addCookie(new Cookie("test2", "cookie2"));
// Get cookies
Set<Cookie> cookies = driver.manage().getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("test1")) {
Assertions.assertEquals(cookie.getValue(), "cookie1");
}
if (cookie.getName().equals("test2")) {
Assertions.assertEquals(cookie.getValue(), "cookie2");
}
}
}
@Test
public void deleteCookieNamed() {
driver.get("https://www.selenium.dev/selenium/web/blank.html");
driver.manage().addCookie(new Cookie("test1", "cookie1"));
// delete cookie named
driver.manage().deleteCookieNamed("test1");
}
@Test
public void deleteCookieObject() {
driver.get("https://www.selenium.dev/selenium/web/blank.html");
Cookie cookie = new Cookie("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);
}
@Test
public void deleteAllCookies() {
driver.get("https://www.selenium.dev/selenium/web/blank.html");
// Add cookies into current browser context
driver.manage().addCookie(new Cookie("test1", "cookie1"));
driver.manage().addCookie(new Cookie("test2", "cookie2"));
// Delete All cookies
driver.manage().deleteAllCookies();
}
@Test
public void sameSiteCookie() {
driver.get("http://www.example.com");
Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
Cookie cookie1 = new Cookie.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 context
driver.add_cookie({"name": "key", "value": "value"})/examples/python/tests/interactions/test_cookies.py
from selenium import webdriver
def test_add_cookie():
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "key", "value": "value"})
def test_get_named_cookie():
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "foo", "value": "bar"})
# Get cookie details with named cookie 'foo'
print(driver.get_cookie("foo"))
def test_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 cookies
print(driver.get_cookies())
def test_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")
def test_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 cookies
driver.delete_all_cookies()
def test_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 context
driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));/examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs
// 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.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocs.Interactions{
[TestClass]
public class CookiesTest{
WebDriver driver = new ChromeDriver();
[TestMethod]
public void addCookie(){
driver.Url="https://www.selenium.dev/selenium/web/blank.html";
// Add cookie into current browser context
driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
driver.Quit();
}
[TestMethod]
public void getNamedCookie(){
driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
// Add cookie into current browser context
driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
// Get cookie details with named cookie 'foo'
Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
Assert.AreEqual(cookie.Value, "bar");
driver.Quit();
}
[TestMethod]
public void getAllCookies(){
driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
// Add cookies into current browser context
driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
// Get cookies
var cookies = driver.Manage().Cookies.AllCookies;
foreach (var cookie in cookies){
if (cookie.Name.Equals("test1")){
Assert.AreEqual("cookie1", cookie.Value);
}
if (cookie.Name.Equals("test2")){
Assert.AreEqual("cookie2", cookie.Value);
}
}
driver.Quit();
}
[TestMethod]
public void deleteCookieNamed(){
driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
// delete cookie named
driver.Manage().Cookies.DeleteCookieNamed("test1");
driver.Quit();
}
[TestMethod]
public void deleteCookieObject(){
driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
Cookie cookie = new Cookie("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]
public void deleteAllCookies(){
driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
// Add cookies into current browser context
driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
// Delete All cookies
driver.Manage().Cookies.DeleteAllCookies();
driver.Quit();
}
}
} driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
# Add cookie into current browser context
driver.manage.add_cookie(name: 'key', value: 'value')/examples/ruby/spec/interactions/cookies_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Cookies' do
let(:driver) { start_session }
it 'adds a cookie' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
# Add cookie into current browser context
driver.manage.add_cookie(name: 'key', value: 'value')
# Verify cookie was added
expect(driver.manage.cookie_named('key')[:value]).to eq('value')
end
it 'gets a named cookie' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
# Add cookie into current browser context
driver.manage.add_cookie(name: 'foo', value: 'bar')
# Get cookie details with named cookie 'foo'
cookie = driver.manage.cookie_named('foo')
expect(cookie[:value]).to eq('bar')
end
it 'gets all cookies' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
# Add cookies into current browser context
driver.manage.add_cookie(name: 'test1', value: 'cookie1')
driver.manage.add_cookie(name: 'test2', value: 'cookie2')
# Get cookies
cookies = driver.manage.all_cookies
# Verify both cookies exist with correct values
test1_cookie = cookies.find { |c| c[:name] == 'test1' }
test2_cookie = cookies.find { |c| c[:name] == 'test2' }
expect(test1_cookie[:value]).to eq('cookie1')
expect(test2_cookie[:value]).to eq('cookie2')
end
it 'deletes a cookie by name' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
driver.manage.add_cookie(name: 'test1', value: 'cookie1')
# Delete cookie named
driver.manage.delete_cookie('test1')
# Verify cookie is deleted
expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
end
it 'deletes all cookies' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
# Add cookies into current browser context
driver.manage.add_cookie(name: 'test1', value: 'cookie1')
driver.manage.add_cookie(name: 'test2', value: 'cookie2')
# Delete All cookies
driver.manage.delete_all_cookies
# Verify all cookies are deleted
expect(driver.manage.all_cookies.size).to eq(0)
end
end
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// set a cookie on the current domain
await driver.manage().addCookie({ name: 'key', value: 'value' });/examples/javascript/test/interactions/cookies.spec.js
const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')
describe('Cookies', function() {
let driver;
before(async function() {
driver = new Builder()
.forBrowser(Browser.CHROME)
.build();
});
after(async () => await driver.quit());
it('Create a cookie', async function() {
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// set a cookie on the current domain
await driver.manage().addCookie({ name: 'key', value: 'value' });
});
it('Create cookies with sameSite', async function() {
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
});
it('Read cookie', async function() {
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// set a cookie on the current domain
await driver.manage().addCookie({ name: 'foo', value: 'bar' });
// Get cookie details with named cookie 'foo'
await driver.manage().getCookie('foo').then(function(cookie) {
assert.equal(cookie.value, 'bar');
});
});
it('Read all cookies', async function() {
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// Add few cookies
await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
// Get all Available cookies
await driver.manage().getCookies().then(function(cookies) {
assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
});
});
it('Delete a cookie', async function() {
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// Add few cookies
await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
// Delete a cookie with name 'test1'
await driver.manage().deleteCookie('test1');
// Get all Available cookies
await driver.manage().getCookies().then(function(cookies) {
assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
});
});
it('Delete all cookies', async function() {
await driver.get('https://www.selenium.dev/selenium/web/blank.html');
// Add few cookies
await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
// Delete all cookies
await driver.manage().deleteAllCookies();
});
});
Answer a basic authentication challenge with BiDi:
network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
network.onAuthRequired(
responseDetails ->
network.continueWithAuth(
responseDetails.getRequest().getRequestId(),
new UsernameAndPassword("admin", "admin")));/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java
package dev.selenium.bidirectional.webdriver_bidi;
import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
class NetworkCommandsTest extends BaseTest {
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
@Test
void canAddIntercept() {
try (Network network = new Network(driver)) {
String intercept =
network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
Assertions.assertNotNull(intercept);
}
}
@Test
void canRemoveIntercept() {
try (Network network = new Network(driver)) {
String intercept =
network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
Assertions.assertNotNull(intercept);
network.removeIntercept(intercept);
}
}
@Test
void canContinueWithAuthCredentials() {
try (Network network = new Network(driver)) {
network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
network.onAuthRequired(
responseDetails ->
network.continueWithAuth(
responseDetails.getRequest().getRequestId(),
new UsernameAndPassword("admin", "admin")));
driver.get("https://the-internet.herokuapp.com/basic_auth");
String successMessage = "Congratulations! You must have the proper credentials.";
WebElement elementMessage = driver.findElement(By.tagName("p"));
Assertions.assertEquals(successMessage, elementMessage.getText());
}
}
@Test
void canContinueWithoutAuthCredentials() {
try (Network network = new Network(driver)) {
network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
network.onAuthRequired(
responseDetails ->
// Does not handle the alert
network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
driver.get("https://the-internet.herokuapp.com/basic_auth");
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
alert.dismiss();
Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
}
}
@Test
void canCancelAuth() {
try (Network network = new Network(driver)) {
network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
network.onAuthRequired(
responseDetails ->
// Does not handle the alert
network.cancelAuth(responseDetails.getRequest().getRequestId()));
driver.get("https://the-internet.herokuapp.com/basic_auth");
Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
}
}
@Test
void canFailRequest() {
try (Network network = new Network(driver)) {
network.addIntercept(new AddInterceptParameters(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"));
}
}
}
/examples/python/tests/bidi/test_network_commands.py
# 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.
import pytest
from selenium.common.exceptions import WebDriverException
@pytest.mark.driver_type("bidi")
def test_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()
assert intercept is not None
driver.network._remove_intercept(intercept["intercept"])
@pytest.mark.driver_type("bidi")
def test_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"])
assert driver.network.intercepts == []
@pytest.mark.driver_type("bidi")
def test_fail_request(driver):
from selenium.webdriver.common.bidi.browsing_context import ReadinessState
from selenium.webdriver.common.bidi.network import Request
def block_request(request: Request):
request.fail()
driver.network.add_request_handler(["**/blank.html"], block_request)
try:
with pytest.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")
def test_add_and_remove_request_handler(driver):
from selenium.webdriver.common.bidi.network import Request
requests = []
def callback(request: Request):
requests.append(request)
callback_id = driver.network.add_request_handler("before_request", callback)
assert callback_id is not None
driver.network.remove_request_handler("before_request", callback_id)
driver.get("https://www.selenium.dev/selenium/web/blank.html")
assert not requests
await network.authRequired(async (event) => {
await network.continueWithAuth(event.request.request, 'admin','admin')
})/examples/javascript/test/bidirectional/network_commands.spec.js
const assert = require("assert")
const firefox = 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 () {
let driver
let network
beforeEach(async function () {
driver = new Builder()
.forBrowser('firefox')
.setFirefoxOptions(new firefox.Options().enableBidi())
.build()
network = await Network(driver)
})
afterEach(async function () {
await network.close()
await driver.quit()
})
it('can add intercept', async function () {
const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
assert.notEqual(intercept, null)
})
it('can remove intercept', async function () {
const network = await Network(driver)
const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
assert.notEqual(intercept, null)
await network.removeIntercept(intercept)
})
it('can continue with auth credentials ', async function () {
await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))
await network.authRequired(async (event) => {
await network.continueWithAuth(event.request.request, 'admin','admin')
})
await driver.get('https://the-internet.herokuapp.com/basic_auth')
const successMessage = 'Congratulations! You must have the proper credentials.'
let elementMessage = await driver.findElement(By.tagName('p')).getText()
assert.equal(elementMessage, successMessage)
})
it('can continue without auth credentials ', async function () {
await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))
await network.authRequired(async (event) => {
await network.continueWithAuthNoCredentials(event.request.request)
})
await driver.get('https://the-internet.herokuapp.com/basic_auth')
const alert = await driver.wait(until.alertIsPresent())
await alert.dismiss()
let source = await driver.getPageSource()
assert.equal(source.includes('Not authorized'), true)
})
it('can cancel auth ', async function () {
await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))
await network.authRequired(async (event) => {
await network.cancelAuth(event.request.request)
})
await driver.get('https://the-internet.herokuapp.com/basic_auth')
let source = await driver.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
Securecookie on anhttp://page. - UnhandledAlertException: a basic authentication dialog is open and blocking the session. Handle it with BiDi before navigating.
Reference
- Working with cookies
- BiDi network: intercepts and the
authRequiredphase - Virtual authenticator: testing WebAuthn and passkeys
- Two-factor authentication and third-party logins: what not to automate
- Avoid sharing state and fresh browser per test



