Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Intermediate Selenium WebDriver!
You have completed Intermediate Selenium WebDriver!
We need WebDriver to wait a bit until an AJAX request completes and an element is loaded. We can accomplish this by setting an "implicit wait" on our driver object.
In this video, we'll be using this version of the RSVP site.
This version of the RSVP app has been set up to load a list of people who have already been invited using an AJAX call. Each time I load the page, notice how the invitees take a second longer to load than the rest of the page. (Actually, to tell the truth, I added an additional one-second delay to the loading, but we'd get the same result if we were on a slow network, or if the server took a long time to send the AJAX response.)
This delay will be a problem if we want to write tests that ensure the invitees are being loaded properly. Let me show you what I mean.
- If we right-click one of the invitee elements and choose Inspect, our browser developer tools will load, with the selected element highlighted.
- Notice that each invitee is being added as a "list item" element within this "unordered list" element, which has an ID of
"invitedList"
. - Let's edit our page object class to add a locator for these list item elements:
- Notice that each invitee is being added as a "list item" element within this "unordered list" element, which has an ID of
pages/rsvp.js
:
invitees: By.css('#invitedList li'),
- Now, let's add a test to ensure these invitee elements get loaded after the page loads.
tests/invitees.js
:
// We'll add a test with a description saying the page "loads existing invitations".
// We'll set up the test in another asynchronous function.
it('loads existing invitations', async function() {
// We'll call our driver object's findElements() method. Notice that's "findElements"
// PLURAL, not singular - we expect to find multiple matching elements, so this will
// return an array of elements. We'll pass findElements() the invitees locator from
// our page object, which is set up to find all the "li" elements inside the element
// with an ID of "invitedList". findElements() returns a promise, soWe use the "await"
// keyword to wait for the promise to resolve, and we store the resulting array in
// the "invitees" variable.
let invitees = await driver.findElements(page.locators.invitees);
// Now, we need to test whether the invitees list loaded correctly. Each element
// contains the invitee's name. So I'm going to access the second invitee element,
// and get its text using the getText() method. As always, this returns a promise,
// so I'll get its resolved value using "await".
let text = await invitees[1].getText();
// Finally, we need the test itself. I'm going to assert that the element text
// includes the string "Craig Dennis".
assert(text.includes("Craig Dennis"));
});
- But if we run this, it will fail with the error
"Cannot read property 'getText' of undefined"
.- We get this error because our attempt to find invitee elements fails.
- Our call to
findElements()
happens as soon as the page loads. - WebDriver looks for
li
elements within theinvitedList
element, but at that moment, there are none, because the AJAX request hasn't completed.
- What we need is for WebDriver to wait a bit until the AJAX request completes and the element is loades.
- We can accomplish this by setting an "implicit wait" on our driver object.
- The wait is considered "implicit" because every time a function call is made that checks for an element, it's implied that the driver should wait a certain amount of time for the element to appear.
-
await driver.manage().setTimeouts({implicit: 3000});
- There are other options you can set using
setTimeouts()
as well. See the docs for more info.
- There are other options you can set using
- Now, if we re-run
mocha
, when the call todriver.findElements()
is made, WebDriver will wait up to 3 seconds for matching elements to appear before continuing with the test.- The test will only fail if the 3 seconds elapses without finding a match.
There's a problem with this approach, though. The implicit wait applies to all tests that use this driver object. This means that for each test, if the element you've specified isn't present on the page, WebDriver will wait up to 3 seconds for it to appear. This is true even if you've made a mistake in your test, or if the app has been changed so the test is failing. Implicit waits can make your failing tests run much slower.
In the next video, we'll look at explicit waits, which can help you avoid this problem.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up