Posts Tagged ‘selenium tips’

Selenium Tips: Upload files on browsers running over remote machines

November 13th, 2009 by Santiago Suarez Ordoñez

Having your tests upload files to the test application is something that becomes confusing when moving Selenium RC servers to different machines.

Browsers can only upload files from the local machine, but when the RC server (and consequently the browser) are on a different machine than the one running the test, this can be very hard to do.

Luckily, for this kind of situations, Selenium has the attach_file method which receives both a locator and a URL as parameters, then the RC Server takes care of downloading the file to the test machine at a temporary location and then attaching the file completing with this path in the desired field.
Here’s the reference from Selenium’s documentation:

In [5]: sel.attach_file?
Definition:    a.attach_file(self, fieldLocator, fileLocator)
Docstring:
Sets a file input (upload) field to the file listed in fileLocator
'fieldLocator' is an element locator
'fileLocator' is a URL pointing to the specified file.
Before the file  can be set in the input field (fieldLocator), Selenium RC may need to transfer the file to the local machine before attaching the file in a web page form.
This is common in selenium  grid configurations where the RC server driving the browser is not the same  machine that started the test.
Supported Browsers: Firefox ("*chrome") only.

Keep in mind that for using this method the files to upload will have to be placed in a public URL. However, if you don’t want them to be 100% public, you can still keep them safe using basic HTTP Auth and get them using the auth information in the same URL.

Here’s an example usage of the command in python:

sel.attach_file("css=input[type=file]", "http://url.com/file.txt")

Some caveats in Selenium’s implementation, is that this only works on firefox and that also the file must be placed on top level in the URL, so using the following URL will not work:

http://saucelabs.com/subdirectory/subdirectory2/file.txt

while the following will:

http://saucelabs.com/file.txt

In Sauce OnDemand, we took care of fixing both issues + adding ftp support too, so if you used Sauce OnDemand, just put your files in a public server (both HTTP or FTP) and then just use attach_file to upload them.

Hope you find this useful, and if you need more info, let us know in the comments.

Selenium Tips: Start improving your locators

October 30th, 2009 by Santiago Suarez Ordoñez

Almost everyone in the Selenium testing world knows of the power of XPATH as a locating strategy, at the same way, most of them also know of its slowness on IE.

Now, if your tests have relatively simple XPATH  locators, putting some effort to change them to CSS (which has native support on all browsers) is a very good investment and will impact your tests with instant time improvements.

For this week’s tip, we’ve decided to start addressing the basic rules for the move of simple locators from XPATH to CSS.

Direct child

A direct child in XPATH is defined by the use of a “/“, while on CSS, it’s defined using “>

Examples:

//div/a

css=div > a

Child or subchild

If an element could be inside another or one it’s childs, it’s defined in XPATH using “//” and in CSS just by a whitespace

Examples:

//div//a

css=div a

Id

An element’s id in XPATH is defined using: “[@id=’example‘]” and in CSS using: “#

Examples:

//div[@id='example']//a

css=div#example a

Class

For class, things are pretty similar in XPATH: “[@class=’example‘]” while in CSS it’s just “.

Examples:

//div[@class='example']//a

css=div.example a

Thats’ all for now, as you can see, the first rules a pretty simple, and you even make you locators shorter and cleaner.

Stay tuned for our next Tip of the Week, we will keep addressing more complex locators soon!

Selenium Tips: Taking ScreenShots on the Server

October 23rd, 2009 by The Sauce Labs Team

Taking screenshots of tests as they run is a great tool for discovering rendering issues with your pages. However, taking screenshots from SeleniumRC can be a bit hard, especially if you’re using it in a grid or are using a service like ours. Luckily Selenium provides a command that’s perfect for getting past exactly these kinds of configuration problems, `captureScreenshotToString`. It returns a base64 encoded png of the current page, which you can then write to a file on your local machine. Here’s an example in python:

def test_case(self):
        browser = self.browser
        browser.open("/")
        png = browser.capture_screenshot_to_string()
        f = open('screenshot.png', 'wb')
        f.write(png.decode('base64'))
        f.close()

Tune in next week for another Selenium Tip of The Week!

Selenium Tips: Infinite Loops Take Forever

October 16th, 2009 by The Sauce Labs Team

In Selenium, it’s a (semi-)common idiom to loop on an element that you expect to exist in the near future.  One way we have seen this done is to create an infinite loop checking for the new element

while not selenium.is_text_present(
                       'logged in'):
    pass

This code causes alarm bells because if ‘logged in’ never appears it will loop until you kill the test!  To solve this problem, you should set an explicit timeout on every query like this, for example

start = time.time()
timeout = 60
found = False
while start + timeout < time.time():
    if selenium.is_text_present('logged in'):
        found = True
        break
    time.sleep(0.25)
self.assert_(found)

With this code your query will expire after the timeout, though it does suffer from a serious DRY failure so it’s a perfect candidate for refactoring into a method

def with_timeout(test, value, timeout=60):
    start = time.time()
    found = False
    while start + timeout < time.time():
        if test(value):
            found = True
            break
        time.sleep(0.25)
    return found

Which you would use in a regular assert like this

self.assert_(
    with_timeout(selenium.is_text_present,
                   value))

This simple change will make your jobs finish reliably in error cases and increase the readability of your logs.

Tune in next week for another Selenium Tip of The Week from Sauce Labs.

Selenium Tips: Improving your waiting skills

October 7th, 2009 by Santiago Suarez Ordoñez

Waiting for elements to appear in your page is something we do pretty much everywhere in our tests, but the way you wait for them to do it can impact in the efficiency of your scripts in interesting ways.

Let’s analyze a test that has a step like the following:

waitForElementPresent css=h2:contains(‘Sauce Labs’) 60000

This waits for the title “Sauce Labs” to appear, which will work as expected most of the times. But, what if you app fails and the title’s text loaded is incorrect? It will take the script to eat the whole 60 second timeout before noticing and reporting it.

Then, a much better approach to write this kind of waiting is:

waitForElementPresent css=h2.titles_class 60000
assertText css=h2.titles_class Sauce Labs

It will now detect the title is loaded at the moment it does, no matter which content it has, and then move on to assert for it’s text.

As you can see, a simple change in your scripts like this one will make them both run faster and report errors more accurately.

Stay tuned, we’ll be bringing more tips to improve your Selenium tests every week.