Power Your Software Testing with AI Agents and Cloud
The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.
- TestMu AI (Formerly LambdaTest)
- /
- Blog
- /
- Selenium Page Load Strategy: Normal, Eager, and None
Selenium Page Load Strategy: Normal, Eager, and None
Selenium page load strategy sets when get() returns. Set normal, eager, or none in Java or Python page_load_strategy, tested in Chrome, Edge, Firefox, Safari.
Last Updated on:
Selenium's page load strategy decides when a navigation command such as get() hands control back to your test, and the answer is not the same in every browser. In a September 2026 run on the TestMu AI grid, get() under the none strategy left Chrome and Edge loading the requested page, while Firefox and Safari were still on the blank start page, which reports readyState complete.
This guide covers what normal, eager, and none wait for in Selenium WebDriver, how to set each one in Java, Python, and JavaScript, and what each returned into across four browsers, along with the navigation gaps in Firefox and Safari and the waits that close them.
Overview
Selenium's page load strategy is a session capability that decides when navigation commands such as get() hand control back to your test. It takes three values, normal (the default), eager, and none, and you set it once per session on the browser options, for example options.page_load_strategy = "eager" in Python.
- normal (default): The normal page load strategy returns after the load event, when readyState is complete. Use it when the next step reads fully loaded content right after navigating. Waits for images and iframes: yes.
- eager: The eager page load strategy returns once the document is interactive and DOMContentLoaded has fired, while images and iframes keep downloading. It saves at most the gap between DOMContentLoaded and load. Waits for images and iframes: no.
- none: The none page load strategy returns without waiting for readiness. In TestMu AI grid runs, Firefox and Safari were still showing the previous page when get() returned, so pair none with a staleness check and an element wait. Waits for DOM readiness: no.
What Is Page Load Strategy in Selenium?
Page load strategy is the pageLoadStrategy session capability, which tells WebDriver when a navigation command such as get() or navigate().to() is finished. The W3C WebDriver specification defines three values: normal, the default, waits for document.readyState to reach complete; eager waits for interactive; and none returns without waiting.
The value is sent once, when the session starts, so it applies to every navigation in that session. It is also older than Selenium 4: the Selenium 3.141.59 Java bindings already ship the PageLoadStrategy enum, and their ChromeOptions, FirefoxOptions, and EdgeOptions classes have a setPageLoadStrategy() method.
Selenium 4 moved that setter into AbstractDriverOptions, the base class every browser's options object extends, so SafariOptions gained it too, and Python's options objects gained a page_load_strategy property.
A shorter wait does not stop the page from loading. When a user reported that CSS and JavaScript files kept downloading under NONE and EAGER, Selenium maintainer diemol answered in SeleniumHQ/selenium issue 9315: "Having the command return earlier does not mean that the page will stop loading."
How document.readyState Maps to Each Strategy
MDN's document.readyState reference defines the three states the strategies wait for. One detail shapes eager: a document becomes interactive before its deferred and module scripts run, and DOMContentLoaded fires only after those scripts have executed.
| Strategy | Navigation returns when | readyState at return | Can still be loading after return |
|---|---|---|---|
| normal (default) | The load event has fired | complete | Only what the page fetches later, such as AJAX data |
| eager | The document is interactive; in every grid run that measured it, DOMContentLoaded had also fired | interactive, or complete if load finished first | Images, stylesheets, iframes, and async scripts |
| none | Right after the navigation starts | Any, including the previous document's | Everything |
How to Set Page Load Strategy in Java, Python, and JavaScript
Set the Selenium page load strategy on the browser options object before the session starts. The client sends it as the pageLoadStrategy capability, so a local driver and a remote grid read it the same way, and a session that never sets it runs as normal.
The C# and Ruby forms in this table come from the Selenium documentation's pageLoadStrategy section; the Java, Python, and JavaScript forms ran in the code in this guide.
| Language | Setter | Values |
|---|---|---|
| Java | options.setPageLoadStrategy(PageLoadStrategy.EAGER) | PageLoadStrategy.NORMAL, EAGER, NONE |
| Python | options.page_load_strategy = "eager" | "normal", "eager", "none" |
| JavaScript | options.setPageLoadStrategy('eager') | 'normal', 'eager', 'none' |
| C# | options.PageLoadStrategy = PageLoadStrategy.Eager | PageLoadStrategy.Normal, Eager, None |
| Ruby | options.page_load_strategy = :eager | :normal, :eager, :none |
| Any W3C client or grid | "pageLoadStrategy": "eager" in the capabilities | "normal", "eager", "none" |
In Java, the setter sits on every options class, so this is the whole change for a local Chrome session:
ChromeOptions options = new ChromeOptions();
options.setPageLoadStrategy(PageLoadStrategy.EAGER); // NORMAL applies when you skip this line
WebDriver driver = new ChromeDriver(options);To confirm what the session accepted, read the capability back with driver.getCapabilities().getCapability("pageLoadStrategy") in Java or driver.capabilities["pageLoadStrategy"] in Python.
In JavaScript, chrome.Options inherits setPageLoadStrategy() from the Capabilities class. This script ran on the TestMu AI grid with Selenium 4.49.0:
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
(async () => {
const options = new chrome.Options()
.setPageLoadStrategy('eager') // 'normal' (default), 'eager' or 'none'
.setBrowserVersion('latest')
.setPlatform('Windows 11');
options.set('LT:Options', {
username: process.env.LT_USERNAME,
accessKey: process.env.LT_ACCESS_KEY,
build: 'Selenium Page Load Strategy',
name: 'JavaScript eager',
});
const driver = await new Builder()
.usingServer('https://hub.lambdatest.com/wd/hub')
.forBrowser('chrome')
.setChromeOptions(options)
.build();
try {
console.log('pageLoadStrategy:', (await driver.getCapabilities()).get('pageLoadStrategy'));
await driver.get('https://ecommerce-playground.lambdatest.io/');
console.log('readyState when get() returned:', await driver.executeScript('return document.readyState'));
await driver.executeScript('lambda-status=passed');
} finally {
await driver.quit();
}
})();Output from two runs of the same script:
pageLoadStrategy: eager
readyState when get() returned: interactive
pageLoadStrategy: eager
readyState when get() returned: completeThe second run returned into complete because that page's load event had already fired by the time the script read readyState. Eager guarantees at least interactive; when load finishes first, you get complete.
Set page_load_strategy in Selenium Python
Python exposes the strategy as a string property on the options object: "normal", "eager", or "none". The script below sets eager on Chrome, runs on the TestMu AI grid, and includes a navigate() helper for eager and none navigations that the waiting section explains.
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
HOME = "https://ecommerce-playground.lambdatest.io/"
SPECIAL = HOME + "index.php?route=product/special"
def start(strategy):
options = webdriver.ChromeOptions()
options.page_load_strategy = strategy # "normal" (default), "eager" or "none"
options.browser_version = "latest"
options.platform_name = "Windows 11"
options.set_capability("LT:Options", {
"username": os.environ["LT_USERNAME"],
"accessKey": os.environ["LT_ACCESS_KEY"],
"build": "Selenium Page Load Strategy",
"name": f"Python {strategy}",
})
return webdriver.Remote(command_executor="https://hub.lambdatest.com/wd/hub", options=options)
def navigate(driver, url, ready_locator, timeout=30):
"""get() that is safe under eager and none: the old page is gone, then the element you need."""
old_html = driver.find_element(By.TAG_NAME, "html")
driver.get(url)
wait = WebDriverWait(driver, timeout)
wait.until(EC.staleness_of(old_html))
return wait.until(EC.visibility_of_element_located(ready_locator))
driver = start(os.environ.get("STRATEGY", "eager"))
try:
driver.get(HOME)
print("page_load_strategy:", driver.capabilities["pageLoadStrategy"])
print("readyState when get() returned:", driver.execute_script("return document.readyState"))
heading = navigate(driver, SPECIAL, (By.CSS_SELECTOR, "body.product-special h1"))
print("next page ready:", heading.text)
driver.execute_script("lambda-status=passed")
finally:
driver.quit()Run it with LT_USERNAME and LT_ACCESS_KEY set in the environment. Output from the grid run:
page_load_strategy: eager
readyState when get() returned: interactive
next page ready: Special OffersWith STRATEGY=none, the same script printed loading after the first get(), and navigate() still returned the Special Offers heading.
Page Load Strategy Measured in Four Browsers
The strategy table states intent. To see what a test gets back under each Selenium page load strategy, the Java project below opened one session per browser and strategy on TestMu AI's Automation Cloud, loaded the TestMu AI ecommerce playground home page, and read the live document from inside the browser the moment get() returned.
TestMu AI's Automation Cloud runs existing Selenium scripts across 3,000+ browser/OS combinations without local drivers, so Chrome and Edge on Windows 11 and Safari on macOS Sequoia run from the same test class by switching the options object and platform name.
Project Setup
You need JDK 17 or newer and Maven. Create a project with the standard src/test/java layout and this pom.xml, which pins Selenium 4.49.0, TestNG 7.12.0, and Surefire 3.5.6 and caps parallel data provider threads at four:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>page-load-strategy</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.49.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.12.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.6</version>
<configuration>
<properties>
<property>
<name>dataproviderthreadcount</name>
<value>4</value>
</property>
</properties>
</configuration>
</plugin>
</plugins>
</build>
</project>Export your username and access key as LT_USERNAME and LT_ACCESS_KEY. The code reads both from the environment and sends them inside LT:Options, which keeps them out of the hub URL; the TestNG guide for the TestMu AI Selenium grid covers the account side.
GridDriver.java starts sessions and reads page state:
package demo;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.AbstractDriverOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariOptions;
public final class GridDriver {
private static final String HUB = "https://hub.lambdatest.com/wd/hub";
private GridDriver() {}
public static RemoteWebDriver start(String browser, PageLoadStrategy strategy, String testName) throws Exception {
AbstractDriverOptions<?> options = switch (browser) {
case "Chrome" -> new ChromeOptions();
case "Edge" -> new EdgeOptions();
case "Firefox" -> new FirefoxOptions();
case "Safari" -> new SafariOptions();
default -> throw new IllegalArgumentException("Unknown browser: " + browser);
};
options.setPageLoadStrategy(strategy); // NORMAL applies when this line is omitted
options.setBrowserVersion("latest");
options.setPlatformName(browser.equals("Safari") ? "macOS Sequoia" : "Windows 11");
Map<String, Object> ltOptions = new HashMap<>();
ltOptions.put("username", System.getenv("LT_USERNAME"));
ltOptions.put("accessKey", System.getenv("LT_ACCESS_KEY"));
ltOptions.put("build", "Selenium Page Load Strategy");
ltOptions.put("name", testName);
options.setCapability("LT:Options", ltOptions);
return new RemoteWebDriver(URI.create(HUB).toURL(), options);
}
/** Reads the document the browser is really showing, from inside the page. */
@SuppressWarnings("unchecked")
public static Map<String, Object> pageState(WebDriver driver) {
Object state = ((JavascriptExecutor) driver).executeScript(
"const nav = performance.getEntriesByType('navigation')[0];"
+ "return { url: document.URL, readyState: document.readyState,"
+ " domContentLoaded: nav ? Math.round(nav.domContentLoadedEventEnd) : 0,"
+ " load: nav ? Math.round(nav.loadEventEnd) : 0 };");
// A script that runs while one document replaces another can come back empty
return state != null ? (Map<String, Object>) state
: Map.of("url", "", "readyState", "unknown", "domContentLoaded", 0L, "load", 0L);
}
}- start() - picks ChromeOptions, EdgeOptions, FirefoxOptions, or SafariOptions, sets the strategy through the shared AbstractDriverOptions setter, and opens a RemoteWebDriver session. Other LT:Options keys, such as video or network logs, come from the TestMu AI Capabilities Generator.
- pageState() - runs a script inside the page and returns document.URL, document.readyState, and the Navigation Timing values domContentLoadedEventEnd and loadEventEnd. It reads the URL from the document itself because WebDriver's view of the page can disagree with the live document, as the results show.
The Measurement Test
PageLoadStrategyTest.java crosses four browsers with three strategies in a parallel TestNG data provider, times get(), and snapshots the page the moment the call returns:
package demo;
import java.time.Duration;
import java.util.Map;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class PageLoadStrategyTest {
static final String HOME = "https://ecommerce-playground.lambdatest.io/";
@DataProvider(parallel = true)
public Object[][] browsersAndStrategies() {
String[] browsers = {"Chrome", "Edge", "Firefox", "Safari"};
PageLoadStrategy[] strategies = {PageLoadStrategy.NORMAL, PageLoadStrategy.EAGER, PageLoadStrategy.NONE};
Object[][] rows = new Object[browsers.length * strategies.length][];
int i = 0;
for (String browser : browsers) {
for (PageLoadStrategy strategy : strategies) {
rows[i++] = new Object[] {browser, strategy};
}
}
return rows;
}
@Test(dataProvider = "browsersAndStrategies")
public void whatGetReturnsInto(String browser, PageLoadStrategy strategy) throws Exception {
RemoteWebDriver driver = GridDriver.start(browser, strategy, browser + " " + strategy);
String status = "failed";
try {
long start = System.nanoTime();
driver.get(HOME);
long getMs = (System.nanoTime() - start) / 1_000_000;
Map<String, Object> atReturn = GridDriver.pageState(driver);
// Wait on the live document: the right URL, readyState complete, load event finished
new WebDriverWait(driver, Duration.ofSeconds(60)).until(d -> {
Map<String, Object> page = GridDriver.pageState(d);
return page.get("url").toString().startsWith(HOME)
&& "complete".equals(page.get("readyState"))
&& ((Number) page.get("load")).longValue() > 0;
});
Map<String, Object> loaded = GridDriver.pageState(driver);
String version = driver.getCapabilities().getBrowserVersion().split("[.]")[0];
boolean onTarget = atReturn.get("url").toString().startsWith(HOME);
boolean dclFired = onTarget && ((Number) atReturn.get("domContentLoaded")).longValue() > 0;
System.out.printf("%-7s %-3s %-6s | get() %5d ms | returned into %-11s on %-11s | DOMContentLoaded fired: %-3s"
+ " | page finished: DOMContentLoaded %5s ms, load %5s ms%n",
browser, version, strategy, getMs, atReturn.get("readyState"),
onTarget ? "target page" : atReturn.get("url"), dclFired ? "yes" : "no",
loaded.get("domContentLoaded"), loaded.get("load"));
status = "passed";
} finally {
driver.executeScript("lambda-status=" + status);
driver.quit();
}
}
}- browsersAndStrategies() - returns the 12 browser and strategy pairs; parallel = true runs them concurrently, up to the four threads the pom allows.
- whatGetReturnsInto() - times get() with System.nanoTime(), captures the page state at once, then waits until the target document is complete and its load event has finished before printing both states.
- lambda-status - marks each session passed or failed on the TestMu AI dashboard, so a failing combination is easy to open with its video and logs.
Run the class with Maven:
mvn test -Dtest=PageLoadStrategyTestResults on the TestMu AI Grid
Console output from the run on September 30, 2026, sorted by browser (one session per line; timings change from run to run):
Chrome 154 normal | get() 3299 ms | returned into complete on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 2920 ms, load 3211 ms
Chrome 154 eager | get() 2957 ms | returned into interactive on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 2681 ms, load 3013 ms
Chrome 154 none | get() 59 ms | returned into loading on target page | DOMContentLoaded fired: no | page finished: DOMContentLoaded 2575 ms, load 3080 ms
Edge 154 normal | get() 6122 ms | returned into complete on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 2738 ms, load 6027 ms
Edge 154 eager | get() 3237 ms | returned into complete on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 3007 ms, load 3012 ms
Edge 154 none | get() 71 ms | returned into loading on target page | DOMContentLoaded fired: no | page finished: DOMContentLoaded 2779 ms, load 2877 ms
Firefox 156 normal | get() 5713 ms | returned into complete on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 3678 ms, load 5255 ms
Firefox 156 eager | get() 4211 ms | returned into interactive on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 3569 ms, load 5148 ms
Firefox 156 none | get() 600 ms | returned into complete on about:blank | DOMContentLoaded fired: no | page finished: DOMContentLoaded 3455 ms, load 4789 ms
Safari 18 normal | get() 5308 ms | returned into complete on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 2236 ms, load 3284 ms
Safari 18 eager | get() 2962 ms | returned into interactive on target page | DOMContentLoaded fired: yes | page finished: DOMContentLoaded 2175 ms, load 3235 ms
Safari 18 none | get() 51 ms | returned into complete on about:blank | DOMContentLoaded fired: no | page finished: DOMContentLoaded 2225 ms, load 3299 ms| Browser | normal returned into | eager returned into | none returned into |
|---|---|---|---|
| Chrome 154 | complete on target page (3299 ms) | interactive on target page (2957 ms) | loading on target page (59 ms) |
| Edge 154 | complete on target page (6122 ms) | complete on target page (3237 ms) | loading on target page (71 ms) |
| Firefox 156 | complete on target page (5713 ms) | interactive on target page (4211 ms) | complete on about:blank (600 ms) |
| Safari 18 | complete on target page (5308 ms) | interactive on target page (2962 ms) | complete on about:blank (51 ms) |
- normal - returned into complete in all four browsers, after 3.3 s in Chrome, 6.1 s in Edge, 5.7 s in Firefox, and 5.3 s in Safari.
- eager - returned with DOMContentLoaded already fired in all four browsers: interactive in Chrome, Firefox, and Safari, and complete in Edge, where that page load fired its load event 5 ms after DOMContentLoaded.
- none - Chrome (59 ms) and Edge (71 ms) returned already on the target URL in the loading state; Safari (51 ms) and Firefox (600 ms) returned while about:blank was still the live document and reported readyState complete.
Single-run get() times are not a benchmark, because network conditions differ from session to session. The in-page gap between DOMContentLoaded and load says more: in the Edge normal session, DOMContentLoaded fired at 2.7 s and load at 6.0 s, so get() waited 6.1 s, while in the Edge eager session the two events were 5 ms apart and eager saved nothing.
Note: Run the same matrix against your own pages on TestMu AI. The networkThrottling capability's presets run from GPRS and Regular 2G up to Regular 4G, so you can see how much of a slow load eager would skip. See the network throttling presets or start testing for free.
Page Load Strategy vs Page Load Timeout
Page load strategy picks which readiness state a navigation waits for; the page load timeout caps how long that wait may last.
The W3C WebDriver Recommendation gives every session a page load timeout of 300,000 milliseconds, or five minutes, unless the session sets another value.
A navigation that runs past that limit fails with a timeout error, which Selenium raises as TimeoutException. The limit bounds only the strategies that wait: under none, the specification returns success before any readiness check, so a navigation cannot time out.
The oneSecondPageLoadTimeout() test sets a one-second limit on Chrome and loads the same home page with each strategy:
Chrome normal pageLoadTimeout 1 s: TimeoutException after 1224 ms
Chrome eager pageLoadTimeout 1 s: TimeoutException after 1186 ms
Chrome none pageLoadTimeout 1 s: get() returned after 73 msNormal and eager both threw TimeoutException just after the one-second limit, because DOMContentLoaded on this page took longer than a second; none returned in 73 ms. When slow pages trip the timeout under normal, raise the limit, and treat eager as a fix only if DOMContentLoaded itself fits inside it.
// Java: raise or lower the cap for every navigation in the session
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));# Python: the value is in seconds
driver.set_page_load_timeout(30)For handling patterns around TimeoutException and its relatives, see these common Selenium exceptions.
How to Wait After an eager or none Navigation
Under eager and none the strategy no longer promises a ready page, so the test has to define ready. Two waits covered every browser in the grid runs: first prove the previous document is gone, then wait for the element the next step uses.
WebElement oldHtml = driver.findElement(By.tagName("html"));
driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=product/special");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.stalenessOf(oldHtml));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body.product-special h1")));The navigate() helper in the Python script is the same pair of waits. Avoid these shortcuts after an eager or none navigation:
- A readyState check - under none, Firefox and Safari reported complete for the blank start page or the previous page.
- A getCurrentUrl() check - Safari reported the destination URL while the previous page was still the live document.
- Thread.sleep() - waits the full duration when the page is fast and still fails when the page is slower than the sleep.
On TestMu AI, the SmartWait capability runs actionability checks before each action, holding it until the element is visible, enabled, and stable, within a window you set between 5 and 120 seconds. It removes per-element waits after eager, but it checks the element an action targets, not which document that element belongs to, so keep the staleness check wherever the previous page can still be live.
For content that keeps arriving after readyState reaches complete, such as AJAX panels, the Selenium wait for page to load guide covers element, staleness, and AJAX waits in Python, and waits in Selenium compares implicit, explicit, and fluent waits.
Which Page Load Strategy Should You Use?
Keep normal unless you have measured a real gap between DOMContentLoaded and load on the pages your tests visit; then move that suite to eager and add element waits. Reserve none for tests that decide readiness themselves, like the measurement test above.
| Strategy | Choose it when | Pair it with |
|---|---|---|
| normal | Tests read page content right after navigating, or pages finish loading soon after DOMContentLoaded | Element waits for content fetched after the load event |
| eager | Images, iframes, ads, or async scripts keep loading well after DOMContentLoaded | A wait for the element the next step uses |
| none | The test measures loading or waits on its own signals | A staleness check on the old html element, then an element wait |
The gap is easy to measure: pageState() already returns domContentLoaded and load from the Navigation Timing API, and load minus domContentLoaded is the most eager can save on that load. Across the 12 loads above it ranged from 5 ms to 3.3 s on the same page, so sample several loads, ideally under the network conditions your users have, before switching. For more ways to time a page from a test, see how to measure page load time with Selenium.
Selenium Skill for AI Coding Agents
When an AI coding assistant writes the test, it needs the same wait rules. TestMu AI's open-source Selenium Skill gives assistants such as Claude Code, Copilot, and Cursor the patterns this guide's code follows: explicit WebDriverWait instead of sleeps, credentials from LT_USERNAME and LT_ACCESS_KEY, driver.quit() in teardown, and lambda-status reporting.
npx agentskillsforall add https://github.com/LambdaTest/agent-skills.git --skill selenium-skillThe same repository holds skills for Playwright, Appium, and other frameworks; the agent skills overview explains how skills work and how to install them.
Install the Selenium Skill so Claude Code, Copilot, and Cursor pair every eager or none navigation with explicit waits.
Conclusion
Start with the slowest page in your suite: log pageState() after get() for a few loads and compare load with domContentLoaded before you change the Selenium page load strategy. Then run the suite with the strategy you picked across Chrome, Edge, Firefox, and Safari using Selenium automation on TestMu AI, with the Selenium 4 capabilities reference open for the options format.
Author
Vipul Gupta is a Sr. Lead SDET at Zupee with over 9 years of experience in functional and automation testing. He has built 10+ automation projects from scratch covering web, API, and mobile applications. Vipul is skilled in Selenium, Appium, Rest Assured, Playwright, Java, Python, Pytest, BDD, TDD, Maven, Jenkins, TestNG, and JUnit. He has successfully led end-to-end QA efforts, including setting up teams from scratch and managing a 15-member QA team to ensure manual and automation testing run in parallel from day one. Vipul graduated in B.Tech CSE from CGC College of Engineering and is followed by 3,000+ QA and SDET professionals on LinkedIn, reflecting his strong influence in the testing community.
Reviewer
Navin Chandra is a Member of Technical Staff at TestMu AI (formerly LambdaTest), building the open-source automation that powers its Selenium and Appium cloud grid. A committer to both Selenium and Appium, he implemented WebDriver BiDi support in Selenium for real-time browser events and bidirectional control and is developing Apple's iOS RemoteXPC protocol in Appium to enable low-level wireless communication with iOS system services. He contributes to Selenium across multiple language bindings as a member of the Selenium GitHub organization. He has served as a Google Summer of Code mentee and mentor at openSUSE and an LFX mentee at CNCF's KubeArmor, and is a SUSE Certified Deployment Specialist. Navin holds a B.Tech in Computer Science.
Page Load Strategy FAQs
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance
- Advanced access controls
- Advanced data retention rules
- Advanced Local Testing
- Premium Support options
- Early access to beta features
- Private Slack Channel
- Unlimited Manual Accessibility DevTools Tests




