AttributeError: ‘WebDriver’ Object Has No Attribute ‘Send_Keys’ | Quick Fix Steps

AttributeError: ‘WebDriver’ Object Has No Attribute ‘Send_Keys’ appears when you call send_keys on the driver instead of a Selenium WebElement.

Selenium tests can grind to a halt when Python throws AttributeError and tells you that the WebDriver object has no attribute named send_keys. The message feels confusing, because you know send_keys exists somewhere in the Selenium API, yet your script stops right away.

This guide walks through what that error message means in plain terms, why it shows up with code that looks reasonable at first glance, and how to fix it with small changes. By the end you will know how to point send_keys at the right target, avoid the Send_Keys typo, and keep keyboard automation stable.

What Attributeerror Webdriver Object Has No Attribute Send Keys Means

In Python, AttributeError pops up when you try to use a method or property that an object does not provide. The message AttributeError: ‘WebDriver’ object has no attribute ‘Send_Keys’ tells you that the WebDriver instance you created does not expose a Send_Keys method at all.

In the Selenium Python bindings, the send_keys method belongs to selenium.webdriver.remote.webelement.WebElement, not to the WebDriver class itself. WebDriver controls the browser window, while WebElement represents items on the page such as inputs, buttons, or the html root node. When you call send_keys directly on the driver, Python searches the WebDriver class for that method and fails.

There is a second detail hidden in the message. Selenium defines send_keys with a lowercase k. When the error mentions Send_Keys with a capital K and an underscore, Python reads it as a different name. Even if you call it on a WebElement, Send_Keys will still crash, because that exact name does not exist in the library.

Fixing AttributeError: ‘WebDriver’ Object Has No Attribute ‘Send_Keys’

The fix comes from changing two things in your Selenium script: where you call send_keys and how you spell it. The method must run on a WebElement, and the name must match the Selenium API exactly.

  • Select the element first — Store the target field, button, or container in a variable returned by find_element or a related call.
  • Call send_keys on that element — Chain send_keys directly on the element variable, not on the driver.
  • Use the correct spelling — Use send_keys with lowercase letters and an underscore, never Send_Keys or sendKeys.
  • Wait for the element to be ready — Combine WebDriverWait with expected_conditions so the element is present and interactable before you type.

Here is a short pattern that removes the AttributeError and keeps your test easy to read at the same time.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver.get("https://example.com/login")

wait = WebDriverWait(driver, 10)
username_input = wait.until(
    EC.visibility_of_element_located((By.ID, "username"))
)
username_input.send_keys("admin")

By waiting for the element and then calling send_keys on username_input instead of driver, you match how the Selenium Python bindings are designed and the AttributeError disappears.

Correct Way To Use Send Keys On Selenium Elements

Once you switch from calling send_keys on the driver to using it on elements, your next step is to build a clear pattern you can repeat across tests. That pattern keeps keyboard interactions readable and reduces strange edge cases.

  1. Locate the element — Choose a stable locator that survives layout changes, such as an id, name, data attribute, or a short css selector.
  2. Store the element — Save the result of find_element in a variable instead of calling long chains each time you type.
  3. Type the input — Call element.send_keys with the text you need or with Keys constants for special keys.
  4. Clear when needed — Call element.clear before send_keys if the field may contain old text from a previous run.
  5. Check the result — After typing, read element.get_attribute(“value”) or another property to confirm that the page accepted the text.

Here is a sample script that uses this pattern to fill in both a username and password field in a login form.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()
driver.get("https://example.com/login")

username = driver.find_element(By.NAME, "username")
password = driver.find_element(By.NAME, "password")

username.clear()
username.send_keys("admin")
password.clear()
password.send_keys("secret")
password.send_keys(Keys.ENTER)

This script gives send_keys to the correct objects and keeps the WebDriver responsible for navigation and session control only.

Common Code Patterns That Trigger This Attributeerror

