These rules help AI coding assistants generate correct, idiomatic Selenium code. They cover the modern Selenium 4 API across all official language bindings.
time.sleep() / Thread.sleep() / sleep(). Use explicit waits.driver.quit() in a finally block or equivalent to release browser resources.id and name first.| Language | Command / Config |
|---|---|
| Python | pip install selenium |
| Java | Maven: selenium-java artifact, group org.seleniumhq.selenium |
| JavaScript | npm install selenium-webdriver |
| Ruby | gem install selenium-webdriver |
| .NET | dotnet add package Selenium.WebDriver |
Selenium Manager (bundled since Selenium 4.6) automatically downloads the correct browser driver. No webdriver-manager, chromedriver-binary, or manual driver setup is needed.
from selenium import webdriver driver = webdriver.Chrome() # Selenium Manager handles chromedriver automatically driver.get("https://example.com")
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; WebDriver driver = new ChromeDriver(); // Selenium Manager handles chromedriver driver.get("https://example.com");
const { Builder } = require('selenium-webdriver'); const driver = await new Builder().forBrowser('chrome').build(); await driver.get('https://example.com');
require 'selenium-webdriver' driver = Selenium::WebDriver.for :chrome driver.navigate.to 'https://example.com'
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; IWebDriver driver = new ChromeDriver(); driver.Navigate().GoToUrl("https://example.com");
try: driver.get("https://example.com") finally: driver.quit()
try { driver.get("https://example.com"); } finally { driver.quit(); }
try { await driver.get('https://example.com'); } finally { await driver.quit(); }
begin driver.navigate.to 'https://example.com' ensure driver.quit end
using (IWebDriver driver = new ChromeDriver()) { driver.Navigate().GoToUrl("https://example.com"); }
Priority order: id > name > css > link_text > xpath
from selenium.webdriver.common.by import By driver.find_element(By.ID, "username") driver.find_element(By.CSS_SELECTOR, "input[name='q']") driver.find_elements(By.CSS_SELECTOR, "ul > li")
import org.openqa.selenium.By; driver.findElement(By.id("username")); driver.findElement(By.cssSelector("input[name='q']")); driver.findElements(By.cssSelector("ul > li"));
const { By } = require('selenium-webdriver'); await driver.findElement(By.id('username')); await driver.findElement(By.css("input[name='q']")); await driver.findElements(By.css('ul > li'));
driver.find_element(id: 'username') driver.find_element(css: "input[name='q']") driver.find_elements(css: 'ul > li')
driver.FindElement(By.Id("username")); driver.FindElement(By.CssSelector("input[name='q']")); driver.FindElements(By.CssSelector("ul > li"));
Wait for a specific condition before interacting with an element.
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By wait = WebDriverWait(driver, timeout=10) element = wait.until(EC.element_to_be_clickable((By.ID, "submit"))) element.click()
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import java.time.Duration; WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit"))); element.click();
const { until } = require('selenium-webdriver'); const element = await driver.wait(until.elementIsVisible( driver.findElement(By.id('submit')) ), 10000); await element.click();
wait = Selenium::WebDriver::Wait.new(timeout: 10) element = wait.until { driver.find_element(id: 'submit') } element.click
using OpenQA.Selenium.Support.UI; using SeleniumExtras.WaitHelpers; var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); var element = wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("submit"))); element.Click();
| Condition | Python | Java |
|---|---|---|
| Element visible | visibility_of_element_located | ExpectedConditions.visibilityOf |
| Element clickable | element_to_be_clickable | ExpectedConditions.elementToBeClickable |
| Text present in element | text_to_be_present_in_element | ExpectedConditions.textToBePresentInElement |
| Alert present | alert_is_present | ExpectedConditions.alertIsPresent |
| URL contains | url_contains | ExpectedConditions.urlContains |
| Title contains | title_contains | ExpectedConditions.titleContains |
| Element staleness | staleness_of | ExpectedConditions.stalenessOf |
from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--headless=new") driver = webdriver.Chrome(options=options)
options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--window-size=1920,1080") options.add_argument("--disable-gpu")
driver.implicitly_wait(5) # seconds
Do not mix implicit and explicit waits — this causes unpredictable timeouts.
Encapsulate page structure in dedicated classes to improve maintainability.
from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class LoginPage: URL = "https://example.com/login" def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def open(self): self.driver.get(self.URL) return self def login(self, username, password): self.wait.until(EC.element_to_be_clickable((By.ID, "username"))).send_keys(username) self.driver.find_element(By.ID, "password").send_keys(password) self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click() return self
from selenium.webdriver.common.action_chains import ActionChains ActionChains(driver).move_to_element(element).click().perform() ActionChains(driver).double_click(element).perform() ActionChains(driver).context_click(element).perform() ActionChains(driver).drag_and_drop(source, target).perform()
from selenium.webdriver.common.keys import Keys element.send_keys("Hello World") element.send_keys(Keys.RETURN) element.clear()
alert = driver.switch_to.alert alert.accept() # OK alert.dismiss() # Cancel alert.send_keys("text")
driver.switch_to.frame("frame-id") driver.switch_to.default_content()
main_window = driver.current_window_handle driver.switch_to.new_window('tab') driver.switch_to.window(main_window) driver.close() driver.switch_to.window(main_window)
driver.save_screenshot("screenshot.png") element.screenshot("element.png")
Use sparingly — prefer native Selenium interactions when possible.
result = driver.execute_script("return document.title;") driver.execute_script("arguments[0].click();", element) driver.execute_script("arguments[0].scrollIntoView(true);", element)
from selenium.webdriver.support.select import Select select = Select(driver.find_element(By.ID, "dropdown")) select.select_by_visible_text("Option 1") select.select_by_value("opt1") select.select_by_index(0) options = select.options
Run tests in parallel across different browsers and machines.
from selenium import webdriver driver = webdriver.Remote( command_executor="http://localhost:4444", options=webdriver.ChromeOptions() )
Start a local Grid (requires Java):
selenium-manager --grid # Or download and run: java -jar selenium-server.jar standalone
Selenium 4 supports real-time browser events via BiDi.
from selenium import webdriver from selenium.webdriver.common.bidi.console import Console driver = webdriver.Chrome() with driver.bidi_connection() as conn: session = conn.session # Use BiDi APIs for log listening, network interception, etc.
Selenium Manager is also a standalone CLI tool for driver and browser management.
# Resolve/download chromedriver for the installed Chrome version selenium-manager --browser chrome # Download a specific Firefox version selenium-manager --browser firefox --browser-version 120 # Generate a Selenium skills reference file selenium-manager --init-skills # Generate these LLM rules in rules/selenium.md selenium-manager --init-rules
| Error | Cause | Fix |
|---|---|---|
NoSuchElementException | Element not in DOM yet | Use explicit wait |
StaleElementReferenceException | DOM updated after element was found | Re-locate the element |
ElementNotInteractableException | Element hidden or covered | Scroll into view or wait for visibility |
TimeoutException | Condition never met in wait | Increase timeout or check selector |
WebDriverException: chrome not reachable | Browser crashed or closed | Check browser startup options |
SessionNotCreatedException | Driver/browser version mismatch | Let Selenium Manager resolve the driver |
time.sleep(5) — use WebDriverWait insteaddriver.find_element(By.XPATH, "/html/body/div[3]/span[2]") — fragile absolute XPathChromeDriver("/usr/bin/chromedriver") — let Selenium Manager handle itdriver.quit() — causes zombie browser processesdriver.get() inside a loop without proper cleanupexecute_script to click elements that are interactable natively