Selenium is the original open-source browser automation project: a set of tools that drive real browsers programmatically, used primarily for automated testing of web applications. It gave the industry the WebDriver protocol, which became a W3C standard implemented by every major browser, and for over a decade it was simply what "browser testing" meant. Today it shares the field with younger frameworks, but its protocol, language breadth, and ecosystem keep it widespread, especially in enterprises.
The Three Pieces#
- Selenium WebDriver: the core library. Your test code (Java, Python, C#, JavaScript, Ruby, Kotlin) sends standardized commands to a browser-specific driver (chromedriver, geckodriver), which controls the real browser.
- Selenium Grid: distributes tests across many machines and browser/OS combinations, on your infrastructure or a vendor cloud (BrowserStack, Sauce Labs, LambdaTest).
- Selenium IDE: a record-and-playback browser extension for quick prototypes; real suites get written in code.
A Minimal Example#
from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Chrome()driver.get("https://example.com/login")driver.find_element(By.CSS_SELECTOR, "[data-testid='submit']").click()WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-testid='dashboard']")))driver.quit()
from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Chrome()driver.get("https://example.com/login")driver.find_element(By.CSS_SELECTOR, "[data-testid='submit']").click()WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-testid='dashboard']")))driver.quit()
The explicit WebDriverWait is the signature Selenium experience: it does not auto-wait, so synchronization is your code's job, and unsynchronized Selenium suites are where most of its flaky-test reputation comes from.
Where Selenium Still Wins#
- Language coverage: the broadest bindings of any framework; if the team writes Ruby or needs Kotlin, Selenium has it
- Standardized protocol: W3C WebDriver is implemented by browser vendors themselves, including niche and legacy browsers nothing else drives
- Enterprise ecosystem: two decades of integrations, vendor grids, and an enormous body of existing suites and expertise
- True browser/OS matrix: Grid plus vendor clouds covers combinations (old Safari, IE-mode Edge) modern tools ignore
Where It Shows Its Age#
Compared with Playwright and Cypress: no auto-waiting, no built-in test runner or assertions (you bring JUnit/pytest/etc.), no trace viewer or time-travel debugging, slower protocol round-trips, and more boilerplate per test. The newer frameworks bundle what Selenium leaves to you, which is most of why greenfield projects rarely pick it.
Limitations to Know#
- Synchronization is on you. Auto-waiting is the single biggest ergonomic gap; budget discipline for explicit waits or inherit flakiness.
- It is a library, not a platform. Runner, reporting, retries, and parallel orchestration are assembly-required.
- Grid is real infrastructure. Self-hosting a reliable Grid is an ops project; most teams end up paying a vendor cloud.
Conclusion#
Selenium is the standard-bearer: broadest languages, the W3C protocol, and unmatched browser/OS reach, at the cost of doing your own waiting, running, and reporting. Pick it for enterprise matrices and non-JS teams; pick a modern framework for greenfield speed.
Whichever framework drives the browser, the suite itself is the recurring cost. ObserveOne's Autopilot generates Playwright tests straight from your app's URL and self-heals them as the UI evolves, which is the part no framework, Selenium included, does for you.