On this page7 sections
CommandsIntermediate6-8 min reference

Selenium Commands

A working reference for WebDriver across Java, Python, and JavaScript. Selenium's API is intentionally consistent across languages — once you know the surface, switching stacks is mostly syntax.

Setup

Java

pom.xml dependency:

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
  <version>4.21.0</version>
</dependency>

Driver initialisation (Selenium 4+ — WebDriverManager no longer required for modern versions):

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.edge.EdgeDriver;
 
WebDriver driver = new ChromeDriver();        // Chrome
// WebDriver driver = new FirefoxDriver();    // Firefox
// WebDriver driver = new EdgeDriver();       // Edge
 
driver.get("https://example.com");
// ... your test steps
driver.quit();

Python

pip install selenium
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.firefox.service import Service as FirefoxService
 
driver = webdriver.Chrome()                   # Chrome
# driver = webdriver.Firefox()                # Firefox
# driver = webdriver.Edge()                   # Edge
 
driver.get("https://example.com")
# ... your test steps
driver.quit()

JavaScript (Node.js)

npm install selenium-webdriver
const { Builder } = require('selenium-webdriver');
 
const driver = await new Builder().forBrowser('chrome').build();
// .forBrowser('firefox') / .forBrowser('MicrosoftEdge')
 
await driver.get('https://example.com');
// ... your test steps
await driver.quit();

Headless and common options

// Java
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new", "--window-size=1280,800", "--disable-gpu");
WebDriver driver = new ChromeDriver(options);
# Python
from selenium.webdriver.chrome.options import Options
 
options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1280,800")
driver = webdriver.Chrome(options=options)

Locators

Selenium uses By strategies. Same names across languages.

By.id()

driver.findElement(By.id("submit")).click();
from selenium.webdriver.common.by import By
 
driver.find_element(By.ID, "submit").click()

By.name()

driver.findElement(By.name("email")).sendKeys("jane@example.com");
driver.find_element(By.NAME, "email").send_keys("jane@example.com")

By.className()

driver.findElement(By.className("btn-primary")).click();
driver.find_element(By.CLASS_NAME, "btn-primary").click()

By.cssSelector()

The most flexible default — matches CSS the rest of the web uses.

driver.findElement(By.cssSelector("[data-testid='login-submit']")).click();
driver.findElement(By.cssSelector("form#signup input[type='email']")).sendKeys("jane@example.com");
driver.find_element(By.CSS_SELECTOR, "[data-testid='login-submit']").click()
driver.find_element(By.CSS_SELECTOR, "form#signup input[type='email']").send_keys("jane@example.com")

By.xpath()

Reach for XPath when CSS can't express what you need (text matching, axes, parent traversal).

driver.findElement(By.xpath("//button[text()='Submit']")).click();
driver.findElement(By.xpath("//label[text()='Email']/following-sibling::input")).sendKeys("jane@example.com");
driver.find_element(By.XPATH, "//button[text()='Submit']").click()
driver.find_element(By.XPATH, "//label[text()='Email']/following-sibling::input").send_keys("jane@example.com")

By.linkText() / By.partialLinkText()

driver.findElement(By.linkText("Sign up")).click();
driver.findElement(By.partialLinkText("Forgot")).click();
driver.find_element(By.LINK_TEXT, "Sign up").click()
driver.find_element(By.PARTIAL_LINK_TEXT, "Forgot").click()

Finding multiple elements

List<WebElement> rows = driver.findElements(By.cssSelector("table tr"));
rows = driver.find_elements(By.CSS_SELECTOR, "table tr")

Actions

click()

driver.findElement(By.id("submit")).click();
driver.find_element(By.ID, "submit").click()

sendKeys() (send_keys in Python)

WebElement email = driver.findElement(By.id("email"));
email.sendKeys("jane@example.com");
email.sendKeys(Keys.TAB);
email.sendKeys(Keys.chord(Keys.CONTROL, "a"));
from selenium.webdriver.common.keys import Keys
 
email = driver.find_element(By.ID, "email")
email.send_keys("jane@example.com")
email.send_keys(Keys.TAB)
email.send_keys(Keys.CONTROL, "a")

clear()

Empty the field. Note: clear doesn't fire input events on every framework — for React/Vue inputs, fall back to Ctrl+A + Delete.

driver.findElement(By.id("email")).clear();
driver.find_element(By.ID, "email").clear()

submit()

Submit the form containing the element. Equivalent to pressing Enter on a form input.

driver.findElement(By.id("login-form")).submit();
driver.find_element(By.ID, "login-form").submit()

Mouse and keyboard via Actions

import org.openqa.selenium.interactions.Actions;
 
Actions actions = new Actions(driver);
actions
  .moveToElement(driver.findElement(By.id("menu")))
  .click(driver.findElement(By.id("submenu-item")))
  .perform();
 
// Drag and drop
actions.dragAndDrop(source, target).perform();
from selenium.webdriver.common.action_chains import ActionChains
 
actions = ActionChains(driver)
actions \
    .move_to_element(driver.find_element(By.ID, "menu")) \
    .click(driver.find_element(By.ID, "submenu-item")) \
    .perform()
 
actions.drag_and_drop(source, target).perform()

Waits

The single biggest source of Selenium flake is missing waits. Use explicit waits — implicit is a footgun.

