Selenium Basics

Core browser automation concepts, locator strategies, synchronization, interaction patterns, and practical Selenium Java examples using a dedicated practice site.

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");
   }
}

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 site

Each 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();