Selenium Commands & Locators Explained

A look at the common Selenium commands and locator methods.

In my first post I introduced Selenium IDE and stepped through creating and running your first test case and test suite. In this second post I am going to introduce some of the basic commands in Selenium, and the various methods used to locate elements with Selenium.

If you click the dropdown list of commands in Selenium IDE you’ll be faced with over 500(!) to choose from. Fortunately, many commands follow a pattern, which essentially extends the core commands. Once you understand this pattern, finding the commands you need becomes much easier.

Actions

It wouldn’t be too useful if we could only get values from a website, so there are also a whole bunch of action commands. I’ve listed some of the more commonly used ones below:

  • open – This will open the specified address
  • click – Clicks the element at the provided location
  • check – Toggles the checked value of a checkbox
  • type – Sends text input to an element
  • select – This will select the specified item in a list

In addition, most action commands in Selenium IDE also have a duplicate command with the AndWait suffix. When these are used the action is performed and a page load is expected and the command will not complete until the page has loaded or the timeout is reached. This simply saves using two commands, and the most common use of this is clickAndWait when a link opens a new page. When moving away from Selenium IDE this handy command is lost, and so is often implemented as a helper method in the chosen programming language.

Store, Check, and Wait

These commands ultimately get something from a website, for example if an element is present, or the value of a textbox. Instead of simply getting a value as you might expect, we can store, check, or even wait until it matches what we’re expecting. For these commands there are the following prefixes in Selenium IDE:

  • store – This will allow you to temporarily store a value.
  • verify – Performs a soft assertion against an expected value.
  • assert – Performs a hard assertion against an expected value.
  • waitFor – Waits until the value matches the specified value or the timeout is reached.

Note: As Selenium IDE can play your test back, it’s important that it can perform these actions. When you move out of the IDE you’ll find a more reduced number of available commands. Most of the above would instead have a prefix of get or is, and the storing/checking/waiting will be handled by your programming language or testing framework.

Triggering Events

One of the issues with Selenium 1.x (and therefore Selenium IDE) is that sometimes what you expect to happen, doesn’t. For example, perhaps typing into a text box is meant to enable the following textbox, or clicking an image creates a duplicate image. When using the type and click commands, you might find that certain JavaScript events aren’t firing. For this reason there are several alternative commands that may help. Some of these are listed below:

  • mouseDown / mouseUp – This simulates clicking the left mouse button.
  • keyDown / keyUp – Simulate the user pressing a key or releasing a key.
  • fireEvent – If all else fails you can fire the JavaScript event directly.

Fortunately, this is something that has been almost completely solved in Selenium 2. By performing ‘native’ events for supported operating systems, it should be no different using the sendKeys command to a real user typing keys on the keyboard.

Locating Elements

There are a few different strategies for locating elements on a page, and some are certainly better than others. You can either explicitly identify the locator type with a prefix, or let Selenium work out which strategy you’re using. Personally I prefer to be explicit and specify the prefix. Below I have listed the various locator types in the order I would always attempt to locate an element, for reasons of speed, robustness, and maintainability.

Identifier, id, name

Using the id of an element is by far the best way to locate it in Selenium. Assuming your web application adheres to the W3C specification that all id’s on a page are unique then you can’t be more targeted and unambiguous. Unfortunately there are many cases when an element does not have an id (or the id is somehow dynamically generated and unpredictable). In these cases you will need to use an alternative locator strategy, however it may be worth asking the developers of the web application if they can add a few ids to a page specifically for testing. It’s usually a trivial task for them and the robustness of your tests will benefit them too.

Of course it’s somewhat unlikely that every element on your page will have an id, so failing that it’s next worth seeing if the desired element has a name attribute. These don’t have to be unique, and Selenium will always assume you want the first matching element. It is unusual for a name to be repeated on a page, but I have seen it happen.

The identifier locator strategy is actually Selenium’s default. It will basically look for the first element that has the specified id or name attribute in that order. Personally I would avoid this way of locating elements as it can be ambiguous.

Examples:

<div id="register">
<label for="email" class="required">Email:</label>
<input id="email" name="register" class="required" type="text"/>
<label for="fullname" class="optional">Full Name:</label>
<input id="fullname" name="register" class=”optional" type="text"/>
</div>

To locate the email textbox from the HTML snippet using these strategies we could use:

  • id=email
  • name=register
  • identifier=email
  • identifier=register

To locate the fullname textbox we can’t use name because it shares the same name as the email textbox.

  • id=fullname
  • identifier=fullname

Note: As mentioned, the identifier locator strategy is Selenium’s default. This means that it is not necessary to include the identifier= prefix.

CSS

For situations where you’re unable to locate using the id or name strategies, my preferred fallback is CSS selectors. These are blazingly fast, and very powerful. Basically you’re hooking into how styles are applied to a page, and it’s very important that browsers are able to do that quickly. Unfortunately they’re a little more complex, but most of the time you should be able to stick with the basics.

