
Selenium with Java Tutorial
Java is the most popular language for Selenium automation. With strong typing, extensive IDE support, and seamless integration with TestNG and Maven, Java provides a robust foundation for enterprise-grade test automation. This tutorial covers everything from initial setup to building maintainable test frameworks.
Whether you're starting fresh or transitioning from another language, this guide will get you writing professional Selenium tests with Java.
Table Of Contents-
Prerequisites and Setup
Required Software
| Software | Version | Purpose |
|---|---|---|
| JDK | 11 or higher | Java runtime |
| Maven | 3.6+ | Dependency management |
| IDE | IntelliJ IDEA or Eclipse | Development environment |
| Browser | Chrome, Firefox, Edge | Test execution |
Install JDK
# Verify Java installation
java -version
javac -version
# Expected output
# java version "17.0.2" 2022-01-18 LTSIf not installed, download from Oracle JDK (opens in a new tab) or use OpenJDK.
Install Maven
# Verify Maven installation
mvn -version
# Expected output
# Apache Maven 3.9.0Configure Environment Variables
# Windows (System Properties > Environment Variables)
JAVA_HOME = C:\Program Files\Java\jdk-17
MAVEN_HOME = C:\Program Files\Apache\maven
# Add to PATH
%JAVA_HOME%\bin
%MAVEN_HOME%\binMaven Project Configuration
Create Maven Project
In IntelliJ IDEA:
- File → New → Project
- Select Maven
- Enter GroupId:
com.yourcompany - Enter ArtifactId:
selenium-tests - Click Create
Configure pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yourcompany</groupId>
<artifactId>selenium-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<selenium.version>4.21.0</selenium.version>
<testng.version>7.9.0</testng.version>
<webdrivermanager.version>5.8.0</webdrivermanager.version>
</properties>
<dependencies>
<!-- Selenium WebDriver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
</dependency>
<!-- WebDriver Manager (auto driver management) -->
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>${webdrivermanager.version}</version>
</dependency>
<!-- TestNG -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>Project Structure
selenium-tests/
├── src/
│ ├── main/
│ │ └── java/
│ │ └── com/yourcompany/
│ │ └── pages/ # Page Objects
│ └── test/
│ └── java/
│ └── com/yourcompany/
│ └── tests/ # Test classes
├── pom.xml
└── testng.xmlYour First Selenium Test
Simple Test Without Framework
package com.yourcompany.tests;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class FirstTest {
public static void main(String[] args) {
// Setup ChromeDriver automatically
WebDriverManager.chromedriver().setup();
// Create driver instance
WebDriver driver = new ChromeDriver();
try {
// Navigate to URL
driver.get("https://www.google.com");
// Find search box and enter text
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys("Selenium WebDriver");
searchBox.submit();
// Print page title
System.out.println("Page title: " + driver.getTitle());
} finally {
// Close browser
driver.quit();
}
}
}Test with TestNG
package com.yourcompany.tests;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class GoogleSearchTest {
private WebDriver driver;
@BeforeClass
public void setupClass() {
WebDriverManager.chromedriver().setup();
}
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
}
@Test
public void testGoogleSearch() {
driver.get("https://www.google.com");
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys("Selenium Java");
searchBox.submit();
Assert.assertTrue(driver.getTitle().contains("Selenium Java"),
"Search results should show Selenium Java");
}
@AfterMethod
public void teardown() {
if (driver != null) {
driver.quit();
}
}
}WebDriver Basics
Creating Driver Instances
// Chrome
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
// Firefox
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new FirefoxDriver();
// Edge
WebDriverManager.edgedriver().setup();
WebDriver driver = new EdgeDriver();Browser Options
// Chrome with options
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless"); // Headless mode
options.addArguments("--disable-gpu");
options.addArguments("--window-size=1920,1080");
options.addArguments("--incognito"); // Incognito mode
options.addArguments("--disable-notifications");
WebDriver driver = new ChromeDriver(options);Navigation Commands
// Navigate to URL
driver.get("https://example.com");
driver.navigate().to("https://example.com");
// Browser navigation
driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();
// Get page info
String title = driver.getTitle();
String url = driver.getCurrentUrl();
String source = driver.getPageSource();Window Management
// Maximize window
driver.manage().window().maximize();
// Set specific size
driver.manage().window().setSize(new Dimension(1920, 1080));
// Full screen
driver.manage().window().fullscreen();Locator Strategies
All Locator Types
// By ID (preferred when available)
driver.findElement(By.id("username"));
// By Name
driver.findElement(By.name("email"));
// By Class Name (single class only)
driver.findElement(By.className("btn-primary"));
// By Tag Name
driver.findElements(By.tagName("input"));
// By Link Text (exact match)
driver.findElement(By.linkText("Sign In"));
// By Partial Link Text
driver.findElement(By.partialLinkText("Sign"));
// By CSS Selector (recommended)
driver.findElement(By.cssSelector("#login-form input[type='email']"));
driver.findElement(By.cssSelector(".btn.btn-primary"));
driver.findElement(By.cssSelector("[data-testid='submit-btn']"));
// By XPath (when CSS can't do it)
driver.findElement(By.xpath("//button[text()='Submit']"));
driver.findElement(By.xpath("//input[@id='email']/../label"));CSS Selector Examples
// By ID
By.cssSelector("#elementId")
// By class
By.cssSelector(".className")
// By attribute
By.cssSelector("[name='email']")
By.cssSelector("input[type='text']")
// Partial attribute match
By.cssSelector("[id*='partial']") // Contains
By.cssSelector("[id^='start']") // Starts with
By.cssSelector("[id$='end']") // Ends with
// Hierarchy
By.cssSelector("form > input") // Direct child
By.cssSelector("form input") // Any descendant
By.cssSelector("label + input") // Adjacent sibling
// nth-child
By.cssSelector("tr:nth-child(2)") // Second row
By.cssSelector("li:first-child")
By.cssSelector("li:last-child")Finding Multiple Elements
// Find all links
List<WebElement> links = driver.findElements(By.tagName("a"));
System.out.println("Found " + links.size() + " links");
// Iterate through elements
for (WebElement link : links) {
System.out.println(link.getText() + " -> " + link.getAttribute("href"));
}
// Find elements within element
WebElement container = driver.findElement(By.id("nav"));
List<WebElement> navLinks = container.findElements(By.tagName("a"));Element Interactions
Basic Interactions
WebElement element = driver.findElement(By.id("username"));
// Click
element.click();
// Type text
element.sendKeys("test@example.com");
// Clear field
element.clear();
// Submit form
element.submit();
// Get text content
String text = element.getText();
// Get attribute value
String value = element.getAttribute("value");
String placeholder = element.getAttribute("placeholder");
// Check element state
boolean displayed = element.isDisplayed();
boolean enabled = element.isEnabled();
boolean selected = element.isSelected();Keyboard Actions
import org.openqa.selenium.Keys;
WebElement input = driver.findElement(By.id("search"));
// Special keys
input.sendKeys(Keys.ENTER);
input.sendKeys(Keys.TAB);
input.sendKeys(Keys.ESCAPE);
// Key combinations
input.sendKeys(Keys.CONTROL + "a"); // Select all
input.sendKeys(Keys.CONTROL + "c"); // Copy
// Clear and type
input.sendKeys(Keys.CONTROL + "a", Keys.DELETE);
input.sendKeys("new text");Dropdown Selection
import org.openqa.selenium.support.ui.Select;
WebElement dropdown = driver.findElement(By.id("country"));
Select select = new Select(dropdown);
// Select by visible text
select.selectByVisibleText("United States");
// Select by value attribute
select.selectByValue("US");
// Select by index (0-based)
select.selectByIndex(2);
// Get selected option
WebElement selected = select.getFirstSelectedOption();
System.out.println("Selected: " + selected.getText());
// Get all options
List<WebElement> options = select.getOptions();
// Multi-select dropdowns
if (select.isMultiple()) {
select.deselectAll();
select.selectByVisibleText("Option 1");
select.selectByVisibleText("Option 2");
}Checkboxes and Radio Buttons
// Checkbox
WebElement checkbox = driver.findElement(By.id("remember-me"));
if (!checkbox.isSelected()) {
checkbox.click();
}
// Radio button
WebElement radio = driver.findElement(By.cssSelector("input[value='option1']"));
radio.click();
// Verify selection
Assert.assertTrue(checkbox.isSelected());Handling Waits
Explicit Wait (Recommended)
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait for element to be visible
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("result"))
);
// Wait for element to be clickable
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
button.click();
// Wait for text to appear
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("status"), "Complete"
)
);
// Wait for element to disappear
wait.until(
ExpectedConditions.invisibilityOfElementLocated(By.id("loader"))
);
// Wait for URL to change
wait.until(ExpectedConditions.urlContains("/dashboard"));Common ExpectedConditions
// Presence (in DOM, may be hidden)
ExpectedConditions.presenceOfElementLocated(locator)
// Visibility (in DOM and visible)
ExpectedConditions.visibilityOfElementLocated(locator)
// Clickable (visible and enabled)
ExpectedConditions.elementToBeClickable(locator)
// Text present
ExpectedConditions.textToBePresentInElement(element, text)
// Attribute value
ExpectedConditions.attributeToBe(locator, attribute, value)
// Frame available
ExpectedConditions.frameToBeAvailableAndSwitchToIt(locator)
// Alert present
ExpectedConditions.alertIsPresent()Fluent Wait
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
Wait<WebDriver> fluentWait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
WebElement element = fluentWait.until(driver ->
driver.findElement(By.id("dynamic-content"))
);TestNG Integration
TestNG Annotations
import org.testng.annotations.*;
public class TestNGExample {
@BeforeSuite
public void beforeSuite() {
// Runs once before entire suite
}
@BeforeClass
public void beforeClass() {
// Runs once before all tests in class
}
@BeforeMethod
public void setUp() {
// Runs before each test method
}
@Test(priority = 1)
public void testLogin() {
// Test method
}
@Test(priority = 2, dependsOnMethods = "testLogin")
public void testDashboard() {
// Runs after testLogin
}
@Test(enabled = false)
public void skippedTest() {
// This test is disabled
}
@AfterMethod
public void tearDown() {
// Runs after each test method
}
@AfterClass
public void afterClass() {
// Runs once after all tests in class
}
@AfterSuite
public void afterSuite() {
// Runs once after entire suite
}
}testng.xml Configuration
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Regression Suite" parallel="methods" thread-count="4">
<test name="Login Tests">
<classes>
<class name="com.yourcompany.tests.LoginTest"/>
</classes>
</test>
<test name="Search Tests">
<parameter name="browser" value="chrome"/>
<classes>
<class name="com.yourcompany.tests.SearchTest"/>
</classes>
</test>
</suite>Parameterized Tests
@Test(dataProvider = "loginData")
public void testLogin(String username, String password, boolean shouldPass) {
loginPage.login(username, password);
if (shouldPass) {
Assert.assertTrue(dashboard.isDisplayed());
} else {
Assert.assertTrue(loginPage.getErrorMessage().isDisplayed());
}
}
@DataProvider(name = "loginData")
public Object[][] getLoginData() {
return new Object[][] {
{"validuser@test.com", "ValidPass123", true},
{"invalid@test.com", "wrong", false},
{"", "password", false},
{"user@test.com", "", false}
};
}Page Object Model
Page Object Class
package com.yourcompany.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class LoginPage {
private WebDriver driver;
private WebDriverWait wait;
// Locators
private By usernameField = By.id("username");
private By passwordField = By.id("password");
private By loginButton = By.id("login-btn");
private By errorMessage = By.className("error-message");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
// Actions
public void enterUsername(String username) {
wait.until(ExpectedConditions.visibilityOfElementLocated(usernameField))
.sendKeys(username);
}
public void enterPassword(String password) {
driver.findElement(passwordField).sendKeys(password);
}
public DashboardPage clickLogin() {
driver.findElement(loginButton).click();
return new DashboardPage(driver);
}
public DashboardPage login(String username, String password) {
enterUsername(username);
enterPassword(password);
return clickLogin();
}
public String getErrorText() {
return wait.until(ExpectedConditions.visibilityOfElementLocated(errorMessage))
.getText();
}
public boolean isLoginPageDisplayed() {
return driver.findElement(usernameField).isDisplayed();
}
}Page Factory (Alternative)
package com.yourcompany.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPageFactory {
private WebDriver driver;
@FindBy(id = "username")
private WebElement usernameField;
@FindBy(id = "password")
private WebElement passwordField;
@FindBy(id = "login-btn")
private WebElement loginButton;
@FindBy(css = ".error-message")
private WebElement errorMessage;
public LoginPageFactory(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void login(String username, String password) {
usernameField.sendKeys(username);
passwordField.sendKeys(password);
loginButton.click();
}
}Test Using Page Objects
package com.yourcompany.tests;
import com.yourcompany.pages.LoginPage;
import com.yourcompany.pages.DashboardPage;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class LoginTest {
private WebDriver driver;
private LoginPage loginPage;
@BeforeMethod
public void setup() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.get("https://example.com/login");
loginPage = new LoginPage(driver);
}
@Test
public void testValidLogin() {
DashboardPage dashboard = loginPage.login("user@test.com", "password123");
Assert.assertTrue(dashboard.isWelcomeMessageDisplayed());
}
@Test
public void testInvalidLogin() {
loginPage.login("invalid@test.com", "wrongpassword");
Assert.assertEquals(loginPage.getErrorText(), "Invalid credentials");
}
@AfterMethod
public void teardown() {
if (driver != null) {
driver.quit();
}
}
}Advanced Techniques
Handling Alerts
import org.openqa.selenium.Alert;
// Wait for alert
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
// Get alert text
String alertText = alert.getText();
// Accept alert (OK)
alert.accept();
// Dismiss alert (Cancel)
alert.dismiss();
// Send text to prompt
alert.sendKeys("Input text");
alert.accept();Handling Frames
// Switch to frame by name or ID
driver.switchTo().frame("frameName");
// Switch to frame by index
driver.switchTo().frame(0);
// Switch to frame by WebElement
WebElement frameElement = driver.findElement(By.cssSelector("iframe.main"));
driver.switchTo().frame(frameElement);
// Switch back to main content
driver.switchTo().defaultContent();
// Switch to parent frame
driver.switchTo().parentFrame();Handling Multiple Windows
// Get current window handle
String mainWindow = driver.getWindowHandle();
// Click link that opens new window
driver.findElement(By.linkText("Open New Window")).click();
// Get all window handles
Set<String> handles = driver.getWindowHandles();
// Switch to new window
for (String handle : handles) {
if (!handle.equals(mainWindow)) {
driver.switchTo().window(handle);
break;
}
}
// Do something in new window
System.out.println("New window title: " + driver.getTitle());
// Close new window and return to main
driver.close();
driver.switchTo().window(mainWindow);JavaScript Execution
JavascriptExecutor js = (JavascriptExecutor) driver;
// Scroll to element
WebElement element = driver.findElement(By.id("footer"));
js.executeScript("arguments[0].scrollIntoView(true);", element);
// Scroll by pixels
js.executeScript("window.scrollBy(0, 500)");
// Click via JavaScript (bypasses overlays)
js.executeScript("arguments[0].click();", element);
// Get computed style
String color = (String) js.executeScript(
"return window.getComputedStyle(arguments[0]).color;", element
);
// Wait for page load
js.executeScript("return document.readyState").equals("complete");Taking Screenshots
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.apache.commons.io.FileUtils;
import java.io.File;
// Take screenshot
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
// Save to file
FileUtils.copyFile(screenshot, new File("screenshots/test-failure.png"));
// Screenshot as Base64 (for reports)
String base64 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64);Best Practices
1. Use WebDriver Manager
// Instead of manually managing drivers
// System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
// Use WebDriver Manager
WebDriverManager.chromedriver().setup();2. Always Clean Up Resources
@AfterMethod(alwaysRun = true)
public void teardown() {
if (driver != null) {
driver.quit();
}
}3. Use Explicit Waits, Not Implicit
// Avoid
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
// Prefer
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(locator));4. Create a Base Test Class
public abstract class BaseTest {
protected WebDriver driver;
protected WebDriverWait wait;
@BeforeMethod
public void baseSetup() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
@AfterMethod(alwaysRun = true)
public void baseTeardown() {
if (driver != null) {
driver.quit();
}
}
}5. Use Meaningful Assertions
// Avoid generic assertions
Assert.assertTrue(element.isDisplayed());
// Use descriptive messages
Assert.assertTrue(element.isDisplayed(),
"Login button should be visible on the page");Test Your Knowledge
Quiz on Selenium with Java
Your Score: 0/10
Question: What is the purpose of WebDriverManager in Selenium Java projects?
Continue Your Selenium Journey
Frequently Asked Questions
Frequently Asked Questions (FAQs) / People Also Ask (PAA)
Which IDE should I use for Selenium with Java?
Should I use TestNG or JUnit for Selenium tests?
What is WebDriver Manager and why should I use it?
How do I handle dynamic elements that take time to load?
What is Page Object Model and why should I use it?
How do I run Selenium tests in headless mode?
Why do I get StaleElementReferenceException?
How do I take screenshots on test failure in TestNG?