Background Image
Table of Contents Table of Contents
Previous Page  407 / 478 Next Page
Information
Show Menu
Previous Page 407 / 478 Next Page
Page Background

Do you remember that we set an

implicitly_wait

on the browser, way back in

Chap‐ ter 2 ?

Do you remember I mentioned it was unreliable?

implicitly_wait

works reasonably well for any calls to any of the Selenium

find_el

ement_

calls, but it doesn’t apply to

browser.current_url

. Seleniumdoesn’t “wait” after

you tell it to click an element, so what’s happened is that the browser hasn’t finished

loading the new page yet, so

current_url

is still the old page. We need to use some

more wait code, like we did for the various Persona pages.

At this point it’s time for a “wait for” helper function. To see how this is going to work,

it helps to see how I expect to use it (outside-in!):

functional_tests/test_my_lists.py (ch20l012).

# She sees that her list is in there, named according to its

# first list item

self

.

browser

.

find_element_by_link_text

(

'Reticulate splines'

)

.

click

()

self

.

wait_for

(

lambda

:

self

.

assertEqual

(

self

.

browser

.

current_url

,

first_list_url

)

)

We’re going to take our

assertEqual

call and turn it into a lambda function, then pass

it into our

wait_for

helper.

functional_tests/base.py (ch20l013).

import

time

from

selenium.common.exceptions

import

WebDriverException

[

...

]

def

wait_for

(

self

,

function_with_assertion

,

timeout

=

DEFAULT_WAIT

):

start_time

=

time

.

time

()

while

time

.

time

()

-

start_time

<

timeout

:

try

:

return

function_with_assertion

()

except

(

AssertionError

,

WebDriverException

):

time

.

sleep

(

0.1

)

# one more try, which will raise any errors if they are outstanding

return

function_with_assertion

()

wait_for

then tries to execute that function, but instead of letting the test fail if the

assertion fails, it catches the

AssertionError

that

assertEqual

would ordinarily raise,

waits for a brief moment, and then loops around retrying it. The

while

loop lasts until

a given timeout. It also catches any

WebDriverException

that might happen if, say, an

element hasn’t appeared on the page yet. It tries one last time after the timeout has

expired, this time without the

try/except

, so that if there really is still an

AssertionEr

ror

, the test will fail appropriately.

A Common Selenium Problem: Race Conditions

|

379