Updated: (Updated Case 2. Adam Goucher pointed out I referenced the Wait class which is for explicit waits, yet this case is about implicit waits. Yeesh. Major writing failure. Thankfully I have good pals who keep me straight.)
NOTE: I missed posting this yesterday due to a long trip back and forth to visit the amazing new expansion at the Kalahari in preparation for CodeMash. That coupled with a sick kid left me behind the power curve. Sorry!
There’s a nice opener for you, but never fear, I’m going to help you through a few of those—because I’ve suffered through them and would prefer you didn’t have to.
Let’s look at three common situations you’ll likely run in to on web applications:
- You’re working with an AJAX-ified page where the element you need isn’t yet loaded.
- You’re working with an AJAX-ified page where the content you need isn’t yet loaded.
Answer: Varies by framework. When using Selenium, the field’s onchange event only fires when focus leaves that field. You’ll need to click to another field to get the validation to work properly. That might look something like this:
In Test Studio, we inject text directly to the DOM, so no events at all get fired on fields. You’ll need to use the “SimulateRealTyping” property to push the input text through the browser itself. This is a property on that specific test step:
Other testing tools/frameworks will have their own approaches to solving this problem. Point being, spend time understanding your app and your tools.
Case 2: AJAX (or some dynamic system) hasn’t yet loaded the element I need!
Problem: The elements you need to work with haven’t yet been loaded on the page.
Have a look at the ASP.NET AJAX demo page for a drop down menu. Use some tool like Firebug to inspect the current DOM and you’ll see the menu elements aren’t actually loaded on the page yet. The menu elements (the ones you want to interact with!) don’t get loaded until you click on the pull-down list. You can’t validate or interact with elements that aren’t yet there!
Answer: Use Selenium’s implicit wait feature to help out with this. You set a default timeout for the browser session you’re currently using, after which Selenium will wait for the configured amount of time for the elements to appear. If the elements don’t show up in the DOM, you’ll see an Exception, which is what you want – the elements aren’t appearing, so your test is failing. In Selenium this looks like:
Note we’re setting the ImplicitWait property to ten seconds. The test will hang around that long waiting for the service call to finish and the DOM to update with the element we need to work with.
In Test Studio we already handle this sort of implicit wait without any extra steps.
Not sure how Watir handles these sorts of situations, but I would assume (yes, bad word!) that it’s very similar.
Case 3: AJAX (or some dynamic system) hasn’t yet loaded the ContentI need!
Problem: The content you need to work with hasn’t yet been loaded on the page.
Answer: Use explicit waits to delay your test’s execution until the content is loaded.
Have a look at the ASP.NET AJAX demo page for cascading menus.
Use some tool like Firebug to inspect the current DOM and you’ll see the menu elements are there, but not their content. Make some choices for the menus, look at the DOM. Now you’ll see the content exists after having been loaded by an AJAX callback. Because the elements exist, but not their content, we need to handle this with an explicit wait. (See the awesome Selenium article on explicit and implicit waits. You need to read this!)
In the example above we need to navigate to the page, then make a series of selctions. In each dropdown selection list, we’ll need to get that selection element, then wait for the specific item we want to appear. That content is loaded by the previous selection, or in the case of the Make selection, by the actual page loading.
Here’s how we write the first section of code to wait and select our option in the Make pulldown. After that, we use WebDriverWait to explicitly wait until our target element (the make of “Acura” in this case) appears. Once the content is loaded in to the options we can then select the specific item from the option list.
Actions on the remaining two lists are the same. For the final confirmation message, also AJAX-ified, we can go back to our implicit wait pattern shown earlier—that message is in an element which isn’t loaded on the page. (NOTE: The test for the confirmation message isn’t a great one. A better one would be to ensure the proper combination of make+model+color is rendered as well as the general message – I took this shortcut for brevity’s sake because this example’s already somewhat lengthy.)
There you have it. A quick walk-through of three common situations on web pages that can give automation folks grief.