Implicit wait (avoid mixing with explicit)

Sets a default poll for every findElement call.

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.implicitly_wait(5)

Don't combine implicit and explicit waits in the same suite — interactions between them produce unpredictable timeouts.

Explicit wait — WebDriverWait + ExpectedConditions

import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
 
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
 
WebElement btn = wait.until(
    ExpectedConditions.elementToBeClickable(By.id("submit"))
);
btn.click();
 
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".dashboard")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector(".spinner")));
wait.until(ExpectedConditions.urlContains("/dashboard"));
wait.until(ExpectedConditions.titleIs("Dashboard"));
wait.until(ExpectedConditions.textToBePresentInElementLocated(
    By.id("status"), "Ready"
));
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
 
wait = WebDriverWait(driver, 10)
 
btn = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
btn.click()
 
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".dashboard")))
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".spinner")))
wait.until(EC.url_contains("/dashboard"))
wait.until(EC.title_is("Dashboard"))
wait.until(EC.text_to_be_present_in_element((By.ID, "status"), "Ready"))

Custom condition

wait.until(d -> d.findElements(By.cssSelector(".row")).size() == 5);
wait.until(lambda d: len(d.find_elements(By.CSS_SELECTOR, ".row")) == 5)

get() and navigate()

driver.get("https://example.com/login");
 
driver.navigate().to("https://example.com/dashboard");
driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();
 
String currentUrl = driver.getCurrentUrl();
String title = driver.getTitle();
driver.get("https://example.com/login")
 
driver.back()
driver.forward()
driver.refresh()
 
current_url = driver.current_url
title = driver.title

Assertions

Selenium itself doesn't ship assertions — you pair it with TestNG, JUnit, or pytest.

TestNG (Java)

import org.testng.annotations.Test;
import static org.testng.Assert.*;
 
@Test
public void loginRedirectsToDashboard() {
    driver.get("https://example.com/login");
    driver.findElement(By.id("email")).sendKeys("jane@example.com");
    driver.findElement(By.id("password")).sendKeys("Secret!23");
    driver.findElement(By.id("submit")).click();
 
    new WebDriverWait(driver, Duration.ofSeconds(10))
        .until(ExpectedConditions.urlContains("/dashboard"));
 
    assertEquals(driver.getCurrentUrl(), "https://example.com/dashboard");
    assertTrue(driver.findElement(By.cssSelector("h1")).getText().contains("Welcome"));
}

JUnit 5 (Java)

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
 
@Test
void loginRedirectsToDashboard() {
    // ... same body, just different assertion library
    assertTrue(driver.getCurrentUrl().contains("/dashboard"));
}

pytest (Python)

def test_login_redirects_to_dashboard(driver, wait):
    driver.get("https://example.com/login")
    driver.find_element(By.ID, "email").send_keys("jane@example.com")
    driver.find_element(By.ID, "password").send_keys("Secret!23")
    driver.find_element(By.ID, "submit").click()
 
    wait.until(EC.url_contains("/dashboard"))
 
    assert driver.current_url == "https://example.com/dashboard"
    assert "Welcome" in driver.find_element(By.CSS_SELECTOR, "h1").text

Soft assertions (TestNG)

Collect failures across a test run and report them all at the end.

import org.testng.asserts.SoftAssert;
 
SoftAssert soft = new SoftAssert();
soft.assertEquals(driver.getTitle(), "Dashboard");
soft.assertTrue(driver.findElement(By.id("user")).isDisplayed());
soft.assertAll();   // call this last — fails the test if any assertion failed

Window handling

Switching between windows / tabs

String original = driver.getWindowHandle();
 
driver.findElement(By.linkText("Open in new tab")).click();
 
for (String handle : driver.getWindowHandles()) {
    if (!handle.equals(original)) {
        driver.switchTo().window(handle);
        break;
    }
}
 
// ... interact with the new window
driver.close();                       // close current window
driver.switchTo().window(original);   // back to original
original = driver.current_window_handle
 
driver.find_element(By.LINK_TEXT, "Open in new tab").click()
 
for handle in driver.window_handles:
    if handle != original:
        driver.switch_to.window(handle)
        break
 
driver.close()
driver.switch_to.window(original)

Switching to iframes

driver.switchTo().frame("iframe-name");
driver.switchTo().frame(0);                        // by index
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe.embed")));
 
// ... interact inside the frame
 
driver.switchTo().defaultContent();                // back to top-level page
driver.switchTo().parentFrame();                   // up one level
driver.switch_to.frame("iframe-name")
driver.switch_to.frame(0)
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe.embed"))
 
driver.switch_to.default_content()
driver.switch_to.parent_frame()

Handling alerts

import org.openqa.selenium.Alert;
 
driver.findElement(By.id("delete")).click();
Alert alert = driver.switchTo().alert();
String text = alert.getText();
alert.accept();                       // OK
// alert.dismiss();                   // Cancel
// alert.sendKeys("input value");     // for prompt() dialogs
driver.find_element(By.ID, "delete").click()
alert = driver.switch_to.alert
text = alert.text
alert.accept()
# alert.dismiss()
# alert.send_keys("input value")

For modern web apps, native alerts are rare — most "alerts" are custom modals. Treat those as regular DOM elements with locators.