guide30 min readUpdated Jan 20, 2026
Se

Keywords & Concepts

Master every essential Selenium concept with detailed explanations and code examples.

Tool:Selenium WebDriverLevel:intermediateDomain:QA Engineering

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.

💡 How to Use This Guide:
  • 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

Core WebDriver Methods

get()

Navigation

Purpose: Loads a web page in the current browser window and waits for the page to load completely.

Syntax
void get(String url)
Java - Example
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);
💡 Key Points:
  • 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)
⚠️ Common Mistakes:
  • Forgetting protocol: "example.com" ❌ → "https://example.com"
  • Not handling page load timeouts (use pageLoadTimeout())

Related: navigate().to(),navigate().back()

findElement()

Element Location

Purpose: Locates and returns the first matching WebElement on the current page. Throws NoSuchElementException if element not found.

Syntax
WebElement findElement(By locator)
Java - All Locator Strategies
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();
💡 Best Practices:
  • 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
Java - Error Handling
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 Location

Purpose: Returns a List of all matching WebElements. Returns empty list if no elements found (does NOT throw exception).

Syntax
List<WebElement> findElements(By locator)
Java - Examples
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 Interaction

Purpose: Simulates a mouse click on a web element (button, link, checkbox, etc.).

Syntax
void click()
Java - Examples
// 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);
⚠️ Common Click Failures & Solutions:
Java - Robust Click Method
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();
    }
}
💡 Prerequisites for Successful 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 Interaction

Purpose: Simulates typing text into an input field or textarea. Can also send special keys.

Syntax
void sendKeys(CharSequence... keysToSend)
Java - Examples
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);
💡 Common Keys Constants:
Java - Keys Enum
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
💡 Best Practices:
  • Always clear() before sendKeys() 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 Interaction

Purpose: Clears the content of an input field or textarea. Only works on editable elements.

Syntax
void clear()
Java - Examples
// 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);
⚠️ Limitations:
  • Only works on <input> and <textarea>
  • Doesn't work on readonly or disabled fields
  • May not work on custom input components (use JavaScript instead)
Java - Alternative for Non-Clearable Fields
// 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 Inspection

Purpose: Returns the visible inner text of an element (what user sees on screen).

Syntax
String getText()
Java - Examples
// 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");
}
💡 Important Behaviors:
  • 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"))
HTML Example
<div id="message">
    Welcome <span>Admin</span>!
    <div style="display:none">Hidden text</div>
</div>
Java - Result
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 Inspection

Purpose: Returns the value of a specified HTML attribute of an element.

Syntax
String getAttribute(String attributeName)
Java - Common Attributes
// 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");
}
💡 Special Use Cases:
Java - Special Attributes
// 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");
AttributeUse CaseExample
valueGet input field textgetAttribute("value")
hrefGet link URLgetAttribute("href")
srcGet image/script sourcegetAttribute("src")
classGet CSS classesgetAttribute("class")
idGet element IDgetAttribute("id")
disabledCheck if disabledgetAttribute("disabled")
checkedCheck checkbox stategetAttribute("checked")

Related: getText(),isDisplayed()

close()

Session Management

Purpose: Closes the current browser window. If it's the last window, the browser process terminates.

Syntax
void close()
Java - Examples
// 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 Management

Purpose: Closes all browser windows, terminates the browser process, and releases all resources.

Syntax
void quit()
Java - Best Practice Usage
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
    }
}
⚠️ Common Mistakes:
  • Using close() instead of quit() 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 State

Purpose: Returns true if element is visible on the page (height & width > 0).

Syntax
boolean isDisplayed()
Java - Examples
// 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");
}
💡 Returns false when:
  • display: none
  • visibility: hidden
  • opacity: 0
  • Element has zero height/width
  • Element is outside viewport (but still returns true if CSS says visible)
Java - Wait for Element to be 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 State

Purpose: Returns true if element is enabled (not disabled). User can interact with it.

