WebDriver API & Interactions
Master the WebDriver API surface: the driver object, WebElement interactions, element state checks, form controls, the Actions API for mouse and keyboard, and executeScript for the edges the public API cannot reach.
What is this?
Beyond findElement and click, the WebDriver API exposes a rich set of interactions. WebElement offers click, sendKeys, clear, getText and attribute queries, while element state methods (isDisplayed, isEnabled, isSelected) gate whether an interaction is possible. Form controls are handled with Select for native dropdowns and plain clicks for checkboxes and radio buttons. The Actions API composes advanced input — hover, double-click, drag-and-drop and keyboard chords — and executeScript reaches into the page for anything the public API cannot express.
Why do you need it?
- Correct interaction requires checking element state first; blind clicks are the top source of flaky tests.
- Native form handling (Select, sendKeys) matches real user input and fires real keyboard events.
- The Actions API covers hover menus, drag-and-drop and modifier-key combinations that simple clicks cannot.
- executeScript reaches dynamic JS widgets, reads computed styles and scrolls elements into view.
- Screenshots and window management (size, position, maximize) make tests observable and reproducible.
Mental model
A user's hands on the keyboard and mouse
WebDriver interactions
A user hovers, clicks, types and drags — each is a discrete action. WebDriver models these as commands on elements and an Actions chain, but it never 'thinks' like a user, so the test must verify state explicitly.
How it works
- findElement returns a WebElement that carries an opaque reference resolved by the browser session.
- Interactions like click and sendKeys send the command with that reference; the driver resolves it, performs the action and returns the new state or an error.
- State checks (isDisplayed, isEnabled, isSelected) query the element's current DOM and computed style.
- Select wraps a <select> element and translates selectByValue / selectByVisibleText into native selection.
- Actions chains build a queue of low-level input events (move, press, release, pause) flushed atomically with perform().
Anatomy of a WebDriver interaction from locate to assert.
Key commands
mvn test -Dtest=WebDriverApiTestRun a single test class exercising the WebDriver API.
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
python -m pytest tests/test_interactions.py -vRun the Python interaction suite with per-test output.
chromedriver --verbose --log-path=driver.logStart ChromeDriver with verbose logging to a file, useful when commands are silently dropped.
pip install seleniumInstall the Selenium client library for Python.
mvn clean test -qRebuild and run the whole test suite quietly.
Examples
Filling forms and composing actions in Python
from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import Selectfrom selenium.webdriver.common.action_chains import ActionChainsfrom selenium.webdriver.common.keys import Keys driver = webdriver.Chrome()driver.get("https://example.com/settings") driver.find_element(By.ID, "search").send_keys("devops", Keys.ENTER) region = Select(driver.find_element(By.ID, "region"))region.select_by_visible_text("Europe")region.select_by_value("us-east-1") checkbox = driver.find_element(By.CSS_SELECTOR, "input[type='checkbox']")if not checkbox.is_selected(): checkbox.click() ActionChains(driver) \ .move_to_element(driver.find_element(By.ID, "menu")) \ .click(driver.find_element(By.ID, "submenu-item")) \ .perform() driver.find_element(By.TAG_NAME, "body").send_keys(Keys.CONTROL, "a") print(driver.find_element(By.ID, "status").get_attribute("data-state"))driver.save_screenshot("settings.png")driver.quit()sendKeys types text and can append special keys like ENTER. Select switches a native dropdown by visible text and by value. The checkbox is only clicked if is_selected() says it is not. ActionChains queues a hover then a click and flushes them atomically with perform(), and send_keys on the body sends a browser-level shortcut.
In production
- Drive keyboard-heavy flows such as shortcut-driven admin tools with Actions and Keys.
- Use Select for region and locale dropdowns so the value matches what the user actually chooses.
- Capture step-by-step screenshots to build a visual trail for manual review or regression comparison.
- Use executeScript to scroll elements into view and drive JS-only widgets before interacting.
Best practices
- Check isDisplayed before clicking; clicking a hidden element either fails or silently does nothing.
- Always clear() before sendKeys on edit fields to avoid appending to existing content.
- Prefer selecting by visible text or value over index, which breaks when options are reordered.
- Re-locate elements instead of caching them when the page re-renders, to avoid StaleElementReferenceException.
- Prefer Actions over raw key events for hover and drag because they fire native input sequences.
Common mistakes
- Using selectByIndex and breaking the test the moment the option order changes.
- Ignoring isEnabled and clicking disabled buttons, producing confusing timeout failures.
- Calling sendKeys on read-only or overlay-shielded fields and getting ElementNotInteractableException.
- Caching a WebElement across a page reload and hitting StaleElementReferenceException mid-flow.
Common issues
ElementNotInteractableException: element not interactableThe element is present but hidden, covered by an overlay, or disabled.
Wait for it to become visible/clickable with WebDriverWait and verify isEnabled before interacting.
StaleElementReferenceException: stale element referenceThe page re-rendered after the element was located, invalidating the reference.
Re-locate the element immediately before interacting instead of reusing a cached reference.
InvalidSelectorException: 'selector' is not a valid selectorThe CSS or XPath expression is malformed.
Validate the selector in DevTools console first, then paste the corrected version into the test.
Debugging tips
- driver.save_screenshot and get_screenshot_as_png capture the exact moment of failure for review.
- getAttribute('value') and text report different things: attributes vs rendered text — assert on the right one.
- Check isDisplayed versus presence: an element in the DOM can still be invisible to the user.
- Enable verbose driver logging to see every command sent and its response when behavior is confusing.
Interview checkpoint
Hands-on lab
- Locate elements with multiple locator strategies
- Fill inputs, a native select and a checkbox
- Compose a hover action with the Actions API
- Capture a screenshot of the resulting page
Drive a Real Form with the WebDriver API
30 min · beginner
Quick quiz
Which class handles native <select> dropdowns in Selenium?
isDisplayed() reports whether the element exists in the DOM.
Clicking a submit button throws ElementNotInteractableException. What should you check first?
Cheat sheet
element.click()Click an elementelement.send_keys('x')Type into a fieldelement.clear()Clear a field firstelement.get_attribute('value')Read field valueelement.textRead rendered textelement.is_displayed()Is it visible?element.is_enabled()Is it interactive?element.is_selected()Checkbox/radio stateActionChains(driver)Start a chain.move_to_element(el)Hover.double_click(el)Double click.click_and_hold(el)Press and hold.drag_and_drop(src, dst)Drag and drop.key_down(Keys.SHIFT)Modifier down.perform()Flush the queue