Many Selenium learners run into AttributeError: ‘WebDriver’ Object Has No Attribute ‘Send_Keys’ with similar kinds of code. The details vary, yet the root cause is always that send_keys runs on the wrong object or with the wrong spelling.

  • Calling send_keys on driver — Code such as driver.send_keys(“admin”) ignores the WebElement layer completely, so Python checks the driver object and fails.
  • Using Send_Keys instead of send_keys — Even when you select an element first, a capital K or extra underscore turns the method into a new name that Selenium never defined.
  • Mixing up element lists and single elements — Methods like find_elements return a list, and lists do not provide send_keys. Call send_keys on one item from the list, not on the list itself.
  • Using the wrong locator for the field — When a locator misses the element, find_element can raise or find_elements can return an empty list, and later calls lead to different errors such as NoneType has no attribute send_keys.

The main keyword AttributeError: ‘WebDriver’ Object Has No Attribute ‘Send_Keys’ can mask these variations, so checking how you select elements is just as helpful as checking how you type.

# Wrong: calls send_keys on the driver
driver.send_keys("admin")

# Right: calls send_keys on the element
username = driver.find_element(By.ID, "username")
username.send_keys("admin")

Once you adjust your code to match the second pattern, the AttributeError stops appearing and the rest of your test logic can run.

Send Keys Alternatives For Page Level Keyboard Actions

Sometimes you do not want to type into a single field at all. You may need to send arrow keys to a canvas game, press Escape to close a dialog, or use shortcut keys that the page listens for at the document level. That is where ActionChains and focus tricks help.

  1. Target the root element — Locate the html or body node and call send_keys on that element so the page receives the keyboard event at a high level.
  2. Use ActionChains for sequences — When you need a series of keys, build an ActionChains instance, add send_keys calls to it, and then call perform.
  3. Click once before typing — Trigger a click on the canvas, iframe, or document area so that the browser focus sits on the right surface before the keys fire.

This pattern keeps keyboard commands aimed at elements instead of the driver and still works even when no input field appears on the page.

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

game_area = driver.find_element(By.TAG_NAME, "html")

actions = ActionChains(driver)
actions.click(game_area)
actions.send_keys(Keys.UP, Keys.RIGHT, Keys.DOWN, Keys.LEFT)
actions.perform()

By sending keys through ActionChains to a top level element, you keep the WebDriver object free from direct keyboard calls and avoid the AttributeError in a clean way.

Quick Reference Table For Attributeerror Send Keys Issues

When you debug a busy Selenium script, it helps to have a compact checklist that links the symptom you see with the part of the code that likely needs a tweak. The table below gives that quick view for the most common send_keys related problems.

Symptom Likely Cause One Line Fix
AttributeError about WebDriver and ‘Send_Keys’ send_keys called on driver with misspelled method name Call send_keys on a WebElement with correct spelling
AttributeError: ‘WebDriver’ object has no attribute ‘send_keys’ send_keys called on driver instead of element Find the target element and use element.send_keys
AttributeError: ‘list’ object has no attribute ‘send_keys’ Using find_elements and calling send_keys on the list Select one element from the list before typing
AttributeError: ‘NoneType’ object has no attribute ‘send_keys’ Locator did not match any element on the page Fix the locator or wait until the element appears
Keys sent but field stays empty Element not visible, disabled, or covered by another node Wait for visibility or scroll the element into view

This table turns the long error text into a short set of checks, so you can scan for the matching row and move straight to the relevant change in your code.

Practical Habits To Prevent Attributeerror In Selenium Tests

Once you have fixed this AttributeError around send_keys on WebDriver, the next goal is to keep the same mistake from sneaking back into new tests. A few small habits in your daily coding rhythm make that much easier.

  • Wrap element lookups in helper functions — Small helpers such as get_username_input or get_search_box hide locator details and return WebElement objects ready for send_keys.
  • Stick to a single naming style — Use snake_case for method names to match the Selenium API so that Send_Keys and sendKeys never appear in your editor.
  • Rely on linters and type hints — Tools like mypy and static checkers can catch method names that do not exist on WebElement before you even run the test suite.
  • Add compact asserts after typing — Short checks on field values or page state right after send_keys calls reveal broken locators much earlier.
  • Extract common keyboard flows — When you repeat the same login or search steps, move them into reusable functions that already call send_keys on the correct targets.

With these habits in place, most new scripts will use send_keys correctly from the start, and your time can go into higher level test logic instead of hunting down AttributeError messages.