Notesss on Selenium 1

8
Notes on Selenium 1 Introduction Selenium is the base name for a portable test framework for web applications. Selenium works well for QA testers needed record/playback authoring of test and for software developers needed to author tests in Java, Ruby, Python, PHP and several other languages using the Selenium API. It was created by ThoughtWorks and is open-source software. There are several variants of Selenium. First, a quick overview of the bits and pieces of Selenium version 1: Selenium IDE (S-IDE): A Firefox plug in that lets you record browser actions (navigation, clicks, input) and play back those. You can write assertions to check for things like text, elements, etc. Scripts can be saved out as HTML or exported to Java, Ruby, C#, and a few others. You can write your own templates for outputting scripts. Selenium Remote Control (Selenium RC): A Java-based server app that launches, manages, and kills browser sessions. You start up RC, then run tests written in one of the various supported languages (lots of client libraries around), and RC does the rest. RC lets you run your tests against different browser platforms. If your scripts are simple, you can run one test suite against Firefox, IE, and Chrome without re- writing. Selenium Core: This is the basic framework for both S-IDE and RC. When you spin up RC you’re getting core as part of the environment. Selenium Grid: Manages splitting off test suites to run your tests in parallel, thereby massively speeding up your tests. There are a variety of development tools and wrappers for Selenium 1, including a Maven plug-in. Development on Selenium 2 started about two years ago and is covered in our document “Notes on Selenium WebDriver”. It is recommended that new development use Selenium 2, but there is much legacy code of tests written using Selenium 1. Resources A Reference card for Selenium 1 is available at http://refcardz.dzone.com/refcardz/getting-started-selenium There is a good Selenium 1 reference at http://release.seleniumhq.org/selenium-core/0.8.0/reference.html Page 1

description

seleniun

Transcript of Notesss on Selenium 1

Page 1: Notesss on Selenium 1

Notes on Selenium 1

IntroductionSelenium is the base name for a portable test framework for web applications. Selenium works well for QA testers needed record/playback authoring of test and for software developers needed to author tests in Java, Ruby, Python, PHP and several other languages using the Selenium API. It was created by ThoughtWorks and is open-source software.

There are several variants of Selenium. First, a quick overview of the bits and pieces of Selenium version 1:

Selenium IDE (S-IDE): A Firefox plug in that lets you record browser actions (navigation, clicks, input) and play back those. You can write assertions to check for things like text, elements, etc. Scripts can be saved out as HTML or exported to Java, Ruby, C#, and a few others. You can write your own templates for outputting scripts.

Selenium Remote Control (Selenium RC): A Java-based server app that launches, manages, and kills browser sessions. You start up RC, then run tests written in one of the various supported languages (lots of client libraries around), and RC does the rest. RC lets you run your tests against different browser platforms. If your scripts are simple, you can run one test suite against Firefox, IE, and Chrome without re-writing.

Selenium Core: This is the basic framework for both S-IDE and RC. When you spin up RC you’re getting core as part of the environment.

Selenium Grid: Manages splitting off test suites to run your tests in parallel, thereby massively speeding up your tests.

There are a variety of development tools and wrappers for Selenium 1, including a Maven plug-in.

Development on Selenium 2 started about two years ago and is covered in our document “Notes on Selenium WebDriver”. It is recommended that new development use Selenium 2, but there is much legacy code of tests written using Selenium 1.

ResourcesA Reference card for Selenium 1 is available at http://refcardz.dzone.com/refcardz/getting-started-selenium

There is a good Selenium 1 reference at http://release.seleniumhq.org/selenium-core/0.8.0/reference.html

There is a good article on writing Selenium scripts at http://us1.campaign-archive.com/?u=8a43ccdb821548b314780e0f3&id=5c4d715177

Good list of frequently used commands at http://mishmashmoo.com/blog/?p=100

Selenium 1.0 Testing Tools: Beginner's Guide by David Burns. Packt Publishing, Nov 11, 2010.

Selenium 1 ReferenceBasic elements of Selenium include the Selenium object itself, which a proxy for the operations within the browser. There are some 500 different methods provided, which correspond to different clicking, typing, and navigation operations, combined with ways of locating information in the HTML of the screen.

The structure of a typical test is to open pages, check for the contents of elements on the page, take actions on the page through those elements, and verify results.

Note that in Selenium 2, the API is much more object-oriented, with objects for each of the types the page elements, while in Selenium 1 there are specific-named API calls on the Selenium object.

Page 1

Page 2: Notesss on Selenium 1

Fortunately, many API calls (these are known as ‘Selenese’ commands) follow a pattern, which essentially extends the core commands. Once you understand this pattern, finding the commands you need becomes much easier.

Locating ElementsThere 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, nameUsing 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=registerTo locate the fullname textbox we can’t use name because it shares the same name as the email textbox.

id=fullname

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

CSSFor 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.

Page 2

Page 3: Notesss on Selenium 1

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=.requiredThis 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

XPathXPath gets quite 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: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

Page 3

Page 4: Notesss on Selenium 1

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.

The use of XPath is basically the only way to locate an element or text in a specific part of the page.

LinkYou 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 localized then your tests will only work on the localization you’ve written them against.

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

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 WaitThese 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.

Page 4

Page 5: Notesss on Selenium 1

Triggering EventsOne 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.

Most Commonly-Used Methodsselenium.open(url)selenium.type(locator, string)selenium.click(locator)selenium.submit(locator)selenium.getText(locator)selenium.getValue(locator)

You can also fetch the entire body text content of the current screen using selenium.getBodyText(). This is helpful when trying to determine if the page is correct when debugging tests.

The Page Object PatternThis is an approach in which the Selenium logic is encapsulated in an object which is created and wrapped around the Selenium connection as the test runs. Each such object typically corresponds to a page, or screen. Hence, you have a LoginPage object, which provides Java-callable methods to enter the user name and password.

Here is an example:

public class LoginPage {private static final String URL = "/SP02/";

private Selenium selenium;

public static LoginPage open(Selenium selenium) {return new LoginPage(selenium, URL);

}

public LoginPage() {verifyPage();

}

private LoginPage(Selenium selenium, String url) {this.selenium = selenium;

selenium.open(url);verifyPage();

}

private void verifyPage() {if (!selenium.isTextPresent("User")

|| !selenium.isTextPresent("Password")) {throw new RuntimeException("Invalid login page");

Page 5

Page 6: Notesss on Selenium 1

}}

public void setName(String name) {selenium.type("j_username", name);

}

public void setPassword(String password) {selenium.type("j_password", password);

}

public HomePage submit() {selenium.submit("f");return new HomePage(selenium);

}}

The most important methods here are the constructors and the verifyPage() method.

Page Objects have emerged as a very-effective way to use Selenium, but it is up to you to create the page object abstraction, as there is not a lot of object-oriented support within the Selenium 1 API.

Using Selenium in GrailsThe Selenium-RC plug-in provides a wrapper for using the Selenium object, and a script which runs the tests and handles storing of test results, etc.

In order to help you get started with creating Page Objects, the library includes four abstract page object classes, one for each of the four basic Grails CRUD screens: list, show, edit, and create.

Page 6