Selenium

A practical introduction to Selenium: what it is, why you’d use it, how Selenium IDE works, and how to move from recorded tests to code-driven WebDriver automation.

Selenium

What is Selenium?

Selenium is a web automation framework that provides a unified API for controlling browsers. In practice, that means you can drive a browser the way a user would (click, type, navigate) and use that to automate workflows and run end-to-end tests.

Selenium has a few parts that are worth separating:

  • Selenium IDE: record/replay flows (great for learning and quick prototypes)
  • Selenium WebDriver: the workhorse for code-driven automation
  • Browser drivers: glue that lets WebDriver control Chrome/Firefox/etc.

This post was originally written in 2015 (Selenium 2.x era), but the core ideas still hold: record when you’re learning, then move to code when you need maintainability.

Why you’d use it

Regression testing hurts. The goal is to stop breaking what already works.

Selenium helps by making it possible to:

  • Automate repetitive manual testing
  • Catch “small” UI regressions before they ship
  • Test cross-browser behavior (especially useful when customers are on varied setups)

Getting started with Selenium IDE

Selenium IDE is the easiest on-ramp. It behaves like a macro recorder: you interact with the browser, and it captures actions as commands.

When it opens, you’ll see:

  • A command table: each recorded step (click, type, assert, etc.)
  • A source view: the underlying script language (historically “Selenese”)

Helpful concept: tests are made up of commands, locators (selectors), and values.

  • Locators: how Selenium finds elements on the page (overview)
  • Assert vs verify: both are used to check expectations; assert typically fails fast (discussion)

Moving from recorded tests to code (WebDriver)

Once you outgrow record/replay, WebDriver gives you a maintainable way to automate browsers in code.

Here’s a simple example in C# (roughly what I was doing with Visual Studio + NuGet at the time):

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
 
public class Program
{
  public static void Main(string[] args)
  {
    IWebDriver driver = new FirefoxDriver();
    driver.Url = "https://www.google.com";
 
    var searchBox = driver.FindElement(By.Name("q"));
    searchBox.SendKeys("Hello World");
    searchBox.Submit();
 
    // ... continue automation ...
  }
}

Choosing elements reliably

Element selection is where a lot of tests become fragile. A few practical tips:

  • Prefer stable IDs / data attributes (e.g. data-testid) when you control the app.
  • CSS selectors are usually easier to maintain than long XPath expressions.
  • Browser devtools can often “copy selector” for you, but treat generated selectors with suspicion.

Waiting: implicit vs explicit waits (important)

Tests often fail because an element exists eventually, not immediately. There are two broad approaches:

  • Implicit waits: global polling behavior (easy, but can hide timing problems)
  • Explicit waits: wait for a specific condition (usually the better default)

Example explicit wait in C#:

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
 
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
var element = wait.Until(d =>
{
  var candidates = d.FindElements(By.ClassName("qs"));
  return candidates.Count > 0 ? candidates[0] : null;
});

Selenium Server + Grid (remote execution)

Selenium can also run remotely via Selenium Server, which is useful when you want to run tests on:

  • Another OS (Windows/Linux/macOS)
  • Another browser/version combination
  • Another machine (CI/CD, shared test infra)

High-level modes:

  • Local: WebDriver talks directly to a local browser
  • Server: WebDriver talks to a remote Selenium server over HTTP
  • Grid: a hub/node model for distributing tests across machines

Starting a standalone server (2015-era JAR shown as an example):

java -jar selenium-standalone-2.45.0.jar -port 4444

Grid hub:

java -jar selenium-standalone-2.45.0.jar -role hub -port 4444

Grid node:

java -jar selenium-standalone-2.45.0.jar -role node -hub http://localhost:4444/grid/register

Further reading