Question

How do I write the function for Selenium to wait for a table with just a class identifier in Python? I'm having a devil of a time learning to use Selenium's Python webdriver functions.

1
42
11/15/2016 3:08:58 PM

Accepted Answer

From the Selenium Documentation PDF :

import contextlib
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui

with contextlib.closing(webdriver.Firefox()) as driver:
    driver.get('http://www.google.com')
    wait = ui.WebDriverWait(driver,10)
    # Do not call `implicitly_wait` if using `WebDriverWait`.
    #     It magnifies the timeout.
    # driver.implicitly_wait(10)  
    inputElement=driver.find_element_by_name('q')
    inputElement.send_keys('Cheese!')
    inputElement.submit()
    print(driver.title)

    wait.until(lambda driver: driver.title.lower().startswith('cheese!'))
    print(driver.title)

    # This raises
    #     selenium.common.exceptions.TimeoutException: Message: None
    #     after 10 seconds
    wait.until(lambda driver: driver.find_element_by_id('someId'))
    print(driver.title)
54
1/14/2012 10:05:29 AM

Selenium 2's Python bindings have a new support class called expected_conditions.py for doing all sorts of things like testing if an element is visible. It's available here.

NOTE: the above file is in the trunk as of Oct 12, 2012, but not yet in the latest download which is still 2.25. For the time being until a new Selenium version is released, you can just save this file locally for now and include it in your imports like I've done below.

To make life a little simpler, you can combine some of these expected condition methods with the Selenium wait until logic to make some very handy functions similar to what was available in Selenium 1. For example, I put this into my base class called SeleniumTest which all of my Selenium test classes extend:

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

@classmethod
def setUpClass(cls):
    cls.selenium = WebDriver()
    super(SeleniumTest, cls).setUpClass()

@classmethod
def tearDownClass(cls):
    cls.selenium.quit()
    super(SeleniumTest, cls).tearDownClass()

# return True if element is visible within 2 seconds, otherwise False
def is_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

# return True if element is not visible within 2 seconds, otherwise False
def is_not_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

You can then use these easily in your tests like so:

def test_search_no_city_entered_then_city_selected(self):
    sel = self.selenium
    sel.get('%s%s' % (self.live_server_url, '/'))
    self.is_not_visible('#search-error')

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon