As web apps grow more complex, test automation using Selenium has become essential for regression testing. However, getting Selenium scripts to run smoothly can be frustrating when encountering common errors like element not found or timeout exceptions.

Debugging faulty Selenium code sucks precious time away from developing new test coverage. Even seasoned Selenium users struggle with cryptic error messages that offer little insight into the root cause.

In this blog, we will examine the top 5 Selenium errors developers face along with their underlying reasons and potential solutions.

Understanding these common Selenium pitfalls will help you speed up troubleshooting. You can spend less time scratching your head over faulty locators and stale elements. We’ll share tips to avoid and proactively handle Selenium errors through improved scripting practices.

With these fixes in your toolkit, you can create reliable test automation that breaks less often. Removing the headaches around Selenium errors will help boost your confidence and productivity in test automation. Let’s get started unraveling Selenium’s quirks!

Top 5 Selenium Errors and How to Fix Them

Here are the top 5 common Selenium errors and fixes:

1. ElementNotInteractableException

This error occurs when your Selenium script tries to interact with an element that is not currently visible or enabled in the UI. For example:

  • Clicking on a button that is hidden or covered by another element
  • Sending keys to a disabled input field
  • Selecting an option from a dropdown that is collapsed

So even though the element exists in the DOM, it is not in an interactable state when the interaction is attempted.

Example

# Disable button after click
driver.find_element(By.ID, ‘btn’).click()
driver.execute_script(‘document.getElementById(“btn”).disabled = true’)

# Trying to click again will now fail
driver.find_element(By.ID, ‘btn’).click()
# Raises ElementNotInteractableException

So in this example, the button element transitions from an interactable to a non-interactable state between the first and second click actions. The second click fails because Selenium does not check if the element is enabled before clicking on it.

Fixes
  • Check if element is enabled before interacting:

    btn = driver.find_element(By.ID, ‘btn’)

    if btn.is_enabled():
    btn.click()

  • Use explicit wait for element to become clickable:

    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, ‘btn’)))
    driver.find_element(By.ID, ‘btn’).click()

This waits up to 10 seconds for the button to become clickable before attempting the click.

2. WebDriverException

The WebDriverException is a generic exception that occurs when there is a communication failure between Selenium and the target browser. Some common cases are:

  • Using an incompatible version of the browser driver
  • Browser driver crashing or disconnecting unexpectedly
  • Timeouts in communicating commands to the browser
  • Trying to run commands after the browser has closed
