Architecture
Selenium works as a command chain between your Java code and the browser. Your test does not talk directly to Chrome or Edge. It sends commands through WebDriver, the driver translates them, and the browser executes them.
You (Test Script) -> WebDriver -> JSON Wire Protocol -> Browser Driver -> Browser
A simple mental model is a courier flow: the test creates the instruction, WebDriver passes it forward, and the browser driver delivers it in the format the browser understands.
Locators
Locator quality determines how stable the test is. Prefer IDs and simple CSS when available. Use XPath when relationships in the DOM are more stable than direct attributes.
XPath traversal
//tbody/tr[2]/following-sibling::tr //tbody/tr[2]/preceding::td //header/div/button[1]/following-sibling::button[1] //form/div/input[@name='name']/preceding-sibling::label //*[text()='Ann']/following-sibling::td[@id='jillAge'] //header/div/button[1]/parent::div/parent::header/a[0]
Use sibling traversal when nearby labels or buttons are easier to anchor than the target itself. Use parent traversal when the child is easy to find but the useful ancestor is the real target.
CSS selectors
css=input#email css=input.text .cart-header-navlink div.container input#username form h2
In browser developer tools, XPath and CSS can be checked quickly before they go into code.
$x("//a[text()='Courses']")
$(".link")
Shadow DOM
Shadow DOM elements live behind a shadow boundary, so standard DOM traversal is not always enough. Older examples often use helper libraries; modern Selenium also supports native shadow access on supported browsers.
<dependency> <groupId>io.github.sukgu</groupId> <artifactId>automation</artifactId> <version>0.1.5</version> </dependency>
public class Z_ShadowDOM_Demo {
public static WebDriver driver;
public static void iShadow() {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("https://books-pwakit.appspot.com/");
Shadow shadow = new Shadow(driver);
WebElement element = shadow.findElementByXPath("//input[@id='input']");
element.sendKeys("do it work");
}
}
Selections
Dropdown behavior varies. Some controls are standard HTML selects, some are custom lists, and some are auto-suggest fields driven by JavaScript.
Increment and passenger selection
driver.findElement(By.id("divpaxinfo")).click();
for (int i = 0; i <= 4; i++) {
driver.findElement(By.id("hrefIncAdt")).click();
}
Dynamic dropdowns
driver.findElement(By.id("ctl00_mainContent_ddl_originStation1_CTXT")).click();
driver.findElement(By.xpath("//a[@value='BLR']")).click();
Thread.sleep(5000);
driver.findElement(By.xpath("(//a[@value='MAA'])[2]")).click();
Where duplicate values exist, avoid index-heavy XPath if a stable container is available.
driver.findElement(By.xpath("//div[@id='ctl00_mainContent_ddl_destinationStation1_CTNR']//a[@value='MAA']")).click();
Auto-suggest
driver.findElement(By.id("autosuggest")).click();
driver.findElement(By.id("autosuggest")).sendKeys("IND");
for (int i = 0; i < 3; i++) {
driver.findElement(By.id("autosuggest")).sendKeys(Keys.DOWN);
}
driver.findElement(By.id("autosuggest")).sendKeys(Keys.ENTER);
Waits
Synchronization is what separates a script that sometimes works from a test that can survive real page timing. Implicit waits apply broadly. Explicit waits target a specific state such as visibility or clickability.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Conditions of Use")));
For shared test code, a reusable wait utility is usually cleaner than repeating wait creation in every test.
public class WaitUtils {
public static WebElement mywaitforclickable(WebDriver driver, By locator, int timeunitinSeconds) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(timeunitinSeconds));
return wait.until(ExpectedConditions.elementToBeClickable(locator));
}
}
Actions
Mouse and keyboard interactions are handled through the Actions API. This becomes useful for hover states, modified key input, drag-and-drop, and custom widgets.
Complete example: uppercase search
public class M_SearchWithUpperCase {
public static WebDriver driver;
public static void SearchWithUpperCase() {
driver = new ChromeDriver();
driver.get("https://www.amazon.in/");
WebElement searchBox = WaitUtils.ElementClickable(
driver,
By.xpath("//input[@id='twotabsearchtextbox']"),
10
);
Actions act = new Actions(driver);
act.moveToElement(searchBox)
.click()
.keyDown(Keys.SHIFT)
.sendKeys("the wolf")
.build()
.perform();
}
public static void main(String[] args) {
SearchWithUpperCase();
}
}
Complete example: window switching
public static void WindowSwitch() {
driver = new ChromeDriver();
driver.get("https://rahulshettyacademy.com/loginpagePractise/");
driver.manage().window().maximize();
WebElement blinkingLink = driver.findElement(By.xpath("//a[@class='blinkingText']"));
blinkingLink.click();
Set<String> windowIds = driver.getWindowHandles();
Iterator<String> itr = windowIds.iterator();
String parentWindow = itr.next();
String childWindow = itr.next();
driver.switchTo().window(childWindow);
String myemailid = driver.findElement(
By.xpath("//a[normalize-space()='mentor@rahulshettyacademy.com']")
).getText();
driver.switchTo().window(parentWindow);
WebElement userIdBox = driver.findElement(By.xpath("//input[@id='username']"));
userIdBox.click();
userIdBox.sendKeys(myemailid);
}
Date Handling
Date controls can be handled either by interacting with the visible calendar widget or by sending values directly when the input allows it.
Complete example: specific date selection
package s1_SeleniumBasics;
import Utils.WaitUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class O_CalenderSpecific {
public static WebDriver driver;
public static void CalenderSpecific() throws InterruptedException {
driver = new ChromeDriver();
driver.get("https://www.tutorialspoint.com/selenium/practice/date-picker.php");
driver.manage().window().maximize();
WebElement cal_icon = driver.findElement(By.xpath("//input[@id='datetimepicker1']"));
cal_icon.click();
WebElement year = WaitUtils.ElementClickable(driver, By.cssSelector(".numInput"), 10);
year.clear();
year.sendKeys("1989");
WebElement monthDropdown = driver.findElement(By.xpath("//select[@aria-label='Month']"));
monthDropdown.click();
monthDropdown.sendKeys("October");
monthDropdown.sendKeys(Keys.ENTER);
String date = "20";
WebElement Date = driver.findElement(By.xpath("//span[text()='" + date + "']"));
Date.click();
}
public static void main(String[] args) throws InterruptedException {
CalenderSpecific();
}
}
Complete example: default highlighted date
package s1_SeleniumBasics;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class E_DefaultCalenderDate {
public static WebDriver driver;
public static void Cal_auto_date() throws InterruptedException {
driver = new ChromeDriver();
driver.get("https://rahulshettyacademy.com/dropdownsPractise/");
driver.findElement(By.id("ctl00_mainContent_ddl_originStation1_CTXT")).click();
driver.findElement(By.xpath("//a[@value='BLR']")).click();
Thread.sleep(5000);
driver.findElement(
By.xpath("//div[@id='ctl00_mainContent_ddl_destinationStation1_CTNR']//a[@value='MAA']")
).click();
driver.findElement(By.cssSelector(".ui-state-default.ui-state-highlight")).click();
}
public static void main(String[] args) throws InterruptedException {
Cal_auto_date();
}
}
JavaScript
JavaScriptExecutor is useful when a standard Selenium action is blocked by overlays, custom components, or hidden interaction layers.
Complete example: send value using JavaScript
package s1_SeleniumBasics;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class U_JavaScript_Demo {
public static WebDriver driver;
public static void sendKeys_usingJSE() {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("https://rahulshettyacademy.com/seleniumPractise/#/");
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("document.getElementsByClassName('search-keyword')[0].value='Cucumber';");
jse.executeScript("document.getElementById('email').value='wasim1065@gmail.com';");
jse.executeScript("window.scrollBy(0,1000)");
jse.executeScript("return document.readyState");
}
public static void main(String[] args) {
sendKeys_usingJSE();
}
}
Direct click fallback
JavascriptExecutor js2 = (JavascriptExecutor) driver;
js2.executeScript("arguments[0].click();", closebtn);
Screenshots
Screenshots help when a test fails in CI or when you want evidence of the browser state after a specific step.
Complete example: capture after adding product
package s1_SeleniumBasics;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class P_ScreenShot {
public static WebDriver driver;
public static void myss() throws InterruptedException, IOException {
driver = new ChromeDriver();
driver.get("https://rahulshettyacademy.com/seleniumPractise/");
List<WebElement> allproducts = driver.findElements(By.cssSelector("h4.product-name"));
for (int i = 0; i < allproducts.size(); i++) {
String myproduct = allproducts.get(i).getText();
if (myproduct.contains("Cucumber")) {
driver.findElement(By.xpath("//div[3]//div[3]//button[1]")).click();
break;
}
}
File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
File destFile = new File("src/main/java/Utils/myss.png");
FileUtils.copyFile(srcFile, destFile);
}
public static void main(String[] args) throws InterruptedException, IOException {
myss();
}
}
Tables
Tables can be automated at two levels: row iteration for broad validation, or direct cell targeting for a specific value check.
Complete example: iterate rows and columns
package s1_SeleniumBasics;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class Q_ListinAutomation {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://rahulshettyacademy.com/seleniumPractise/#/offers");
List<WebElement> tablerows = driver.findElements(By.cssSelector("tr"));
for (WebElement iter : tablerows) {
List<WebElement> column = iter.findElements(By.xpath("td"));
String get_value = column.get(2).getText();
System.out.println(get_value);
}
}
}
Complete example: target one cell
public class TableHand {
public static WebDriver driver;
public static void Table_me() throws InterruptedException {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("https://rahulshettyacademy.com/seleniumPractise/#/offers");
WebElement FifthRowSecondElement = driver.findElement(By.xpath("//table/tbody/tr[5]/td[2]"));
String s = FifthRowSecondElement.getText();
System.out.println(s);
}
public static void main(String[] args) throws InterruptedException {
Table_me();
}
}
Automation Strategy
UI automation should target stable, business-relevant workflows. Repeated paths, critical user journeys, and complex regression areas are good candidates. Low-value, short-lived, or highly subjective checks are usually poor candidates.
Framework choice should follow the surface you are testing. Use Selenium for browser workflows, API tools for service-level validation, and shared utilities for synchronization and reuse.
Selenium Java Practice Programs (30 Sections)
Open practice siteEach section below uses the shared BaseTest that creates the driver, opens the practice site, and quits the browser after every test. The snippets show the exact body that goes inside the test method for that section.
Base Class
package base;
import org.junit.After;
import org.junit.Before;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
public class BaseTest {
protected WebDriver driver;
@Before
public void setup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts()
.implicitlyWait(Duration.ofSeconds(10));
driver.get("https://www.sreenidhirajakrishnan.com/practice");
}
@After
public void tearDown() {
driver.quit();
}
}
Section 1 — Basic Form Elements
driver.findElement(By.id("text-input")).sendKeys("Wasim");
driver.findElement(By.id("password-input")).sendKeys("1234");
driver.findElement(By.id("email-input")).sendKeys("test@gmail.com");
driver.findElement(By.id("phone-input")).sendKeys("9999999999");
driver.findElement(By.id("textarea-input")).sendKeys("QA Engineer");
driver.findElement(By.id("form-submit")).click();
Section 2 — Button Interactions
driver.findElement(By.id("single-click-btn")).click();
new Actions(driver).doubleClick(driver.findElement(By.id("double-click-btn"))).perform();
new Actions(driver).contextClick(driver.findElement(By.id("right-click-btn"))).perform();
driver.findElement(By.id("start-delay-btn")).click();
Section 3 — Checkboxes & Radio Buttons
driver.findElement(By.id("select-all")).click();
driver.findElement(By.id("radio-1")).click();
Section 4 — Dropdowns
new Select(driver.findElement(By.id("standard-select"))).selectByVisibleText("Red");
Select multi = new Select(driver.findElement(By.id("multi-select")));
multi.selectByVisibleText("Java");
multi.selectByVisibleText("Python");
Section 5 — Locator Practice
driver.findElement(By.id("locator-by-id"));
driver.findElement(By.className("locator-by-class"));
driver.findElement(By.name("locator-name"));
driver.findElement(By.xpath("//span[text()='ExactTextTarget']"));
Section 6 — Dynamic Content
driver.findElement(By.id("change-text-btn")).click();
driver.findElement(By.id("increment-btn")).click();
driver.findElement(By.id("load-content-btn")).click();
Section 7 — Waits & Synchronisation
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//p[text()='Loaded']")));
driver.findElement(By.id("ajax-btn")).click();
Section 8 — Table Automation
List<WebElement> rows = driver.findElements(By.xpath("//table[@id='practice-table']//tr"));
for (WebElement row : rows) {
System.out.println(row.getText());
}
Section 9 — Alerts
driver.findElement(By.id("alert-btn")).click();
driver.switchTo().alert().accept();
driver.findElement(By.id("confirm-btn")).click();
driver.switchTo().alert().dismiss();
Section 10 — Modals
driver.findElement(By.id("open-modal-btn")).click();
Section 11 — iFrame
driver.switchTo().frame(0);
driver.findElement(By.tagName("input")).sendKeys("Inside Frame");
driver.switchTo().defaultContent();
Section 12 — Shadow DOM
WebElement host = driver.findElement(By.cssSelector("practice-shadow-box"));
SearchContext shadow = host.getShadowRoot();
shadow.findElement(By.cssSelector("#shadow-input")).sendKeys("Hello");
shadow.findElement(By.cssSelector("#shadow-btn")).click();
Section 13 — Drag & Drop
WebElement source = driver.findElement(By.id("drag-source"));
WebElement target = driver.findElement(By.id("drop-zone"));
new Actions(driver).dragAndDrop(source, target).perform();
Section 14 — Hover Menu
new Actions(driver).moveToElement(driver.findElement(By.id("hover-menu-trigger"))).perform();
Section 15 — Tooltip
new Actions(driver).moveToElement(driver.findElement(By.id("tooltip-trigger"))).perform();
Section 16 — File Upload
driver.findElement(By.id("file-upload")).sendKeys("C:\\test.txt");
Section 17 — Download
driver.findElement(By.id("download-btn")).click();
Section 18 — Hidden Elements
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", driver.findElement(By.id("css-hidden-btn")));
Section 19 — Scroll Testing
WebElement element = driver.findElement(By.id("scroll-target"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", element);
Section 20 — Multiple Windows
driver.findElement(By.id("open-window-btn")).click();
for (String win : driver.getWindowHandles()) {
driver.switchTo().window(win);
}
Section 21 — Authentication Simulation
driver.findElement(By.id("auth-username")).sendKeys("admin");
driver.findElement(By.id("auth-password")).sendKeys("admin123");
driver.findElement(By.id("auth-login-btn")).click();
Section 22 — Stale Element Simulation
WebElement element = driver.findElement(By.id("stale-target"));
driver.findElement(By.id("stale-refresh-btn")).click();
element = driver.findElement(By.id("stale-target"));
Section 23 — Dynamic List
driver.findElement(By.id("list-input")).sendKeys("Item1");
driver.findElement(By.id("add-item-btn")).click();
Section 24 — Network Delay Simulation
driver.findElement(By.id("delay-btn")).click();
Section 25 — Random Fail (Flaky) Elements
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(By.id("flaky-btn")));
driver.findElement(By.id("flaky-btn")).click();
Section 26 — Keyboard Actions
new Actions(driver)
.sendKeys(Keys.CONTROL + "a")
.sendKeys(Keys.DELETE)
.perform();
Section 27 — Slider
new Actions(driver)
.clickAndHold(driver.findElement(By.id("slider")))
.moveByOffset(50, 0)
.release()
.perform();
Section 28 — Date Picker
driver.findElement(By.id("date-picker")).sendKeys("2026-06-24");
Section 29 — Resizable Element
new Actions(driver)
.clickAndHold(driver.findElement(By.cssSelector(".resize-handle")))
.moveByOffset(50, 50)
.release()
.perform();
Section 30 — Complex DOM Structure
driver.findElement(By.xpath("//div[@id='xpath-grandparent']//span[@id='xpath-leaf']")).getText();