Introduction
This comprehensive reference guide covers every essential Selenium WebDriver keyword, method, class, and concept you need to master for professional test automation. All examples use Selenium 4.x (latest version) with Java bindings.
- Use the Quick Navigation Index to jump to specific keywords
- Each entry includes syntax, practical examples, and best practices
- Code examples are production-ready and follow industry standards
- Related concepts are cross-referenced for deeper learning
Quick Navigation Index
E - I
Core WebDriver Methods
get()
NavigationPurpose: Loads a web page in the current browser window and waits for the page to load completely.
void get(String url)
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
WebDriver driver = new ChromeDriver();
// Navigate to URL
driver.get("https://www.example.com");
// Navigate to local file
driver.get("file:///C:/test/page.html");
// Navigate with dynamic URL
String baseUrl = "https://www.example.com";
String endpoint = "/login";
driver.get(baseUrl + endpoint);- Blocks until page load event fires (DOM ready)
- Does NOT wait for AJAX/JavaScript execution
- Accepts both HTTP/HTTPS and file:// protocols
- Replaces current page (not a new tab)
- Forgetting protocol:
"example.com"❌ →"https://example.com"✅ - Not handling page load timeouts (use
pageLoadTimeout())
Related: navigate().to(),navigate().back()
findElement()
Element LocationPurpose: Locates and returns the first matching WebElement on the current page. Throws NoSuchElementException if element not found.
WebElement findElement(By locator)
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
// 1. ID (Most Reliable)
WebElement element = driver.findElement(By.id("username"));
// 2. Name
WebElement element = driver.findElement(By.name("email"));
// 3. Class Name
WebElement element = driver.findElement(By.className("btn-primary"));
// 4. Tag Name
WebElement element = driver.findElement(By.tagName("input"));
// 5. Link Text (Exact match)
WebElement element = driver.findElement(By.linkText("Sign Up"));
// 6. Partial Link Text
WebElement element = driver.findElement(By.partialLinkText("Sign"));
// 7. CSS Selector (Fast & Flexible)
WebElement element = driver.findElement(By.cssSelector("#username"));
WebElement element = driver.findElement(By.cssSelector(".form-control"));
WebElement element = driver.findElement(By.cssSelector("input[type='email']"));
// 8. XPath (Most Powerful)
WebElement element = driver.findElement(By.xpath("//input[@id='username']"));
WebElement element = driver.findElement(By.xpath("//button[text()='Submit']"));
// Chain operations
driver.findElement(By.id("username"))
.sendKeys("testuser")
.submit();- Priority Order: ID → Name → CSS → XPath
- Use CSS Selector for performance (2-3x faster than XPath)
- Avoid absolute XPath (brittle)
- Store locators as constants for maintainability
try {
WebElement element = driver.findElement(By.id("username"));
element.sendKeys("admin");
} catch(NoSuchElementException e) {
System.out.println("Element not found: " + e.getMessage());
// Add wait or verify page loaded correctly
}
// Better: Use Explicit Wait
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(
ExpectedConditions.presenceOfElementLocated(By.id("username"))
);Related: findElements(),ExpectedConditions
findElements()
Element LocationPurpose: Returns a List of all matching WebElements. Returns empty list if no elements found (does NOT throw exception).
List<WebElement> findElements(By locator)
import java.util.List;
// Get all links on page
List<WebElement> links = driver.findElements(By.tagName("a"));
System.out.println("Total links: " + links.size());
// Iterate through elements
for(WebElement link : links) {
System.out.println(link.getText() + " - " + link.getAttribute("href"));
}
// Get all products
List<WebElement> products = driver.findElements(By.className("product-card"));
for(WebElement product : products) {
String name = product.findElement(By.className("product-name")).getText();
String price = product.findElement(By.className("product-price")).getText();
System.out.println(name + ": " + price);
}
// Check if element exists (safe way)
List<WebElement> errorMessages = driver.findElements(By.id("error"));
if(errorMessages.size() > 0) {
System.out.println("Error displayed");
} else {
System.out.println("No errors");
}
// Get count of elements
int checkboxCount = driver.findElements(By.cssSelector("input[type='checkbox']")).size();
System.out.println("Total checkboxes: " + checkboxCount);findElement()
- Returns single WebElement
- Throws NoSuchElementException
- Use when expecting ONE element
- Faster (stops at first match)
findElements()
- Returns List<WebElement>
- Returns empty list (no exception)
- Use when expecting MULTIPLE elements
- Safer for existence checks
Related: findElement()
click()
User InteractionPurpose: Simulates a mouse click on a web element (button, link, checkbox, etc.).
void click()
// Click button
driver.findElement(By.id("submit-btn")).click();
// Click link
driver.findElement(By.linkText("Learn More")).click();
// Click checkbox
WebElement checkbox = driver.findElement(By.id("terms"));
if(!checkbox.isSelected()) {
checkbox.click(); // Check it
}
// Click radio button
driver.findElement(By.id("payment-credit-card")).click();
// Click element using Actions (for stubborn elements)
WebElement element = driver.findElement(By.id("btn"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().perform();
// Click using JavaScript (last resort)
WebElement element = driver.findElement(By.id("btn"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);public void clickElement(By locator) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
try {
// Wait for element to be clickable
WebElement element = wait.until(
ExpectedConditions.elementToBeClickable(locator)
);
element.click();
} catch(ElementClickInterceptedException e) {
// Element is covered by another element
System.out.println("Click intercepted, trying JS click");
WebElement element = driver.findElement(locator);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);
} catch(StaleElementReferenceException e) {
// Element was removed from DOM
System.out.println("Stale element, re-locating and clicking");
driver.findElement(locator).click();
}
}- Element must be visible (
isDisplayed()) - Element must be enabled (
isEnabled()) - Element must be in viewport (scroll if needed)
- No overlay covering the element
Related: Actions Class,JavascriptExecutor
sendKeys()
User InteractionPurpose: Simulates typing text into an input field or textarea. Can also send special keys.
void sendKeys(CharSequence... keysToSend)
import org.openqa.selenium.Keys;
// Type text
driver.findElement(By.id("username")).sendKeys("testuser");
// Clear and type
WebElement emailField = driver.findElement(By.id("email"));
emailField.clear();
emailField.sendKeys("user@example.com");
// Type password
driver.findElement(By.id("password")).sendKeys("SecurePass123");
// Special keys
driver.findElement(By.id("search")).sendKeys("Selenium", Keys.ENTER);
// Keyboard shortcuts
WebElement textArea = driver.findElement(By.id("editor"));
textArea.sendKeys(Keys.chord(Keys.CONTROL, "a")); // Select All (Ctrl+A)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "c")); // Copy (Ctrl+C)
// Multiple keys
driver.findElement(By.id("field")).sendKeys("Hello", Keys.TAB, "World");
// File upload (for <input type="file">)
String filePath = System.getProperty("user.dir") + "/test.pdf";
driver.findElement(By.id("file-upload")).sendKeys(filePath);Keys.ENTER // Enter key Keys.TAB // Tab key Keys.ESCAPE // Escape key Keys.BACK_SPACE // Backspace Keys.DELETE // Delete Keys.ARROW_UP // Arrow keys Keys.ARROW_DOWN Keys.ARROW_LEFT Keys.ARROW_RIGHT Keys.HOME // Home key Keys.END // End key Keys.PAGE_UP // Page Up Keys.PAGE_DOWN // Page Down Keys.F1 to Keys.F12 // Function keys Keys.CONTROL // Ctrl (Windows/Linux) Keys.COMMAND // Cmd (Mac) Keys.SHIFT // Shift Keys.ALT // Alt
- Always
clear()beforesendKeys()to remove existing text - Use
Keys.chord()for simultaneous key presses - Verify field accepts input with
isEnabled() - For file uploads, use absolute paths
Related: clear(),Actions Class
clear()
User InteractionPurpose: Clears the content of an input field or textarea. Only works on editable elements.
void clear()
// Clear input field
WebElement usernameField = driver.findElement(By.id("username"));
usernameField.clear();
usernameField.sendKeys("newuser");
// Clear textarea
WebElement comments = driver.findElement(By.id("comments"));
comments.clear();
comments.sendKeys("Updated comment");
// Standard pattern: clear then type
driver.findElement(By.id("search"))
.clear();
driver.findElement(By.id("search"))
.sendKeys("Selenium WebDriver");
// Alternative: Select all and delete
WebElement field = driver.findElement(By.id("field"));
field.sendKeys(Keys.chord(Keys.CONTROL, "a"));
field.sendKeys(Keys.BACK_SPACE);- Only works on
<input>and<textarea> - Doesn't work on
readonlyordisabledfields - May not work on custom input components (use JavaScript instead)
// Use JavaScript to clear value
WebElement field = driver.findElement(By.id("readonly-field"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].value='';", field);
// Or set new value directly
js.executeScript("arguments[0].value='New Value';", field);Related: sendKeys()
getText()
Element InspectionPurpose: Returns the visible inner text of an element (what user sees on screen).
String getText()
// Get button text
String buttonText = driver.findElement(By.id("submit-btn")).getText();
System.out.println("Button says: " + buttonText);
// Get error message
String error = driver.findElement(By.className("error-message")).getText();
Assert.assertEquals(error, "Invalid credentials");
// Get page heading
String heading = driver.findElement(By.tagName("h1")).getText();
System.out.println("Page title: " + heading);
// Get all product names
List<WebElement> products = driver.findElements(By.className("product-name"));
for(WebElement product : products) {
System.out.println(product.getText());
}
// Check if text contains substring
String message = driver.findElement(By.id("message")).getText();
if(message.contains("success")) {
System.out.println("Operation successful");
}- Returns only visible text (not hidden elements)
- Returns empty string if element is hidden
- Includes text from child elements
- Trims leading/trailing whitespace
- Does NOT return text from input fields (use
getAttribute("value"))
<div id="message">
Welcome <span>Admin</span>!
<div style="display:none">Hidden text</div>
</div>String text = driver.findElement(By.id("message")).getText();
// Result: "Welcome Admin!"
// (Hidden text is NOT included)getText()
- Returns visible text only
- Use for: buttons, labels, divs, spans
- Does NOT work for input values
getAttribute("value")
- Returns input field value
- Use for: input, textarea
- Works for hidden fields too
Related: getAttribute(),isDisplayed()
getAttribute()
Element InspectionPurpose: Returns the value of a specified HTML attribute of an element.
String getAttribute(String attributeName)
// Get input value
String username = driver.findElement(By.id("username"))
.getAttribute("value");
// Get link URL
String url = driver.findElement(By.linkText("Home"))
.getAttribute("href");
// Get image source
String imageSrc = driver.findElement(By.id("logo"))
.getAttribute("src");
// Get CSS class
String className = driver.findElement(By.id("btn"))
.getAttribute("class");
// Get placeholder text
String placeholder = driver.findElement(By.id("search"))
.getAttribute("placeholder");
// Get data attributes
String userId = driver.findElement(By.id("profile"))
.getAttribute("data-user-id");
// Get title attribute
String tooltip = driver.findElement(By.id("help-icon"))
.getAttribute("title");
// Check if attribute exists
String disabled = driver.findElement(By.id("submit-btn"))
.getAttribute("disabled");
if(disabled != null) {
System.out.println("Button is disabled");
}// Get computed CSS properties
String color = driver.findElement(By.id("heading"))
.getCssValue("color");
String fontSize = driver.findElement(By.id("text"))
.getCssValue("font-size");
// Get inner HTML
String innerHTML = driver.findElement(By.id("div"))
.getAttribute("innerHTML");
// Get outer HTML
String outerHTML = driver.findElement(By.id("div"))
.getAttribute("outerHTML");
// Get text content (includes hidden text)
String textContent = driver.findElement(By.id("div"))
.getAttribute("textContent");| Attribute | Use Case | Example |
|---|---|---|
value | Get input field text | getAttribute("value") |
href | Get link URL | getAttribute("href") |
src | Get image/script source | getAttribute("src") |
class | Get CSS classes | getAttribute("class") |
id | Get element ID | getAttribute("id") |
disabled | Check if disabled | getAttribute("disabled") |
checked | Check checkbox state | getAttribute("checked") |
Related: getText(),isDisplayed()
close()
Session ManagementPurpose: Closes the current browser window. If it's the last window, the browser process terminates.
void close()
// Close current window
driver.close();
// Typical usage: Close popup window
String mainWindow = driver.getWindowHandle();
// Click link that opens new tab
driver.findElement(By.linkText("Terms")).click();
// Switch to new tab
Set<String> allWindows = driver.getWindowHandles();
for(String window : allWindows) {
if(!window.equals(mainWindow)) {
driver.switchTo().window(window);
// Read terms
String terms = driver.findElement(By.id("terms-text")).getText();
// Close this tab
driver.close();
break;
}
}
// Switch back to main window
driver.switchTo().window(mainWindow);close()
- Closes current window only
- Other windows remain open
- Browser process may continue
- Use for: Closing popups/tabs
quit()
- Closes all windows
- Terminates browser process
- Releases all resources
- Use for: Test cleanup
Related: quit(),getWindowHandle()
quit()
Session ManagementPurpose: Closes all browser windows, terminates the browser process, and releases all resources.
void quit()
import org.testng.annotations.*;
public class TestClass {
WebDriver driver;
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
}
@Test
public void testLogin() {
driver.get("https://example.com");
// Test logic
}
@AfterMethod
public void teardown() {
if(driver != null) {
driver.quit(); // Always quit in teardown
}
}
}
// Try-finally pattern (without TestNG)
WebDriver driver = null;
try {
driver = new ChromeDriver();
driver.get("https://example.com");
// Test logic
} finally {
if(driver != null) {
driver.quit(); // Ensures cleanup even if test fails
}
}- Using
close()instead ofquit()in test cleanup - Not checking if driver is null before calling quit()
- Calling driver methods after quit() (throws exception)
- Not using try-finally or @AfterMethod for guaranteed cleanup
Related: close()
Element State Methods
isDisplayed()
Element StatePurpose: Returns true if element is visible on the page (height & width > 0).
boolean isDisplayed()
// Check if element is visible
WebElement logo = driver.findElement(By.id("logo"));
if(logo.isDisplayed()) {
System.out.println("Logo is visible");
}
// Conditional action based on visibility
WebElement errorMessage = driver.findElement(By.id("error"));
if(errorMessage.isDisplayed()) {
System.out.println("Error: " + errorMessage.getText());
}
// Assertion in tests
WebElement successMsg = driver.findElement(By.className("success"));
Assert.assertTrue(successMsg.isDisplayed(), "Success message should be visible");
// Safe check (element may not exist)
List<WebElement> errors = driver.findElements(By.className("error"));
if(errors.size() > 0 && errors.get(0).isDisplayed()) {
System.out.println("Error displayed");
}display: nonevisibility: hiddenopacity: 0- Element has zero height/width
- Element is outside viewport (but still returns true if CSS says visible)
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait until element is visible
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("dynamic-element"))
);
// Verify it's displayed
Assert.assertTrue(element.isDisplayed());Related: isEnabled(),isSelected()
isEnabled()
Element StatePurpose: Returns true if element is enabled (not disabled). User can interact with it.
boolean isEnabled()
// Check if button is enabled
WebElement submitBtn = driver.findElement(By.id("submit"));
if(submitBtn.isEnabled()) {
submitBtn.click();
} else {
System.out.println("Button is disabled");
}
// Verify form field is editable
WebElement emailField = driver.findElement(By.id("email"));
Assert.assertTrue(emailField.isEnabled(), "Email field should be enabled");
// Wait until element becomes enabled
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement saveBtn = wait.until(driver -> {
WebElement btn = driver.findElement(By.id("save"));
return btn.isEnabled() ? btn : null;
});
saveBtn.click();<!-- This button returns isEnabled() = false --> <button id="submit" disabled>Submit</button> <!-- This input returns isEnabled() = false --> <input id="username" disabled value="admin"> <!-- This button returns isEnabled() = true --> <button id="save">Save</button>
- Check if form fields are editable
- Verify button states before clicking
- Wait for elements to become interactive after AJAX
- Validate form validation logic (disable submit until valid)
Related: isDisplayed(),isSelected()
isSelected()
Element StatePurpose: Returns true if checkbox, radio button, or option is selected/checked.
boolean isSelected()
// Check if checkbox is selected
WebElement termsCheckbox = driver.findElement(By.id("terms"));
if(!termsCheckbox.isSelected()) {
termsCheckbox.click(); // Check it
System.out.println("Checkbox now checked");
}
// Toggle checkbox
if(termsCheckbox.isSelected()) {
termsCheckbox.click(); // Uncheck
} else {
termsCheckbox.click(); // Check
}
// Verify checkbox state
Assert.assertTrue(termsCheckbox.isSelected(), "Terms checkbox should be checked");// Find radio button group
List<WebElement> paymentOptions = driver.findElements(By.name("payment"));
// Select specific radio button
for(WebElement option : paymentOptions) {
if(option.getAttribute("value").equals("credit-card")) {
if(!option.isSelected()) {
option.click();
}
break;
}
}
// Verify which radio is selected
for(WebElement option : paymentOptions) {
if(option.isSelected()) {
String selected = option.getAttribute("value");
System.out.println("Selected payment: " + selected);
}
}import org.openqa.selenium.support.ui.Select;
// Check selected option in dropdown
WebElement dropdown = driver.findElement(By.id("country"));
Select select = new Select(dropdown);
WebElement selectedOption = select.getFirstSelectedOption();
if(selectedOption.isSelected()) {
System.out.println("Selected: " + selectedOption.getText());
}
// Verify specific option is selected
List<WebElement> allOptions = select.getOptions();
for(WebElement option : allOptions) {
if(option.isSelected()) {
Assert.assertEquals(option.getText(), "United States");
}
}Related: isDisplayed(),isEnabled(),Select Class
Essential Classes & Interfaces
WebDriver Interface
Core InterfacePurpose: The main interface for controlling browser. Implemented by browser-specific drivers (ChromeDriver, FirefoxDriver, EdgeDriver, SafariDriver).
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.safari.SafariDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
// Chrome
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
// Firefox
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new FirefoxDriver();
// Edge
WebDriverManager.edgedriver().setup();
WebDriver driver = new EdgeDriver();
// Safari (Mac only)
WebDriver driver = new SafariDriver();
// With options
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--headless");
WebDriver driver = new ChromeDriver(options);| Method Category | Key Methods |
|---|---|
| Navigation | get(), navigate(), getCurrentUrl(), getTitle() |
| Element Location | findElement(), findElements() |
| Window Management | getWindowHandle(), getWindowHandles(), close(), quit() |
| Context Switching | switchTo() |
| Browser Options | manage() |
Related: WebElement
WebElement Interface
Core InterfacePurpose: Represents an HTML element on the page. Provides methods to interact with and inspect elements.
import org.openqa.selenium.WebElement;
WebElement element = driver.findElement(By.id("username"));
// Interaction Methods
element.click(); // Click element
element.sendKeys("text"); // Type text
element.clear(); // Clear field
element.submit(); // Submit form
// Inspection Methods
element.getText(); // Get visible text
element.getAttribute("value"); // Get attribute value
element.getCssValue("color"); // Get CSS property
element.getTagName(); // Get tag name (div, input, etc.)
element.getSize(); // Get element dimensions
element.getLocation(); // Get element position
element.getRect(); // Get size and location
// State Methods
element.isDisplayed(); // Is visible?
element.isEnabled(); // Is enabled?
element.isSelected(); // Is selected? (checkbox/radio)
// Finding child elements
element.findElement(By.className("child"));
element.findElements(By.tagName("li"));// Find form
WebElement loginForm = driver.findElement(By.id("login-form"));
// Find elements within form
WebElement username = loginForm.findElement(By.id("username"));
WebElement password = loginForm.findElement(By.id("password"));
WebElement submitBtn = loginForm.findElement(By.id("submit"));
// Check if fields are enabled
if(username.isEnabled() && password.isEnabled()) {
// Clear and enter values
username.clear();
username.sendKeys("admin");
password.clear();
password.sendKeys("password123");
// Check if submit button is enabled
if(submitBtn.isEnabled()) {
submitBtn.click();
}
}
// Verify success
WebElement message = driver.findElement(By.id("welcome-message"));
if(message.isDisplayed()) {
System.out.println(message.getText());
}Related: WebDriver
Actions Class
Advanced InteractionsPurpose: Provides advanced user interactions: mouse hover, drag & drop, right-click, double-click, keyboard operations, and complex action sequences.
import org.openqa.selenium.interactions.Actions;
Actions actions = new Actions(driver);
WebElement element = driver.findElement(By.id("element"));
// Mouse Hover
actions.moveToElement(element).perform();
// Right Click (Context Click)
actions.contextClick(element).perform();
// Double Click
actions.doubleClick(element).perform();
// Click and Hold
actions.clickAndHold(element).perform();
// Release
actions.release().perform();
// Drag and Drop
WebElement source = driver.findElement(By.id("draggable"));
WebElement target = driver.findElement(By.id("droppable"));
actions.dragAndDrop(source, target).perform();
// Drag by Offset
actions.dragAndDropBy(source, 100, 200).perform();
// Move by Offset
actions.moveByOffset(50, 100).perform();import org.openqa.selenium.Keys;
// Type in uppercase
actions.keyDown(Keys.SHIFT)
.sendKeys("hello world")
.keyUp(Keys.SHIFT)
.perform();
// Keyboard shortcuts
// Ctrl + A (Select All)
actions.keyDown(Keys.CONTROL)
.sendKeys("a")
.keyUp(Keys.CONTROL)
.perform();
// Ctrl + C (Copy)
actions.keyDown(Keys.CONTROL)
.sendKeys("c")
.keyUp(Keys.CONTROL)
.perform();
// Copy-paste between fields
WebElement source = driver.findElement(By.id("source"));
WebElement target = driver.findElement(By.id("target"));
actions.click(source)
.keyDown(Keys.CONTROL)
.sendKeys("a")
.sendKeys("c")
.keyUp(Keys.CONTROL)
.click(target)
.keyDown(Keys.CONTROL)
.sendKeys("v")
.keyUp(Keys.CONTROL)
.perform();// Hover over menu, then submenu, then click
WebElement menu = driver.findElement(By.id("menu"));
WebElement submenu = driver.findElement(By.id("submenu"));
WebElement item = driver.findElement(By.id("menu-item"));
actions.moveToElement(menu)
.pause(Duration.ofMillis(500))
.moveToElement(submenu)
.pause(Duration.ofMillis(500))
.moveToElement(item)
.click()
.perform();
// Scroll to element (Selenium 4+)
actions.scrollToElement(element).perform();
// Scroll by amount
actions.scrollByAmount(0, 500).perform(); // Scroll down 500px- Actions are built but not executed until
.perform()is called - Forgetting
.perform()is the #1 mistake with Actions class - Each action chain needs its own
.perform()call
Related: click(),sendKeys()
Alert Interface
Popup HandlingPurpose: Handle JavaScript alerts, confirmations, and prompts.
import org.openqa.selenium.Alert;
// Switch to alert
Alert alert = driver.switchTo().alert();
// Get alert text
String alertText = alert.getText();
System.out.println("Alert says: " + alertText);
// Accept alert (Click OK)
alert.accept();
// Dismiss alert (Click Cancel)
alert.dismiss();
// Send text to prompt
alert.sendKeys("Input text");
alert.accept();// 1. Simple Alert
// JavaScript: alert("Hello World");
driver.findElement(By.id("alert-button")).click();
Alert alert = driver.switchTo().alert();
System.out.println(alert.getText());
alert.accept();
// 2. Confirmation Alert
// JavaScript: confirm("Are you sure?");
driver.findElement(By.id("confirm-button")).click();
Alert confirm = driver.switchTo().alert();
System.out.println(confirm.getText());
confirm.dismiss(); // Or confirm.accept()
// 3. Prompt Alert
// JavaScript: prompt("Enter your name:");
driver.findElement(By.id("prompt-button")).click();
Alert prompt = driver.switchTo().alert();
prompt.sendKeys("John Doe");
prompt.accept();
// With Explicit Wait
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
alert.accept();- Cannot inspect alerts using DevTools (they're native browser popups)
- Must switch to alert before interacting with it
- Alert must be present before
switchTo().alert() - Use
ExpectedConditions.alertIsPresent()to wait
Related: switchTo(),ExpectedConditions
Select Class
Dropdown HandlingPurpose: Specialized class for handling <select> dropdown elements. Provides methods to select/deselect options by text, value, or index.
import org.openqa.selenium.support.ui.Select;
// Locate dropdown and create Select object
WebElement dropdownElement = driver.findElement(By.id("country"));
Select dropdown = new Select(dropdownElement);
// Selection Methods
dropdown.selectByVisibleText("India"); // By visible text
dropdown.selectByValue("in"); // By value attribute
dropdown.selectByIndex(2); // By index (0-based)
// Get selected option
WebElement selected = dropdown.getFirstSelectedOption();
System.out.println("Selected: " + selected.getText());
// Get all options
List<WebElement> allOptions = dropdown.getOptions();
System.out.println("Total options: " + allOptions.size());
// Print all options
for(WebElement option : allOptions) {
System.out.println(option.getText());
}
// Check if multi-select
if(dropdown.isMultiple()) {
System.out.println("This is a multi-select dropdown");
}<!-- Single Select -->
<select id="country" name="country">
<option value="">Select Country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="in">India</option>
</select>
<!-- Multi-Select -->
<select id="skills" name="skills" multiple>
<option value="java">Java</option>
<option value="python">Python</option>
<option value="selenium">Selenium</option>
</select>WebElement skillsElement = driver.findElement(By.id("skills"));
Select skills = new Select(skillsElement);
// Verify it's multi-select
Assert.assertTrue(skills.isMultiple());
// Select multiple options
skills.selectByValue("java");
skills.selectByValue("selenium");
skills.selectByVisibleText("Python");
// Get all selected options
List<WebElement> selected = skills.getAllSelectedOptions();
System.out.println("Selected " + selected.size() + " options");
for(WebElement option : selected) {
System.out.println("- " + option.getText());
}
// Deselect specific option
skills.deselectByValue("java");
// Deselect all
skills.deselectAll();// Select option that contains specific text
Select dropdown = new Select(driver.findElement(By.id("country")));
List<WebElement> options = dropdown.getOptions();
for(WebElement option : options) {
if(option.getText().contains("United")) {
dropdown.selectByVisibleText(option.getText());
break;
}
}
// Select random option
Random random = new Random();
int randomIndex = random.nextInt(options.size());
dropdown.selectByIndex(randomIndex);
// Verify option exists before selecting
public void safeSelectByText(Select dropdown, String text) {
List<WebElement> options = dropdown.getOptions();
boolean found = false;
for(WebElement option : options) {
if(option.getText().equals(text)) {
dropdown.selectByVisibleText(text);
found = true;
break;
}
}
if(!found) {
throw new RuntimeException("Option not found: " + text);
}
}- Only works with
<select>tags - Does NOT work with custom dropdowns (div-based, React Select, etc.)
- For custom dropdowns, use
click()andfindElement()
Related: isSelected()
JavascriptExecutor Interface
JavaScript ExecutionPurpose: Execute JavaScript code directly in the browser. Use when Selenium's native methods fail or when you need browser-level operations.
import org.openqa.selenium.JavascriptExecutor;
// Cast WebDriver to JavascriptExecutor
JavascriptExecutor js = (JavascriptExecutor) driver;
// Execute JavaScript
js.executeScript("JavaScript code here");
// Execute and return value
Object result = js.executeScript("return document.title;");JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = driver.findElement(By.id("element"));
// 1. Click element (when normal click fails)
js.executeScript("arguments[0].click();", element);
// 2. Scroll to element
js.executeScript("arguments[0].scrollIntoView(true);", element);
// 3. Scroll to bottom
js.executeScript("window.scrollTo(0, document.body.scrollHeight)");
// 4. Scroll to top
js.executeScript("window.scrollTo(0, 0)");
// 5. Change element value
js.executeScript("arguments[0].value='New Value';", element);
// 6. Highlight element (debugging)
js.executeScript("arguments[0].style.border='3px solid red'", element);
// 7. Remove attribute
js.executeScript("arguments[0].removeAttribute('disabled');", element);
// 8. Get page height
Long height = (Long) js.executeScript("return document.body.scrollHeight;");
// 9. Refresh page
js.executeScript("location.reload()");
// 10. Navigate to URL
js.executeScript("window.location = 'https://www.example.com'");// Get all links on page
List<WebElement> links = (List<WebElement>) js.executeScript(
"return document.getElementsByTagName('a');"
);
// Check if element is in viewport
Boolean inView = (Boolean) js.executeScript(
"var elem = arguments[0];" +
"var rect = elem.getBoundingClientRect();" +
"return (" +
" rect.top >= 0 &&" +
" rect.left >= 0 &&" +
" rect.bottom <= window.innerHeight &&" +
" rect.right <= window.innerWidth" +
");",
element
);
// Generate alert
js.executeScript("alert('This is a test alert');");
// Get computed style
String color = (String) js.executeScript(
"return window.getComputedStyle(arguments[0]).color;",
element
);
// Zoom page
js.executeScript("document.body.style.zoom='150%'");
// Open new tab
js.executeScript("window.open('https://www.example.com', '_blank');");public class JSUtils {
JavascriptExecutor js;
public JSUtils(WebDriver driver) {
this.js = (JavascriptExecutor) driver;
}
public void clickElement(WebElement element) {
js.executeScript("arguments[0].click();", element);
}
public void scrollToElement(WebElement element) {
js.executeScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", element);
}
public void highlightElement(WebElement element) {
js.executeScript(
"arguments[0].style.border='3px solid red';" +
"arguments[0].style.backgroundColor='yellow';",
element
);
}
public String getPageTitle() {
return (String) js.executeScript("return document.title;");
}
public void scrollToBottom() {
js.executeScript("window.scrollTo(0, document.body.scrollHeight)");
}
public Boolean isElementInViewport(WebElement element) {
return (Boolean) js.executeScript(
"var rect = arguments[0].getBoundingClientRect();" +
"return (" +
" rect.top >= 0 &&" +
" rect.bottom <= window.innerHeight" +
");",
element
);
}
}Related: click(),sendKeys()
WebDriverWait Class
Explicit WaitPurpose: Waits for a specific condition to be met before proceeding. Most commonly used for handling dynamic elements in modern web applications.
WebDriverWait wait = new WebDriverWait(driver, Duration duration)
import org.openqa.selenium.support.ui.ExpectedConditions;
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait for element to be clickable
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
button.click();
// Wait for element to be visible
WebElement message = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("success-message"))
);
// Wait for element to be present in DOM
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("dynamic-element")));
// Wait for text to be present
wait.until(ExpectedConditions.textToBePresentInElementLocated(
By.id("status"),
"Completed"
));
// Wait for title
wait.until(ExpectedConditions.titleIs("Dashboard"));
wait.until(ExpectedConditions.titleContains("Dashboard"));
// Wait for URL
wait.until(ExpectedConditions.urlToBe("https://example.com/dashboard"));
wait.until(ExpectedConditions.urlContains("/dashboard"));
// Wait for alert
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
// Wait for element to be invisible (loading spinner)
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loader")));
// Wait for frame and switch
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frame-id"));// Custom condition with lambda
WebElement element = wait.until(driver -> {
WebElement el = driver.findElement(By.id("status"));
String status = el.getText();
return status.equals("Ready") ? el : null;
});
// Custom condition: Wait for element attribute to have value
wait.until(driver -> {
WebElement el = driver.findElement(By.id("progress"));
String value = el.getAttribute("data-progress");
return value.equals("100") ? true : null;
});
// Wait for element count
wait.until(driver -> {
List<WebElement> items = driver.findElements(By.className("item"));
return items.size() > 5 ? true : null;
});
// Wait for page to be fully loaded (AJAX complete)
wait.until(driver ->
js.executeScript("return document.readyState").equals("complete")
);
// Wait for jQuery to complete (if using jQuery)
wait.until(driver ->
(Boolean) js.executeScript("return jQuery.active == 0")
);- Use Explicit Waits over Implicit Waits
- Set realistic timeout values (10-15 seconds typical)
- Wait for specific conditions, not arbitrary sleeps
- Create reusable wait methods in utility classes
- Handle TimeoutException gracefully
import org.openqa.selenium.TimeoutException;
try {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element")));
} catch(TimeoutException e) {
System.out.println("Element did not appear within 5 seconds");
// Take screenshot, log error, etc.
}Related: ExpectedConditions,implicitlyWait(),FluentWait
ExpectedConditions Class
Wait ConditionsPurpose: Provides predefined conditions for use with WebDriverWait. Contains 40+ ready-to-use wait conditions.
| Category | Condition | When to Use |
|---|---|---|
| Element Presence | presenceOfElementLocated | Element exists in DOM (may not be visible) |
presenceOfAllElementsLocated | Multiple elements exist in DOM | |
visibilityOfElementLocated | Element exists AND visible (height/width > 0) | |
visibilityOf | WebElement object is visible | |
| Element State | elementToBeClickable | Element is visible AND enabled |
elementToBeSelected | Checkbox/radio is selected | |
elementSelectionStateToBe | Element selection matches expected state | |
| Element Disappearance | invisibilityOfElementLocated | Element not visible or not in DOM |
stalenessOf | Element no longer attached to DOM | |
numberOfElementsToBe | Specific count of elements | |
| Text/Attribute | textToBePresentInElement | Element contains specific text |
textToBePresentInElementValue | Input value contains text | |
attributeToBe | Attribute has specific value | |
| Page State | titleIs | Page title exactly matches |
titleContains | Page title contains text | |
urlToBe / urlContains | URL matches or contains text | |
| Alerts/Frames | alertIsPresent | Alert popup is present |
frameToBeAvailableAndSwitchToIt | Frame is available and switch to it |
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait for AJAX loading to complete
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-spinner")));
// Wait for specific attribute value
wait.until(ExpectedConditions.attributeToBe(
By.id("progress-bar"),
"aria-valuenow",
"100"
));
// Wait for attribute to contain text
wait.until(ExpectedConditions.attributeContains(
By.id("status"),
"class",
"success"
));
// Wait for number of elements to be exactly X
wait.until(ExpectedConditions.numberOfElementsToBe(
By.className("product-card"),
10
));
// Wait for number of elements to be more than X
wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(
By.className("search-result"),
5
));
// Wait for element to become stale (DOM refresh)
WebElement oldElement = driver.findElement(By.id("element"));
driver.navigate().refresh();
wait.until(ExpectedConditions.stalenessOf(oldElement));
// Combined conditions with AND
wait.until(ExpectedConditions.and(
ExpectedConditions.visibilityOfElementLocated(By.id("element1")),
ExpectedConditions.elementToBeClickable(By.id("element2"))
));
// Combined conditions with OR
wait.until(ExpectedConditions.or(
ExpectedConditions.titleIs("Dashboard"),
ExpectedConditions.titleIs("Home")
));
// Negation (wait for condition to NOT be true)
wait.until(ExpectedConditions.not(
ExpectedConditions.attributeContains(By.id("btn"), "class", "disabled")
));Related: WebDriverWait,FluentWait
FluentWait Class
Advanced WaitPurpose: Most flexible wait mechanism. Allows custom polling interval,timeout, and exception ignoring.
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.ElementNotInteractableException;
// Create FluentWait
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30)) // Max wait time
.pollingEvery(Duration.ofSeconds(2)) // Check every 2 seconds
.ignoring(NoSuchElementException.class) // Ignore this exception
.ignoring(ElementNotInteractableException.class) // Ignore this too
.withMessage("Element not found after 30 seconds"); // Custom error message
// Use the wait
WebElement element = fluentWait.until(driver ->
driver.findElement(By.id("dynamic-element"))
);// Wait for text to contain specific value
WebElement statusElement = fluentWait.until(driver -> {
WebElement el = driver.findElement(By.id("status"));
String status = el.getText();
if(status.contains("Completed")) {
return el;
}
return null; // Keep waiting
});
// Wait for element count to reach threshold
List<WebElement> items = fluentWait.until(driver -> {
List<WebElement> elements = driver.findElements(By.className("item"));
return elements.size() >= 10 ? elements : null;
});
// Wait for attribute value change
WebElement progressBar = fluentWait.until(driver -> {
WebElement el = driver.findElement(By.id("progress"));
String value = el.getAttribute("data-progress");
return value.equals("100") ? el : null;
});
// Wait for page to be fully loaded (including AJAX)
fluentWait.until(driver -> {
JavascriptExecutor js = (JavascriptExecutor) driver;
return js.executeScript("return document.readyState").equals("complete");
});WebDriverWait
- Fixed polling (500ms)
- Simpler syntax
- Use for: 90% of cases
- Extends FluentWait
FluentWait
- Custom polling interval
- Ignore specific exceptions
- Use for: Complex scenarios
- Most flexible option
public class WaitHelper {
private WebDriver driver;
private Wait<WebDriver> fluentWait;
public WaitHelper(WebDriver driver) {
this.driver = driver;
this.fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(1))
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
}
public WebElement waitForElementToBeClickable(By locator) {
return fluentWait.until(driver -> {
WebElement el = driver.findElement(locator);
return el.isDisplayed() && el.isEnabled() ? el : null;
});
}
public void waitForTextToChange(By locator, String oldText) {
fluentWait.until(driver -> {
String currentText = driver.findElement(locator).getText();
return !currentText.equals(oldText);
});
}
public void waitForPageLoad() {
fluentWait.until(driver -> {
JavascriptExecutor js = (JavascriptExecutor) driver;
return js.executeScript("return document.readyState").equals("complete");
});
}
}Related: WebDriverWait,ExpectedConditions
PageFactory Class
Page Object ModelPurpose: Initializes web elements defined with @FindBy annotations in Page Object classes. Essential for implementing Page Object Model pattern.
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.FindBy;
public class LoginPage {
WebDriver driver;
// Define elements with @FindBy
@FindBy(id = "username")
WebElement usernameField;
@FindBy(id = "password")
WebElement passwordField;
@FindBy(xpath = "//button[@type='submit']")
WebElement loginButton;
// Constructor - Initialize elements
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this); // REQUIRED!
}
// Page methods
public void login(String username, String password) {
usernameField.sendKeys(username);
passwordField.sendKeys(password);
loginButton.click();
}
}import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
public class DashboardPage {
WebDriver driver;
@FindBy(id = "user-profile")
WebElement profileSection;
@FindBy(className = "notification")
List<WebElement> notifications;
public DashboardPage(WebDriver driver) {
this.driver = driver;
// Use AjaxElementLocatorFactory for dynamic elements
// Elements are re-located each time they're accessed
// Timeout of 15 seconds for each element
PageFactory.initElements(
new AjaxElementLocatorFactory(driver, 15),
this
);
}
public int getNotificationCount() {
return notifications.size(); // Re-locates elements each time
}
public void clickProfile() {
profileSection.click(); // Re-locates element each time
}
}| Method | Behavior |
|---|---|
PageFactory.initElements(driver, this) | Elements located once, cached (faster but can become stale) |
AjaxElementLocatorFactory | Elements re-located on each access (slower but handles dynamic content) |
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.FindAll;
import org.openqa.selenium.support.CacheLookup;
public class AdvancedPage {
// Basic @FindBy
@FindBy(id = "element")
WebElement element;
// List of elements
@FindBy(className = "product")
List<WebElement> products;
// @FindBys - AND condition (all must match)
@FindBys({
@FindBy(tagName = "input"),
@FindBy(className = "search")
})
WebElement searchInput; // <input class="search">
// @FindAll - OR condition (any can match)
@FindAll({
@FindBy(id = "submit"),
@FindBy(name = "submit"),
@FindBy(className = "submit-btn")
})
WebElement submitButton; // Matches first found
// @CacheLookup - Cache element (use for static elements only)
@CacheLookup
@FindBy(id = "logo")
WebElement logo;
public AdvancedPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
}Related: findElement()
TakesScreenshot Interface
Screenshot CapturePurpose: Capture screenshots of the current browser window. Essential for debugging and test reporting.
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.OutputType;
import org.apache.commons.io.FileUtils;
import java.io.File;
// Cast driver to TakesScreenshot
TakesScreenshot ts = (TakesScreenshot) driver;
// Capture screenshot as File
File screenshot = ts.getScreenshotAs(OutputType.FILE);
// Save to specific location
File destination = new File("./screenshots/test.png");
FileUtils.copyFile(screenshot, destination);
System.out.println("Screenshot saved: " + destination.getAbsolutePath());import java.text.SimpleDateFormat;
import java.util.Date;
public class ScreenshotUtil {
public static String captureScreenshot(WebDriver driver, String testName) {
try {
// Generate timestamp
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
// Create filename
String fileName = testName + "_" + timestamp + ".png";
String screenshotPath = "./screenshots/" + fileName;
// Capture screenshot
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
File destination = new File(screenshotPath);
// Ensure directory exists
destination.getParentFile().mkdirs();
// Save file
FileUtils.copyFile(source, destination);
System.out.println("Screenshot saved: " + screenshotPath);
return screenshotPath;
} catch (Exception e) {
System.out.println("Failed to capture screenshot: " + e.getMessage());
return null;
}
}
// Capture as Base64 (for HTML reports)
public static String captureBase64(WebDriver driver) {
TakesScreenshot ts = (TakesScreenshot) driver;
return ts.getScreenshotAs(OutputType.BASE64);
}
// Capture as byte array
public static byte[] captureBytes(WebDriver driver) {
TakesScreenshot ts = (TakesScreenshot) driver;
return ts.getScreenshotAs(OutputType.BYTES);
}
}import org.testng.ITestListener;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
@Override
public void onTestFailure(ITestResult result) {
System.out.println("Test Failed: " + result.getName());
// Capture screenshot on failure
WebDriver driver = ((BaseTest) result.getInstance()).getDriver();
String screenshotPath = ScreenshotUtil.captureScreenshot(
driver,
result.getName()
);
// Attach to Extent Report (if using)
if(screenshotPath != null) {
// ExtentReports code here
}
}
}| OutputType | Returns | Use Case |
|---|---|---|
OutputType.FILE | File object | Save to disk |
OutputType.BASE64 | Base64 string | Embed in HTML reports |
OutputType.BYTES | byte[] | Direct manipulation |
Related: WebDriver
Advanced Locator Strategies
CSS Selector (Advanced)
Locator StrategyPurpose: CSS Selectors provide fast, readable, and powerful element location. 2-3x faster than XPath and preferred for most scenarios.
| Pattern | CSS Syntax | Example |
|---|---|---|
| ID | #id | #username |
| Class | .class | .btn-primary |
| Tag | tag | input |
| Attribute | [attribute='value'] | [type='email'] |
| Contains | [attribute*='value'] | [class*='submit'] |
| Starts with | [attribute^='value'] | [id^='user'] |
| Ends with | [attribute$='value'] | [id$='name'] |
| Child | parent > child | div > input |
| Descendant | ancestor descendant | form input |
| nth-child | :nth-child(n) | li:nth-child(2) |
| First child | :first-child | li:first-child |
| Last child | :last-child | li:last-child |
// ID
driver.findElement(By.cssSelector("#username"));
// Class
driver.findElement(By.cssSelector(".form-control"));
// Multiple classes
driver.findElement(By.cssSelector(".btn.btn-primary"));
// Tag with attribute
driver.findElement(By.cssSelector("input[type='email']"));
// Tag with multiple attributes
driver.findElement(By.cssSelector("input[type='text'][name='username']"));
// Attribute contains
driver.findElement(By.cssSelector("button[class*='submit']"));
// Attribute starts with
driver.findElement(By.cssSelector("input[id^='user']"));
// Attribute ends with
driver.findElement(By.cssSelector("input[id$='name']"));
// Direct child
driver.findElement(By.cssSelector("form > input"));
// Descendant (any level)
driver.findElement(By.cssSelector("div.form-group input"));
// nth-child (2nd element)
driver.findElement(By.cssSelector("ul > li:nth-child(2)"));
// First child
driver.findElement(By.cssSelector("ul > li:first-child"));
// Last child
driver.findElement(By.cssSelector("ul > li:last-child"));
// nth-of-type
driver.findElement(By.cssSelector("div:nth-of-type(3)"));
// Adjacent sibling (+)
driver.findElement(By.cssSelector("label + input"));
// General sibling (~)
driver.findElement(By.cssSelector("h2 ~ p"));
// Combine multiple
driver.findElement(By.cssSelector("form#login input[type='text'].form-control"));// Find email input in login form
driver.findElement(By.cssSelector("form#login input[type='email']"));
// Find submit button with specific text (using attribute)
driver.findElement(By.cssSelector("button[type='submit'][value='Login']"));
// Find element by data attribute
driver.findElement(By.cssSelector("div[data-testid='user-profile']"));
// Find placeholder-specific input
driver.findElement(By.cssSelector("input[placeholder='Enter email']"));
// Find disabled element
driver.findElement(By.cssSelector("button[disabled]"));
// Find checkbox that is checked
driver.findElement(By.cssSelector("input[type='checkbox']:checked"));
// Find link containing specific href
driver.findElement(By.cssSelector("a[href*='/products']"));
// Find element by exact class name (avoiding partial matches)
driver.findElement(By.cssSelector(".btn-primary:not(.btn-primary-outline)"));
// Complex: 3rd input inside 2nd form
driver.findElement(By.cssSelector("form:nth-of-type(2) input:nth-of-type(3)"));
// Find all list items except first
driver.findElements(By.cssSelector("ul > li:not(:first-child)"));- Use ID when unique:
#username - Combine tag + attribute:
input[type='email'] - Avoid deep nesting (keep selectors short)
- Use data attributes for test automation:
[data-testid='value'] - Prefer class over complex traversal
Related: XPath,findElement()
XPath (Advanced)
Locator StrategyPurpose: XPath is the most powerful locator strategy. Can traverse in any direction, select by text, and handle complex DOM structures. Slower than CSS but more flexible.
| Type | XPath Syntax | Example |
|---|---|---|
| Absolute | /html/body/div/input | ❌ Brittle, avoid! |
| Relative | //input[@id='username'] | ✅ Recommended |
| By attribute | //tag[@attribute='value'] | //input[@type='email'] |
| By text | //tag[text()='value'] | //button[text()='Submit'] |
| Contains text | //tag[contains(text(),'value')] | //a[contains(text(),'Login')] |
| Contains attribute | //tag[contains(@attr,'value')] | //div[contains(@class,'user')] |
| Starts with | //tag[starts-with(@attr,'value')] | //input[starts-with(@id,'user')] |
| AND condition | //tag[@attr1='v1' and @attr2='v2'] | //input[@type='text' and @name='email'] |
| OR condition | //tag[@attr='v1' or @attr='v2'] | //input[@id='email' or @name='email'] |
| Parent | //tag[@attr='value']/parent::tag | //input[@id='username']/parent::div |
| Child | //parent/child | //form/input |
| Following sibling | //tag/following-sibling::tag | //label/following-sibling::input |
| Preceding sibling | //tag/preceding-sibling::tag | //input/preceding-sibling::label |
| Index | (//tag)[index] | (//li)[2] |
// Basic attribute
driver.findElement(By.xpath("//input[@id='username']"));
// Text selection (unique to XPath)
driver.findElement(By.xpath("//button[text()='Submit']"));
driver.findElement(By.xpath("//a[text()='Login']"));
// Partial text match
driver.findElement(By.xpath("//button[contains(text(),'Submit')]"));
// Multiple attributes (AND)
driver.findElement(By.xpath("//input[@type='text' and @name='username']"));
// OR condition
driver.findElement(By.xpath("//input[@id='email' or @name='email']"));
// Contains attribute
driver.findElement(By.xpath("//div[contains(@class,'form-group')]"));
// Starts with
driver.findElement(By.xpath("//input[starts-with(@id,'user')]"));
// Parent traversal
driver.findElement(By.xpath("//input[@id='username']/parent::div"));
// Ancestor
driver.findElement(By.xpath("//input[@id='username']/ancestor::form"));
// Following sibling
driver.findElement(By.xpath("//label[text()='Email']/following-sibling::input"));
// Preceding sibling
driver.findElement(By.xpath("//input[@id='password']/preceding-sibling::label"));
// Child
driver.findElement(By.xpath("//form[@id='login']//input[@type='email']"));
// Descendant
driver.findElement(By.xpath("//div[@class='container']//button"));
// Index (select 2nd element)
driver.findElement(By.xpath("(//input[@type='text'])[2]"));
// Last element
driver.findElement(By.xpath("(//li)[last()]"));
// Position-based
driver.findElement(By.xpath("//li[position()=3]"));// Find input based on label text
driver.findElement(By.xpath("//label[text()='Username']/following-sibling::input"));
// Find button in specific div
driver.findElement(By.xpath("//div[@class='modal']//button[text()='Confirm']"));
// Find row containing specific text, then click button in that row
driver.findElement(By.xpath("//tr[contains(., 'John Doe')]//button[@class='edit']"));
// Find element with specific class but NOT another class
driver.findElement(By.xpath("//button[contains(@class,'btn') and not(contains(@class,'disabled'))]"));
// Find element by data attribute
driver.findElement(By.xpath("//div[@data-testid='user-profile']"));
// Dynamic ID (changes on reload) - use contains
driver.findElement(By.xpath("//input[contains(@id,'username')]"));
// Select option by visible text
driver.findElement(By.xpath("//select[@id='country']//option[text()='India']"));
// Find link by partial href
driver.findElement(By.xpath("//a[contains(@href,'/products')]"));
// Find element by multiple classes
driver.findElement(By.xpath("//div[contains(@class,'card') and contains(@class,'featured')]"));
// Find nth element of specific type
driver.findElement(By.xpath("(//div[@class='product'])[3]"));
// Find element where attribute exists (regardless of value)
driver.findElement(By.xpath("//button[@disabled]"));
// Normalize space (handle extra whitespace)
driver.findElement(By.xpath("//button[normalize-space(text())='Submit']"));
// Case-insensitive text match (using translate)
driver.findElement(By.xpath("//button[translate(text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='submit']"));- ❌ Avoid absolute XPath:
/html/body/div[1]/div[2] - ✅ Use relative XPath:
//input[@id='username'] - ❌ Avoid index-based unless necessary:
[1], [2] - ✅ Use attributes that won't change:
id, name, data-* - ✅ Keep XPath short and readable
- ✅ Use contains() for dynamic attributes
When to use CSS
- Performance is critical
- Forward navigation only
- Simple element selection
- Cleaner, more readable
When to use XPath
- Need parent/ancestor traversal
- Text-based selection
- Complex conditions
- Dynamic structures
Related: CSS Selector,findElement()
Timeouts & Performance
implicitlyWait()
Global TimeoutPurpose: Sets a global timeout for all findElement() calls. WebDriver polls the DOM for the specified duration before throwing NoSuchElementException.
Timeouts implicitlyWait(Duration duration)
import java.time.Duration;
// Set implicit wait (applies globally)
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
// Now all findElement() calls wait up to 10 seconds
driver.findElement(By.id("username")).sendKeys("admin");
driver.findElement(By.id("password")).sendKeys("password");
driver.findElement(By.id("submit")).click();
// Set to zero to disable
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(0));- Applies to ALL elements globally (cannot customize per element)
- Only waits for element presence, not visibility or clickability
- Conflicts with Explicit Waits (can cause unpredictable behavior)
- Cannot wait for complex conditions (text, attribute changes)
- Not recommended for production frameworks
Related: WebDriverWait,FluentWait
pageLoadTimeout()
Navigation TimeoutPurpose: Sets the maximum time to wait for a page to load completely. Throws TimeoutException if page doesn't load within specified duration.
// Set page load timeout
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));
// Navigate to URL (will timeout after 30 seconds if not loaded)
driver.get("https://www.example.com");
// Handle timeout
try {
driver.get("https://slow-website.com");
} catch(TimeoutException e) {
System.out.println("Page load timed out after 30 seconds");
driver.navigate().refresh(); // Retry
}Related: get(),scriptTimeout()
scriptTimeout()
Script TimeoutPurpose: Sets timeout for asynchronous JavaScript execution viaexecuteAsyncScript().
// Set script timeout
driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(30));
// Execute async script
JavascriptExecutor js = (JavascriptExecutor) driver;
Object result = js.executeAsyncScript(
"var callback = arguments[arguments.length - 1];" +
"setTimeout(function() {" +
" callback('Script completed');" +
"}, 5000);"
);
System.out.println(result); // "Script completed"Related: JavascriptExecutor
Selenium 4 New Features
Relative Locators (Selenium 4)
New in Selenium 4Purpose: Locate elements based on their spatial relationship to other elements. Useful when traditional locators are unreliable.
import static org.openqa.selenium.support.locators.RelativeLocator.with;
WebElement referenceElement = driver.findElement(By.id("reference"));
// Above
WebElement above = driver.findElement(with(By.tagName("input"))
.above(referenceElement));
// Below
WebElement below = driver.findElement(with(By.tagName("button"))
.below(referenceElement));
// To left of
WebElement left = driver.findElement(with(By.tagName("label"))
.toLeftOf(referenceElement));
// To right of
WebElement right = driver.findElement(with(By.tagName("span"))
.toRightOf(referenceElement));
// Near (within 50px by default)
WebElement near = driver.findElement(with(By.tagName("input"))
.near(referenceElement));
// Combine multiple directions
WebElement element = driver.findElement(with(By.tagName("button"))
.below(referenceElement)
.toRightOf(anotherElement));// Find input field below "Email" label
WebElement emailLabel = driver.findElement(By.xpath("//label[text()='Email']"));
WebElement emailInput = driver.findElement(with(By.tagName("input"))
.below(emailLabel));
// Find password field below email field
WebElement passwordInput = driver.findElement(with(By.tagName("input"))
.below(emailInput));
// Find submit button below password field
WebElement submitBtn = driver.findElement(with(By.tagName("button"))
.below(passwordInput));Related: findElement()
Chrome DevTools Protocol (Selenium 4)
New in Selenium 4Purpose: Direct access to Chrome DevTools Protocol for advanced browser operations like network interception, performance metrics, console logs, and more.
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v120.network.Network;
import org.openqa.selenium.devtools.v120.log.Log;
ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
// 1. Capture network traffic
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
devTools.addListener(Network.requestWillBeSent(), request -> {
System.out.println("Request: " + request.getRequest().getUrl());
});
devTools.addListener(Network.responseReceived(), response -> {
System.out.println("Response: " + response.getResponse().getUrl());
System.out.println("Status: " + response.getResponse().getStatus());
});
// 2. Capture console logs
devTools.send(Log.enable());
devTools.addListener(Log.entryAdded(), logEntry -> {
System.out.println("Console " + logEntry.getLevel() + ": " + logEntry.getText());
});
// 3. Mock geolocation
devTools.send(Emulation.setGeolocationOverride(
Optional.of(40.7128), // Latitude (New York)
Optional.of(-74.0060), // Longitude
Optional.of(1) // Accuracy
));
// 4. Set network conditions (simulate slow 3G)
devTools.send(Network.emulateNetworkConditions(
false, // offline
100, // latency (ms)
50000, // download throughput (bytes/s)
20000, // upload throughput (bytes/s)
Optional.empty() // connection type
));
// 5. Block specific URLs
devTools.send(Network.setBlockedURLs(
Arrays.asList("*.jpg", "*.png", "*.css")
));
// 6. Get performance metrics
Map<String, Object> metrics = driver.executeCdpCommand(
"Performance.getMetrics",
new HashMap<>()
);- Monitor network requests/responses
- Capture JavaScript console logs
- Mock geolocation for location-based testing
- Simulate network conditions (offline, slow 3G)
- Block specific resources (ads, images)
- Measure performance metrics
Note: Chrome DevTools Protocol is Chrome-specific. Not available for other browsers.
Quick Reference Summary
- Core Methods: get(), findElement(), findElements(), click(), sendKeys(), getText(), getAttribute()
- State Checks: isDisplayed(), isEnabled(), isSelected()
- Navigation: navigate().to(), back(), forward(), refresh()
- Wait Classes: WebDriverWait, ExpectedConditions, FluentWait
- Advanced: Actions, Alert, Select, JavascriptExecutor, PageFactory
- Locators: CSS Selectors (preferred), XPath (when needed)
- Know the difference between similar methods (close vs quit, getText vs getAttribute)
- Understand when to use each locator strategy
- Be ready to write code for common scenarios
- Explain best practices for each concept
- Know the limitations and workarounds