Selenium WebDriver Basics
Selenium WebDriver drives real browsers through the W3C WebDriver protocol. Learn the core objects — WebDriver, WebElement and By — and the session lifecycle: start a browser, navigate, interact, verify and clean up.
What is this?
Selenium WebDriver is a browser automation framework that controls real Chrome, Firefox, Edge and Safari instances through the standardized W3C WebDriver protocol. Tests are written in the language of your choice and talk to a browser-specific driver binary (chromedriver, geckodriver) that translates commands into native browser actions. The three core objects are WebDriver (the browser session), WebElement (an element inside the page) and By (the locator strategy used to find elements).
Why do you need it?
- End-to-end tests exercise real user flows through a real browser, catching integration bugs that unit tests miss.
- The W3C WebDriver standard means one API works across browsers, so the same suite can run on Chrome, Firefox and Edge.
- Browser automation verifies the whole stack — frontend, API and database — the way a user experiences it.
- WebDriver exposes browser features (screenshots, navigation history, alerts) that pure HTTP tests cannot reach.
- The same test that runs locally runs in a container or on a remote grid, so CI and local behave identically.
Mental model
A remote-controlled race car
WebDriver driving a browser
You never sit in the car — you send commands from a controller and the car executes them on the track. WebDriver sends JSON commands over the wire and the browser executes them natively, reporting back element state and results.
How it works
- A test creates a WebDriver session for a browser (e.g. ChromeDriver); this launches a real browser instance and returns a session id.
- The test locates elements with By (id, name, CSS selector, XPath, link text) and calls WebDriver and WebElement methods.
- WebDriver serializes each command to JSON and sends it over HTTP to the driver binary, which executes it inside the browser.
- The driver responds with the result — an element reference, a value, or an error — which the test asserts against.
- The session is torn down with quit(), which closes the browser and releases the driver process.
Lifecycle of a WebDriver session from start to teardown.
Key commands
pip install seleniumInstall the Selenium client library for Python.
pip install webdriver-managerInstall a driver auto-downloader so browser driver binaries are fetched and cached for you.
Successfully installed webdriver-manager-4.0.1
chromedriver --versionVerify the ChromeDriver binary is present and matches your installed Chrome version.
ChromeDriver 119.0.6045.105 (398c19657d0b...)
mvn test -Dtest=FirstTestRun a single JUnit/TestNG test class through Maven Surefire.
python -m pytest tests/test_login.py -vRun one Python test module with verbose per-test output.
tests/test_login.py::test_valid_login PASSED
Examples
A first login flow in Java
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) { WebDriver driver = new ChromeDriver(); driver.get("https://example.com/login"); WebElement user = driver.findElement(By.id("username")); user.sendKeys("alice"); driver.findElement(By.name("password")).sendKeys("s3cret"); driver.findElement(By.tagName("button")).click(); String heading = driver.findElement(By.tagName("h1")).getText(); System.out.println("Logged in as: " + heading); driver.quit(); }}new ChromeDriver() launches a real Chrome browser, driver.get() navigates to the login page, and findElement(By.id(...)) locates fields that are then filled with sendKeys. The submit button is clicked, the resulting heading is read with getText(), and quit() closes the browser and ends the session.
In production
- Run the same smoke tests against staging after every deploy to catch regressions before users do.
- Combine Selenium with a grid and CI to run the suite across Chrome, Firefox and Edge in parallel.
- Drive multi-step user journeys — signup, checkout, password reset — that span several pages.
- Capture screenshots and session logs on failure so developers get a reproduction artifact, not just a stack trace.
Best practices
- Always quit the driver in a finally block or teardown hook to avoid leaking browser processes on shared runners.
- Prefer stable locators such as id or a data-testid attribute over brittle XPath and CSS chains.
- Keep tests independent: each test opens its own session and creates its own data.
- Introduce explicit waits from day one instead of sprinkling in Thread.sleep later.
- Run headless in CI and headed locally so you can watch a failing test during development.
Common mistakes
- Letting the driver leak by never calling quit(), which exhausts memory and process limits on shared agents.
- Relying on Thread.sleep for synchronization instead of waiting for real application state.
- Coupling tests to one browser without a configuration switch, which breaks the moment Firefox is needed.
- Asserting on brittle selectors that change with every CSS tweak instead of stable test hooks.
Common issues
unknown error: cannot find Chrome binaryChromeDriver cannot locate a Chrome executable on the machine.
Point to the Chrome binary via system properties/environment variables, or install Chrome.
SessionNotCreatedException: This version of ChromeDriver only supports Chrome version 119ChromeDriver and Chrome versions do not match.
Update ChromeDriver to match the installed Chrome (webdriver-manager does this automatically).
AttributeError: 'WebDriver' object has no attribute 'find_element_by_id'You are using the removed pre-Selenium-4 Python API.
Use find_element(By.ID, ...) with the By import from selenium.webdriver.common.by.
Debugging tips
- Read the exception type first: NoSuchElementException usually means a wrong locator or a missing wait.
- Take a screenshot in the failure handler to see the exact page state when the test died.
- Check the browser's console log and network tab; many failures are application errors, not Selenium errors.
- Run headed with a short pause in the failure handler so you can watch the actual page state.
Interview checkpoint
Hands-on lab
- Set up a Python project with Selenium in a virtual environment
- Automatically manage the ChromeDriver binary with webdriver-manager
- Launch a browser, navigate and locate elements
- Assert on page content and capture a screenshot
Your First Selenium Test
25 min · beginner
Quick quiz
Which of the following is NOT a Selenium component?
Selenium WebDriver can only automate Google Chrome.
Your test fails with NoSuchElementException right after page load on a slow connection, but passes on fast machines. What is the best fix?
Cheat sheet
new ChromeDriver()Start a browser sessiondriver.get(url)Navigate to a URLdriver.getTitle()Read the page titledriver.close()Close the current windowdriver.quit()End the session and kill the browserBy.id("email")Fastest, usually uniqueBy.name("password")Form field namesBy.cssSelector("button.primary")Structural queriesBy.xpath("//div[@id='cart']/span")Most flexible, most brittleBy.linkText("Sign out")Anchor tags only