Examples
  • Incompatible driver version

    # Chrome version is lower than Chromedriver version
    chromedriver = ChromeDriver(version=”97″)
    browser = Chrome(version=”94″)
    # Raises WebDriverException due to incompatibility

    In this code, the ChromeDriver is being initialized to use version 97 while the target Chrome browser version is 94.

    The ChromeDriver and Chrome browser versions need to be compatible – the driver version should be >= the Chrome version.

    Since there is a mismatch between the ChromeDriver version (97) and the Chrome browser version (94), Selenium will fail to establish a connection between the driver and the browser.
    This will result in a WebDriverException being raised due to version incompatibility.

  • Browser crashed

    driver.get(“http://example.com”)
    # WebDriverException as driver cannot communicate with crashed browser

    In this example, the test is attempting to navigate to a website using the driver.get() command.
    However, if the Chrome browser has crashed for some reason, Selenium will be unable to communicate with it to execute the .get() action.

    When Selenium tries to send the command to the browser but gets no response because the browser process has died, a WebDriverException will be raised due to the lost connection.

    So in both cases, the root cause is a failure in communication between Selenium and the target browser resulting in a WebDriverException.

Fixes
  • Upgrade Selenium and browser drivers to their latest supported versions
  • Add waits and retries to handle temporary disconnects:

    for i in range(3):
    try:
    driver.get(“http://example.com”)
    break
    except WebDriverException:
    time.sleep(3)

  • Isolate tests to identify browser version failures

So WebDriverExceptions can arise due to both driver conflicts as well as underlying browser issues. Using stable versions and having robust waits/retries can mitigate such errors.

3. StaleElementReferenceException

This exception occurs when the DOM changes after an element was located, so the element no longer exists in the same form when Selenium tries to interact with it later.

For example, the element may have been deleted, re-rendered or the page navigated away.

Examples
  • Page refresh

    # Store reference to element
    elem = driver.find_element(By.ID, “myElement”)

    # Page refreshes and element is stale
    driver.refresh()

    # StaleElementReferenceException thrown
    elem.click()

    This code first locates an element by its ID and stores a reference in the elem variable.
    It then refreshes the page using driver.refresh(). This causes the page to reload and the DOM to be reconstructed.

    Finally, it tries to .click() on the stored element reference. But since the page was refreshed, the old DOM no longer exists – so the elem is now a stale reference.

    When it tries interacting with elem, it will throw a StaleElementReferenceException.

  • Element removed from DOM

    # Element removed via JavaScript after fetching
    elem = driver.find_element(By.XPATH, “//button[1]”)
    driver.execute_script(“document.getElementById(‘button1’).remove();”)

    # Element no longer exists – exception thrown
    elem.click()

    Here, the element is located first before the DOM is modified. The execute_script call removes the element from the document altogether.

    So when Selenium tries to .click() on the now non-existent elem, it raises a StaleElementReferenceException because the element no longer exists in the modified DOM.

    In both cases, the element becomes stale due to DOM state changes after fetching the reference.

Fixes
  • Avoid storing element references. Find element directly before interacting:

    driver.find_element(By.ID, “element”).click()

    – Refresh reference before each interaction:
    elem = driver.find_element(By.ID, “element”)
    elem.click()
    elem.clear()

  • Catch exception and re-find element:

    try:
    elem = driver.find_element(By.ID, “element”)
    elem.click()
    except StaleElementReferenceException:
    elem = driver.find_element(By.ID, “element”)
    elem.click()

4. NoSuchElementException

This error occurs when Selenium is unable to locate an element using the specified locator. Some common cases are:

  • The locator is incorrectly typed e.g. spelling mistakes
  • The locator is not unique enough and matches multiple elements
  • The desired element is not yet present in the DOM
Examples
  • Incorrect locator

    # Incorrect spelling of ID
    driver.find_element(By.ID, ‘lname’)

    This locator is trying to find an element by ID, but has a typo in the ID string.
    If there is no element with ID lname on the page, Selenium will be unable to find the target element and will throw NoSuchElementException.

  • Not unique locator

    # Not unique – multiple elements with same class
    driver.find_element(By.CLASS_NAME, ‘input’)

    Here, a class name locator is being used. Class names can match multiple elements on a page.
    If Selenium finds more than one element with the class input, it will not know which specific element to return and will throw NoSuchElementException.

  • Page not loaded

    # Page not fully loaded before finding element
    driver.get(“http://www.example.com”)
    driver.find_element(By.TAG_NAME, ‘button’)

    This navigates to a new page, but immediately tries to find an element before the page is fully loaded.
    If the tag does not exist on the page yet, Selenium will throw NoSuchElementException as it tries finding the element too soon.

Fixes
  • Double check locator string is typed correctly
  • Use unique locators like ID instead of name/class
  • Add waits before trying to find element:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, “submitBtn”)))
  • Limit scope of locator to section of page

The key is using reliable locators and allowing time for elements to load before accessing them.

5. TimeoutException

Here is a detailed explanation of the TimeoutException error and fixes:

TimeoutException

A TimeoutException occurs when Selenium code waits longer than the defined time for an expected condition to occur. Common cases:

  • Page load timeout exceeded
  • Element not found within timeout duration
  • Wait for element visibility/interaction exceeds timeout
Examples
  • Page load timeout

    # Timeout too short for page load
    driver.set_page_load_timeout(3)
    driver.get(‘http://example.com’)

    This sets the webpage load timeout to 3 seconds using set_page_load_timeout(). It then navigates to example.com.

    If the page takes over 3 seconds to load, the timeout will expire before the page finishes loading. This will cause a TimeoutException to be raised.

    So if example.com takes over 3 seconds to load, the short timeout will be exceeded and result in a timeout.

  • Element visibility timeout

    # Element not visible in 5 seconds
    driver.find_element(By.ID, “spinner”).is_displayed()
    WebDriverWait(driver, 5).until(EC.visibility_of_element((By.ID, “spinner”)))

    This first checks if the spinner element is displayed. If not, it waits up to 5 seconds for the spinner to become visible on the page.

    If the spinner does not appear within 5 seconds, the .until() condition will time out as the visibility requirement was not met within the threshold.

    So if the spinner element takes longer than 5 seconds to become visible, a TimeoutException will occur due to exceeded wait time.

Fixes
  • Set optimal explicit and implicit timeout durations
  • Use effective wait conditions like element_to_be_clickable
  • Handle exception and retry timed out actions
    try:
    my_element = WebDriverWait(driver, 10).until(EC.visibility_of_element((By.ID, “elem”)))
    except TimeoutException:
    print(“Retrying…”)
    my_element = WebDriverWait(driver, 10).until(EC.visibility_of_element((By.ID, “elem”)))
  • Setting timeouts as per app needs and having robust waits/retries can help mitigate timeouts.

a. Achieve Rapid and Robust Test Automation with LambdaTest

Here are more details on the key Selenium automation features provided by AI-powered test orchestration and execution platforms like LambdaTest:

i. Extensive Grid of Real Browsers

LambdaTest gives access to a scalable online Selenium grid comprising 2000+ real desktop and mobile browsers. The grid includes all major browsers like Chrome, Firefox, Safari, and Edge across a range of operating systems including Windows, MacOS, iOS, Android, and Linux. New browser versions and devices are continuously added.

ii. Support for All Languages and Frameworks

The LambdaTest Selenium grid supports test automation in all popular languages like Java, Python, C#, Ruby, PHP, etc. It also has native integration with all major test frameworks such as Selenium, Cypress, Playwright, Puppeteer, and Appium. Configuration is simplified through detailed docs and client libraries.

iii. Local Testing with Lambda Tunnel

LambdaTest Tunnel enables running tests on locally hosted or privately hosted web pages and apps by establishing a secure tunnel connection. This avoids exposing internal servers directly to the internet. Tunnel also reduces test failures caused by firewalls and network constraints.

iv. Comprehensive Test Execution Logs

LambdaTest provides extensive logs for each test run – Selenium logs, videos, network traffic, console logs, screenshots, and more. These execution artifacts aid in faster debugging and root-cause analysis of test failures.

v. Geolocation Testing Capability

The platform has an in-built geolocation feature that allows testing an application from different geographic locations. This helps validate region-specific use cases and localization. 60+ countries and regions are supported.

vi. Powerful Analytics and Reporting

LambdaTest offers detailed analytics on test executions like pass rate, failures, errors, etc. Filterable dashboards provide insights into test health. PDF and email reports can be auto-generated to share results with stakeholders.

These capabilities together enable performing reliable test automation at scale on LambdaTest’s cloud infrastructure.

b. Conclusion

Selenium errors like ElementNotInteractableException, WebDriverException, and TimeoutException can quickly derail your test automation efforts. Debugging faulty locators or waits eats up valuable time that could be better spent enhancing test coverage.

The goal is to spend less time troubleshooting failures, and more time expanding the capabilities of your test framework. Knowledge of Selenium’s quirks combined with sound automation hygiene will help tame test flakiness.

Tools like LambdaTest can provide cloud infrastructure, speed, and analytics to further boost test resilience. Leveraging the right techniques and solutions will let you harness the power of Selenium for stable test automation.