Syntax
boolean isEnabled()
Java - Examples
// 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();
HTML - Disabled Attribute
<!-- 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>
💡 Common Use Cases:
  • 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 State

Purpose: Returns true if checkbox, radio button, or option is selected/checked.

Syntax
boolean isSelected()
Java - Checkboxes
// 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");
Java - Radio Buttons
// 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);
    }
}
Java - Dropdown Options
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 Interface

Purpose: The main interface for controlling browser. Implemented by browser-specific drivers (ChromeDriver, FirefoxDriver, EdgeDriver, SafariDriver).

Java - Browser Initialization
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 CategoryKey Methods
Navigationget(), navigate(), getCurrentUrl(), getTitle()
Element LocationfindElement(), findElements()
Window ManagementgetWindowHandle(), getWindowHandles(), close(), quit()
Context SwitchingswitchTo()
Browser Optionsmanage()

Related: WebElement

WebElement Interface

Core Interface

Purpose: Represents an HTML element on the page. Provides methods to interact with and inspect elements.

Java - WebElement Methods
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"));
💡 Complete Example:
Java - Form Interaction
// 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 Interactions

Purpose: Provides advanced user interactions: mouse hover, drag & drop, right-click, double-click, keyboard operations, and complex action sequences.

Java - Mouse Operations
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();
Java - Keyboard Operations
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();
Java - Complex Sequences
// 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
⚠️ Critical: Always call .perform()!
  • 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 Handling

Purpose: Handle JavaScript alerts, confirmations, and prompts.

Java - Alert Methods
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();
Java - Complete Examples
// 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();
⚠️ Important Notes:
  • 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 Handling

Purpose: Specialized class for handling <select> dropdown elements. Provides methods to select/deselect options by text, value, or index.

Java - Select Class Methods
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");
}
HTML - Dropdown Examples
<!-- 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>
Java - Multi-Select Handling
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();
💡 Advanced Usage:
Java - Dynamic Selection
// 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);
    }
}
⚠️ Select Class Limitations:
  • Only works with <select> tags
  • Does NOT work with custom dropdowns (div-based, React Select, etc.)
  • For custom dropdowns, use click() and findElement()

Related: isSelected()

JavascriptExecutor Interface

JavaScript Execution

Purpose: Execute JavaScript code directly in the browser. Use when Selenium's native methods fail or when you need browser-level operations.

Java - Setup
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;");
Java - Common Operations
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'");
Java - Advanced Examples
// 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');");
💡 Reusable Utility Methods:
Java - JS Utilities
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 Wait

Purpose: Waits for a specific condition to be met before proceeding. Most commonly used for handling dynamic elements in modern web applications.

Syntax
WebDriverWait wait = new WebDriverWait(driver, Duration duration)
Java - Common Usage Patterns
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"));
Java - Custom Conditions
// 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")
);
💡 Best Practices:
  • 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
Java - Exception Handling
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 Conditions

Purpose: Provides predefined conditions for use with WebDriverWait. Contains 40+ ready-to-use wait conditions.

CategoryConditionWhen to Use
Element PresencepresenceOfElementLocatedElement exists in DOM (may not be visible)
presenceOfAllElementsLocatedMultiple elements exist in DOM
visibilityOfElementLocatedElement exists AND visible (height/width > 0)
visibilityOfWebElement object is visible
Element StateelementToBeClickableElement is visible AND enabled
elementToBeSelectedCheckbox/radio is selected
elementSelectionStateToBeElement selection matches expected state
Element DisappearanceinvisibilityOfElementLocatedElement not visible or not in DOM
stalenessOfElement no longer attached to DOM
numberOfElementsToBeSpecific count of elements
Text/AttributetextToBePresentInElementElement contains specific text
textToBePresentInElementValueInput value contains text
attributeToBeAttribute has specific value
Page StatetitleIsPage title exactly matches
titleContainsPage title contains text
urlToBe / urlContainsURL matches or contains text
Alerts/FramesalertIsPresentAlert popup is present
frameToBeAvailableAndSwitchToItFrame is available and switch to it
Java - Comprehensive Examples
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 Wait