It’s great if you can start by ‘anchoring’ your locator to an id, using the # symbol to identify it. Then you can optionally use things like the tag name, class attribute, and attribute or text contents of the target element. The best way to explain would be by showing a few examples.

Examples:

<div id="register">
<label for="email" class="required">Email:</label>
<input id="email" name="register" class="required" type="text"/>
<label for="fullname" class="optional">Full Name:</label>
<input id="fullname" name="register" class="optional" type="text"/>
</div>

To locate the email label in the above HTML snippet you could use one of:

css=#register label[for=email]

This starts at the element with id of register and then locates a label element beneath that has a for attribute with the value ‘email’

css=label:contains(Email:)

This locates the first label element on the page that has text contents of ‘Email:’

css=.required

This locates the first element on the page with a class of ‘required’.

Note: Elements may have more than one class, however you don’t need to list them all. Only specify enough to unambiguously locate the element. You can chain classes by separating them will a period. For example css=label.required.important

XPath

XPath gets quiet a bad press with regards to Selenium testing, and is sometimes the reason people ‘give up’ with their test automation. Basically, XPath is very powerful, it treats the web page as a structured document (which it is), and allows you to traverse the hierarchy of nodes (elements).

The two common misconceptions of XPath are: it’s slow, and it’s brittle. These are only true of complex XPaths that are heavily dependent of the structure of your web page. It’s true that in general XPath is slower than CSS locators, but you can just as easily write complex and brittle CSS locators.

XPath is one of the locator strategies often used when Selenium IDE is recording a test. The brittleness and speed issues can be mostly avoided by using simple and relative XPaths. This means finding an element near the one you want that you can locate quickly and easily (great if it has an id), and then describing how to get to your target element. As with CSS, some examples will help me to explain.

Examples:

<div id="register">
<label>Email:</label>
<input type="text"/>
<label>Full Name:</label>
<input type="text"/>
</div>

To locate the fullname textbox in the above HTML snippet you could use the following:

xpath=id(‘register’)/input[2]

This locates the second input element beneath the element with an id value of ‘register’

xpath=//label[text()=‘Full Name:’]/following-sibling::input

This first locates a label element with the text contents of ‘Full Name:’ and then moves onto the following input element

The more complex your XPath gets, the longer it could take for the browser to find your element, and the more dependent your locator is on the structure of the page. This means that minor changes to the HTML on the page that cause no functional changes could quite easily cause your tests to fail.

Link

You can also locate links based on their text. This is a very simple locator strategy, but one I try to avoid for a few reasons. First, there could be multiple links with the same text (such as repeated header and footer navigation) that mean your tests become ambiguous. Second, someone might decide to change “Submit” to “Continue”, and suddenly your text fails even though the meaning of the link is the same. Finally, if you are testing an application that is localised then your tests will only work on the localisation you’ve written them against.

For more information on Selenium commands and locators I would recommend the official documentation.

If you have any questions you might find the Selenium Users group useful.

If you find any issues in Selenium please check if it’s already been raised on the official issue tracker before raising a new report with as much information as possible.

You might be interested in... A Day of Lean Software Testing

Tags: ,

7 Responses to “Selenium Commands & Locators Explained”

  1. Michael JohnstonApril 7, 2011 at 11:27 am #

    Great breakdown of selenium Locators. Its a good resource for getting people up to speed with the concepts. Looking forward to the one where you describe IDE-extensions.js and creating your own locator strategies. :)

  2. Roger PadillaApril 8, 2011 at 12:31 am #

    Very useful and very well explained, thank you.

  3. elegApril 17, 2011 at 3:25 am #

    about links :

    * according to accessibility guidelines (WCAG 2.0), same text links should have same destination url, so ambiguity is not really a problem there.

    * if you want to check the “quality” of the link’s text (from a writer’s point of view), it is a good thing that the test detect it has changed, don’t you think? (2 different words never have /strictly/ the exact same meaning, and the act of choosing between them should be the result of usability tests, not a programmer’s whim) :-)

  4. Bindu LaxminarayanApril 26, 2011 at 7:26 am #

    Good examples for locators. Nice work :)

  5. kunalSeptember 14, 2011 at 9:22 am #

    nice explanation of selenium

Trackbacks/Pingbacks

  1. A Smattering of Selenium #46 « Official Selenium Blog - April 11, 2011

    […] Selenium Commands & Locators Explained is the next in Dave Hunt’s guest series at the Software Testing Club. Pay extra attention to the last sentence of the Link section […]

  2. selenium-IDE explain « selenium automation testing - April 28, 2011

    […] selenium-IDE explain http://blog.softwaretestingclub.com/2011/04/selenium-commands-locators-explained/ […]