Selenium Test Scripts: Practical How-To Guide
This guide walks you through writing reliable Selenium test scripts from scratch. You’ll learn how to set up your environment, locate elements, write test logic, handle waits, and structure your tests for maintainability. By the end, you’ll have a working example you can adapt to your own web application.
What You’ll Need
- A code editor (VS Code, IntelliJ, or similar)
- Java Development Kit (JDK) 8 or higher (if using Java)
- Maven or Gradle for dependency management (or download Selenium jars manually)
- WebDriver for your browser (ChromeDriver for Chrome, GeckoDriver for Firefox)
- Basic knowledge of programming (variables, functions, loops)
- Familiarity with HTML/CSS selectors (id, class, XPath)
Step-by-Step
- Set up a new project. Create a Maven project in your IDE. Add the Selenium Java dependency to your
pom.xml:<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.21.0</version> </dependency>
If you’re using Python, install selenium via pip:
pip install selenium. - Download the WebDriver. Go to the official site for your browser driver (ChromeDriver for Chrome, GeckoDriver for Firefox). Download the version that matches your browser’s version. Place it in a known folder or add it to your PATH.
- Write a basic test script. Create a new Java class (e.g.,
FirstTest.java). Start with the WebDriver setup:import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class FirstTest { public static void main(String[] args) { System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver"); WebDriver driver = new ChromeDriver(); driver.get("https://example.com"); System.out.println("Title: " + driver.getTitle()); driver.quit(); } }Run it. If the browser opens and prints the title, your setup works.
- Locate elements. Use the
findElementmethod with a locator. Common strategies:By.id(),By.name(),By.className(),By.cssSelector(),By.xpath(). Prefer IDs and CSS selectors over XPath for speed and readability. Example:WebElement searchBox = driver.findElement(By.name("q")); searchBox.sendKeys("Selenium"); searchBox.submit(); - Add assertions. Use TestNG or JUnit to verify expected outcomes. With TestNG:
import org.testng.Assert; import org.testng.annotations.Test; public class SearchTest { @Test public void testSearch() { WebDriver driver = new ChromeDriver(); driver.get("https://www.google.com"); WebElement searchBox = driver.findElement(By.name("q")); searchBox.sendKeys("Selenium"); searchBox.submit(); Assert.assertTrue(driver.getTitle().contains("Selenium")); driver.quit(); } } - Handle waits. Replace
Thread.sleep()with explicit waits. UseWebDriverWaitto wait for an element to be clickable or visible:WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit"))); button.click();This makes tests more reliable and faster.
- Organize test structure. Use Page Object Model (POM) to separate page logic from test logic. Create a class for each page:
public class LoginPage { WebDriver driver; By username = By.id("username"); By password = By.id("password"); By loginBtn = By.id("login"); public LoginPage(WebDriver driver) { this.driver = driver; } public void login(String user, String pass) { driver.findElement(username).sendKeys(user); driver.findElement(password).sendKeys(pass); driver.findElement(loginBtn).click(); } }Then in your test, instantiate the page object and call its methods.
- Run tests in CI. Integrate with Maven Surefire and a CI tool like Jenkins. Add the TestNG plugin to your
pom.xmland runmvn test.
Common Mistakes
- Using Thread.sleep() – slows tests and causes flakiness. Use explicit waits.
- Hardcoding paths – use relative paths or a config file.
- Not cleaning up – always call
driver.quit()in afinallyblock or use@AfterMethod. - Ignoring element visibility – an element may exist but be hidden; use
isDisplayed()before interacting. - Overusing XPath – XPath is slow and brittle. Prefer IDs and CSS selectors.
- Not handling pop-ups or new tabs – use
driver.getWindowHandles()to switch windows.
Tips
- Use data-driven tests: read test data from Excel or CSV files.
- Run tests in headless mode for CI:
ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); - Take screenshots on failure:
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); - Keep tests independent – each test should not depend on another’s state.
- Use descriptive test names that explain the expected behavior.
Troubleshooting
Browser doesn’t start: Check that the WebDriver path is correct and the driver version matches your browser. Also ensure the browser is installed in the default location.
Element not found: Verify the locator is unique. Use your browser’s DevTools to inspect the element. Try a different locator strategy (e.g., CSS instead of XPath). Also check if the element is inside an iframe – switch to it first.
Stale element reference: This happens when the page refreshes after you find the element. Re-find the element after the refresh.
Tests are flaky: Increase wait times, but prefer explicit waits over fixed sleeps. Ensure your tests don’t depend on network speed.
Permission errors with driver: On Linux/Mac, make the driver executable: chmod +x chromedriver.
Frequently Asked Questions
Can I use Selenium with Python instead of Java?
Yes, Selenium supports multiple languages including Python, C#, and JavaScript. The concepts are the same; only the syntax differs.
How do I handle dynamic elements that change IDs?
Use relative XPath or CSS selectors that rely on stable attributes like class or text. You can also use contains() in XPath: //button[contains(@id, 'submit')].
What’s the difference between findElement and findElements?
findElement returns the first matching element and throws an exception if none is found. findElements returns a list of all matching elements, which is empty if none are found.
How do I test file uploads?
Use sendKeys() on the file input element with the absolute file path. Do not click the upload button; just send the path.
Can I run Selenium tests in parallel?
Yes, use TestNG’s @Test(threadPoolSize = 3) or Selenium Grid to distribute tests across multiple machines or browsers.
How do I wait for a page to load completely?
Use driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30)) or wait for a specific element that indicates the page is ready.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.