Purpose: Most flexible wait mechanism. Allows custom polling interval,timeout, and exception ignoring.

Java - FluentWait Configuration
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"))
);
Java - Custom Conditions
// 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
💡 Production Example:
Java - WaitHelper Utility
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 Model

Purpose: Initializes web elements defined with @FindBy annotations in Page Object classes. Essential for implementing Page Object Model pattern.

Java - Basic PageFactory Usage
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();
    }
}
Java - With AjaxElementLocatorFactory
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
    }
}
💡 Key Differences:
MethodBehavior
PageFactory.initElements(driver, this)Elements located once, cached (faster but can become stale)
AjaxElementLocatorFactoryElements re-located on each access (slower but handles dynamic content)
💡 Advanced @FindBy Usage:
Java - Advanced Annotations
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 Capture

Purpose: Capture screenshots of the current browser window. Essential for debugging and test reporting.

Java - Basic Screenshot
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());
Java - Reusable Screenshot Utility
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);
    }
}
Java - Usage in TestNG Listener
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
        }
    }
}
OutputTypeReturnsUse Case
OutputType.FILEFile objectSave to disk
OutputType.BASE64Base64 stringEmbed in HTML reports
OutputType.BYTESbyte[]Direct manipulation

Related: WebDriver

Advanced Locator Strategies

CSS Selector (Advanced)

Locator Strategy

Purpose: CSS Selectors provide fast, readable, and powerful element location. 2-3x faster than XPath and preferred for most scenarios.

PatternCSS SyntaxExample
ID#id#username
Class.class.btn-primary
Tagtaginput
Attribute[attribute='value'][type='email']
Contains[attribute*='value'][class*='submit']
Starts with[attribute^='value'][id^='user']
Ends with[attribute$='value'][id$='name']
Childparent > childdiv > input
Descendantancestor descendantform input
nth-child:nth-child(n)li:nth-child(2)
First child:first-childli:first-child
Last child:last-childli:last-child
Java - CSS Selector Examples
// 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"));
💡 Real-World Examples:
Java - Production Patterns
// 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)"));
💡 CSS Best Practices:
  • 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 Strategy

Purpose: 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.

TypeXPath SyntaxExample
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]
Java - XPath Examples
// 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]"));
💡 Advanced XPath Patterns:
Java - Complex XPath
// 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']"));
⚠️ XPath Best Practices:
  • ❌ 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 Timeout

Purpose: Sets a global timeout for all findElement() calls. WebDriver polls the DOM for the specified duration before throwing NoSuchElementException.

Syntax
Timeouts implicitlyWait(Duration duration)
Java - Examples
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));
⚠️ Implicit Wait Limitations:
  • 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
💡 Recommendation: Use Explicit Waits (WebDriverWait) instead of Implicit Waits in production frameworks. Explicit Waits provide better control, specific conditions, and don't conflict with other waits.

Related: WebDriverWait,FluentWait

pageLoadTimeout()

Navigation Timeout

Purpose: Sets the maximum time to wait for a page to load completely. Throws TimeoutException if page doesn't load within specified duration.

Java - Usage
// 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
}
💡 Best Practice: Set page load timeout in your setup method to prevent tests from hanging indefinitely on slow-loading pages.

Related: get(),scriptTimeout()

scriptTimeout()

Script Timeout

Purpose: Sets timeout for asynchronous JavaScript execution viaexecuteAsyncScript().

Java - Usage
// 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 4

Purpose: Locate elements based on their spatial relationship to other elements. Useful when traditional locators are unreliable.

Java - Relative Locators
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));
💡 Real-World Example:
Java - Form Field Selection
// 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 4

Purpose: Direct access to Chrome DevTools Protocol for advanced browser operations like network interception, performance metrics, console logs, and more.

Java - CDP Examples
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<>()
);
💡 Use Cases:
  • 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

🎯 Essential Keywords You Must Master:
  • 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)
💡 Interview Preparation Tips:
  • 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

Continue Learning