Channels ▼
RSS

JVM Languages

Selenium: Cross-browser Website Testing


There appears to be a consensus in the Selenium community that "native" modes are the preferred way to "drive" browsers under test. Selenium 2.0, which is currently being actively developed, will merge with the Google WebDriver project, which provides another indication of the Selenium community to go "native".

Now, that you have a basic understanding of what Selenium is and how it works, let's take a brief overview of Selenium API, then continue to a more complex Selenium programming example.

Table 1 is a short and definitely not comprehensive list of essential Selenium API calls. I intentionally omitted the less frequently used commands as well as command arguments to make it more readable:

startLaunches the browser width a new Selenium session
stopKills the browser
typeSets the value of an input field, as though you typed it in
typeKeysSimulates keystroke events on the specified element
clickClicks on a link, button, checkbox or radio button
waitForPageToLoadWaits for a new page to load, usually used after click()
waitForConditionRuns the specified JavaScript snippet repeatedly until it evaluates to "true"
getEvalGets the result of evaluating the specified JavaScript snippet
selectSelect an option from a drop-down using an option locator
openOpens an URL in the test frame
openWindowOpens a popup window
selectWindowSelects a popup window using a window locator; once a popup window has been selected, all commands go to that window
selectFrameSelects a frame widthin the current window
isTextPresentVerifies that the specified text pattern appears
isElementPresentVerifies that the specified element is somewhere on the page
dragAndDropDrags an element a certain distance and then drops it
Table 1: Abbreviated list of Selenium API calls.

Table 1 demonstrates the richness of the Selenium API, but if you need something extra take a look at the getEval() method which effectively allows you to extend the Selenium functionality by running any Javascript code on the test page. If you find yourself using this quite a lot you may find the -userJsInjection Selenium server option handy which allows you to specify a Javascript file which will be injected into all pages.

Now let's take a look at a bit more complex web test which requires actual programming logic. This is where Selenium really shines. The following sample code tests for a common and frustrating error I'm sure you've seen at least once when you fill a long form online and press "Submit" only to discover that you made a mistake in CAPTCHA or password verification and have to fill the same form again. The code below verifies that the Yahoo email registration page preserves all entered fields if the CAPTCHA check fails:


 String url = "https://na.edit.yahoo.com/registration";
 Selenium selenium = new DefaultSelenium("localhost", 4444,"*firefox", url);
    selenium.start();
        
    selenium.open(url);    
    selenium.windowMaximize();
    selenium.type("firstname", "Vasya");
    selenium.type("secondname", "Pupkin");
    selenium.select("gender", "value=m");
    selenium.select("mm", "index=6");
    selenium.type("dd", "10");
    selenium.type("yyyy", "1917");
    selenium.select("country", "value=il");
    while (true) {
        try {
           Thread.sleep(200);
      } catch (InterruptedException e1) {            
    }
       if (selenium.isElementPresent("cimg"))
           break;
  }
    selenium.click("IAgreeBtn");
     while (true) {
         try {
            Thread.sleep(200);
      } catch (InterruptedException e1) {
    }
      if (selenium.isElementPresent("cimg"))
            break;
    }
    String firstname = selenium.getValue("firstname");
    String secondname = selenium.getValue("secondname");
    String gender = selenium.getValue("gender");
    String month = selenium.getValue("mm");
    String day = selenium.getValue("dd");
    String year = selenium.getValue("yyyy");
    String country = selenium.getSelectedLabel("country");
        
    System.out.println(firstname + " " + secondname + " " + gender + " " + month + " " + day + " " +        year + " " + country);
    selenium.stop();

If you run the above example you will see that the Yahoo registration page works as expected. As with the first example, this code does not need an extensive explanation, but some Selenium tricks may need a clarification.

After filling all the fields (I omitted some of them to make the code more readable) the test application waits for the element cimg to appear. This is the CAPTCHA image and if "the user" clicks before it is loaded Yahoo assumes that something's wrong with your browser Javascript. After pressing the "Create my account" button the test waits for the new page to load. You might think that the waitForPageToLoad() Selenium call is the right command to use here and you will be right, at least according to the documentation. In practice I've found this function to be unreliable and it is usually safer to test for the appearance of a certain element on the page in all but very simple cases, this is the reason there is a second piece of code that waits for the element cimg.

The last piece to the Selenium puzzle is a straightforward instruction on how to run this test. First you should add "import com.thoughtworks.selenium.*;" at the beginning of yor code, put "selenium-java-client-*.jar" somewhere in the path and don't forget to run the selenium server by issuing the "java -jar selenium-server-*-standalone.jar" command.

Selenium is a powerful tool for writing web site tests. It is under active development and I expect the Selenium community to add more exciting features in the near future and hope that they will also find the time to fix some of its bugs. As it often happens with open source projects, implementation of new functionality gets more attention than boring tests and bug fixes.

Selenium Projects

There is more to Selenium than just the RC. Selenium Core is the Javascript engine used by Selenium RC, but you can also deploy it standalone. It is actually more flexible than the RC in some ways, mostly because it can work with all browsers, but the downside is that you have to install it on the web server. If you find yourself running Selenium tests overnight than you may want to take a look at the Selenium Grid, which would allow you to run many tests in parallel on different machines in an easy, efficient and scalable way. Since the machines do not have to run the same OS you can also use it for cross browser/cross operating system tests. The last and certainly not the list project is Selenium IDE which is a Firefox add-on that records user actions such as clicks and text typing and produces a Selenium test that you can play back. This record can become a basis for your website tests.

—A.S.

However, Selenium is probably not the only automatic web site testing tool you will ever need. Even though it is often praised for its multiple browser testing capability in reality browsers other than Firefox and Internet Explorer are poorly supported. At the end of the day if you have to ensure that your web site works correctly under all important browsers your best bet is still a simple browser screenshot tool such as BrowserShots or BrowserSeal. The former is a free web-based screenshot service supporting a wide range of browsers, that unfortunately suffers from long response time while the latter is a screenshot application that has the advantage of speed and potentially can be integrated into automatic test scripts.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video