Selenium Tips: Infinite Loops Take Forever

October 16th, 2009 by The Sauce Labs Team

In Selenium, it’s a (semi-)common idiom to loop on an element that you expect to exist in the near future.  One way we have seen this done is to create an infinite loop checking for the new element

while not selenium.is_text_present(
                       'logged in'):
    pass

This code causes alarm bells because if ‘logged in’ never appears it will loop until you kill the test!  To solve this problem, you should set an explicit timeout on every query like this, for example

start = time.time()
timeout = 60
found = False
while start + timeout < time.time():
    if selenium.is_text_present('logged in'):
        found = True
        break
    time.sleep(0.25)
self.assert_(found)

With this code your query will expire after the timeout, though it does suffer from a serious DRY failure so it’s a perfect candidate for refactoring into a method

def with_timeout(test, value, timeout=60):
    start = time.time()
    found = False
    while start + timeout < time.time():
        if test(value):
            found = True
            break
        time.sleep(0.25)
    return found

Which you would use in a regular assert like this

self.assert_(
    with_timeout(selenium.is_text_present,
                   value))

This simple change will make your jobs finish reliably in error cases and increase the readability of your logs.

Tune in next week for another Selenium Tip of The Week from Sauce Labs.

Share

Related posts:
Selenium Tips: Improving your waiting skills

Comments (You may use the <code> or <pre> tags in your comment)

  1. Jeremy says:

    I understand you don’t like finite loops but I think your while loop completely skips the loop altogether. :) Are you sure you don’t want:

    while start + timeout > time.time():

    you want a greater than not a less than right?

Leave a Comment