![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0282.png)
In this one we’ve “rolled our own” wait—we iterate through all the current browser
windows, looking for one with a particular title. If we can’t find it, we do a short wait,
and try again, decrementing a retry counter.
This is such a common pattern in Selenium tests that the teamcreated anAPI for waiting
—it doesn’t quite handle all use cases though, so that’s why we had to roll our own the
first time around. When doing something simpler like waiting for an element with a
given ID to appear on the page, we can use the
WebDriverWait
class:
functional_tests/test_login.py (ch15l015).
from
selenium.webdriver.support.ui
import
WebDriverWait
[
...
]
def
wait_for_element_with_id
(
self
,
element_id
):
WebDriverWait
(
self
.
browser
,
timeout
=
30
)
.
until
(
lambda
b
:
b
.
find_element_by_id
(
element_id
)
)
This is what Selenium calls an “explicit wait”. If you remember, we already defined an
“implicit wait” in
FunctionalTest.setUp
. We set that to just three seconds, which is
fine in most cases, but when we’re waiting for an external service like Persona, we
sometimes need to bump that default timeout.
There are more examples in the
Selenium docs, but I actually found reading the
source codemore instructive—there are good docstrings!
implicitly_wait
is unreliable, especially once JavaScript is in‐
volved. Prefer the “wait-for” pattern in your FT whenever you need
to check for asynchronous interactions on your pages. We’ll see this
again in
Chapter 20.
And if we run the FT, it works!
$
python3 manage.py test functional_tests.test_login
Creating test database for alias 'default'...
Not Found: /favicon.ico
login view
sending to mozilla {'assertion': [...]
[...]
got b'{"audience":"localhost","expires":[...]
[...]
.
---------------------------------------------------------------------
Ran 1 test in 32.222s
OK
Destroying test database for alias 'default'...
254
|
Chapter 15: User Authentication, Integrating Third-Party Plugins, and Mocking with JavaScript