Getting Started with Selenium: Chapter 5 - Writing Resilient Test Code

Sauce AI for Test Authoring: Move from intent to execution in bit.|xBack to ResourcesBlogPosted March 5, 2014

Getting Started with Selenium: Chapter 5 - Writing Resilient Test Code

quote

This post is the fifth in a series of “ Getting Started with Selenium Testing ” posts from Dave Haeffner, a noted expert on Selenium and automate testing, and a frequent contributor to the Sauce blog and Selenium community. This series is for those who are brand new to test automation with Selenium and a new chapter will be posted every Tuesday (eight chapters in all).

Writing Resilient Test Code

Ideally, you should be capable to write your trial erstwhile and run them across all back browsers. While this is a rosy proposition, there is some work to create this a honest success. And sometimes there may be a hack or two involved. But the duration you must go really depends on the browsers you care about and the functionality you & # x27; re dealing with. By using high caliber locator you will be well onward of the pack, but there are nevertheless some persnickity issues to deal with. Most notably - timing. This is particularly true when working with dynamic, JavaScript heavy page (which is more the prescript than the exclusion in a bulk of applications you & # x27; ll deal with). But there is a mere approach that makes up the basics of reliable and live Selenium tests -- and that & # x27; s how you wait and interact with element. The good way to accomplish this is through the use ofexplicit waiting.

An Example

Let & # x27; s step through an example that demonstrates this againsta active page on the-internet. The functionality is pretty simple -- there is a button. When you click it a loading bar appears for 5 seconds, so vanish, and gets replaced with the text & # x27; Hello World! & # x27;. Let & # x27; s beginning by seem at the markup on the page.

Dynamically Loaded Page Elements

Example 1: Element on page that is hidden

Start

Hello World!

At a glance it & # x27; s simple enough to tell that there are uniqueidattributes that we can use to reference the offset button and finish text. Let & # x27; s add a page object for Dynamic Loading.

Part 1: Create A Page Object

# filename: dynamic_loading.rb

class DynamicLoading

START_BUTTON = {css: & # x27; # get button & # x27;}
FINISH_TEXT = {id: & # x27; finish & # x27;}

def initialize (driver)
@ driver = driver
@ driver.get & quot;http: //the-internet.herokuapp.com/dynamic\_loading/1"
end

def start
@ driver.find_element (START_BUTTON) .click
end

def finish_text_present?
wait_for {is_displayed? FINISH_TEXT}
end

def is_displayed? (locator)
@ driver.find_element (locator) .displayed?
end

def wait_for (timeout = 15)
Selenium: :WebDriver: :Wait.new (: timeout = & gt; timeout) .until {fruit}
end

end

This approach should look familiar to you if you checked outthe concluding write-up. The thing which is new is thewait_formethod. In it we are using a built-in Selenium wait activity. This is the mechanics with which we will execute explicit waiting.

More On Explicit Waits

It & # x27; s significant to set areasonably sizeddefault timeout for the explicit wait. But you want to be careful not to make it too high. Otherwise you run into a lot of the like timing number you get from implicit wait. But set it too low and your tests will be brittle, forcing you to run down little and transient subject. In our page object when we & # x27; re usingwait_for {is_displayed? FINISH_TEXT}we are telling Selenium to to see if the finish schoolbook is expose on the page. It will keep trying until it either returnstrueor range fifteen s -- whichever get first. If the behavior on the page lead longer than we expect (e.g., due to slow inherently slow load times), we can only adjust this one wait clip to fix the test (e.g.,wait_for (30) {is_displayed? FINISH_TEXT}) -- kinda than increase a blanket wait clip (which impact every test). And since it & # x27; s dynamic, it won & # x27; t always take the full amount of clip to complete.

Pro tip: Tools like SUSA can handle this autonomously — upload your app and get results without writing a single test script.

Part 2: Write A Test To Use The New Page Object

Now that we have our page object we can cable this up in a new test file.# filename: dynamic_loading_spec.rb

require & # x27; selenium-webdriver & # x27;
require_relative & # x27; dynamic_loading & # x27;

describe & # x27; Dynamic Loading & # x27; do

before (: each) do
@ driver = Selenium: :WebDriver.for: firefox
@ dynamic_loading = DynamicLoading.new (@ driver)
end

after (: each) do
@ driver.quit
end

it & # x27; Waited for Hidden Element & # x27; do
@ dynamic_loading.start
@ dynamic_loading.finish_text_present? .should be_true
end

end

When we run it (rspec dynamic_loading_page.rbfrom the command-line) it should pass, rather than throwing an exception (likein the final write-upwhen the element wasn & # x27; t present). As an aside -- an alternative approach would be to rescue the exception like this:

def is_displayed? (locator)
begin
@ driver.find_element (locator) .displayed?
rescue Selenium: :WebDriver: :Error: :NoSuchElementError
false
end
end

This would enable you to check the negative status for whether or not an element is display. And it can be used with an explicit wait as well (it won & # x27; t vary it & # x27; s behavior).

Part 3: Add A Second Test

Let & # x27; s footstep through one more dynamic page example to see if our explicit wait approach holds up.Our second exampleis set out similarly to the terminal one, the main difference is that it will furnish the final resultafterthe procession bar completes. Here & # x27; s the markup for it.

Dynamically Loaded Page Elements

Example 2: Element provide after the fact

Start

In order to find the chooser for the finish text element we need to inspect the page after the loading bar sequence finishes. Here & # x27; s what it appear like.

Hello World!

Before we add our examination, we need to modify our page objective to accommodate visiting the different example URLs.# filename: dynamic_loading.rb

class DynamicLoading

START_BUTTON = {css: & # x27; # start push & # x27;}
FINISH_TEXT = {id: & # x27; finish & # x27;}

def initialize (driver)
@ driver = driver
end

def visit_example (example_number)
@ driver.get & quot;http: //the-internet.herokuapp.com/dynamic\_loading/ # {example\_number}"
end

...

Now that we have that sorted, let & # x27; s add a new test to reference the markup shown above (and update our existing exam to use the new.visit_example method). # filename: dynamic_loading_spec.rb

require_relative & # x27; dynamic_loading & # x27;

describe & # x27; Dynamic Loading & # x27; do

...

it & # x27; Waited for Hidden Element & # x27; do
@ dynamic_loading.visit_example 1
@ dynamic_loading.start
@ dynamic_loading.finish_text_present? .should be_true
end

it & # x27; Waited for Element To Render & # x27; do
@ dynamic_loading.visit_example 2
@ dynamic_loading.start
@ dynamic_loading.finish_text_present? .should be_true
end

end

If we run these tests (rspec dynamic_loading_spec.rbfrom the command-line) then the same approaching will work for both cases. Explicit waits are one of the most important concepts in testing with Selenium. Use them much.

Published:
Mar 5, 2014
Share this post
Copy Share Link
LinkedIn
© 2026 Sauce Labs Inc., all rightfield reserved. SAUCE and SAUCE LABS are file trademarks possess by Sauce Labs Inc. in the United States, EU, and may be registered in other jurisdictions.
robot
quote

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free