This page is intended for sharing ideas and resources related to using Selenium and Selenium IDE

{composition-setup}
{composition-setup}
{deck:id=beef jerky}
{card:label=Selenium How To}

Selenium: For Regression testing, Acceptance testing and setting up Test Environments with Sites, Users and Seed Data.

Selenium IDE is an integrated development environment for Selenium tests. It is implemented as a Firefox extension, and allows you to record, edit, and debug tests. You can choose to use its recording capability, or you may edit your scripts by hand.

Setting up Selenium IDE

AdBlock Plus is no longer needed to run the Selenium scripts referenced here.

  1. You can download the extension here. You will then be able to run any of the scripts attached to this page right in your browser.
  2. Some of the scripts (including the environment setup scripts) require that you upload certain files. These files can be found in the TestingData.zip file. If you are using any of these scripts and you are not on the network you will need to download this file and unzip. Additionally, anywhere in the scripts where a file needs to be uploaded you will need to change the default path to that of downloaded TestingData file. There are comments in the scripts where this action will be necessary.
  3. Finally, you will need to add this file user-extensions.js to Selenium. To do so, open up Selenium IDE and select Options from the Options menu. Use the Browse button to select the file and then select OK. You will now need to close and reopen open Selenium IDE for the changes to take affect.

You are now ready to begin recording and running the tests.

Recording Tests

This is a very (I repeat, very) general idea on how to record tests with Selenium IDE. Just remember that once you have it open it is already in record mode and will be recording any actions you make in the browser.

Once you have finished recording your tests there are a couple of basic things you want to do to it right away. First of all, remove 'selectWindow' and 'selectFrame' commands from your test. If you are testing a JSF tool (eg. Samigo, Melete) you will most likely want to use XPath instead of what was recorded in the Target field. JSF tools use randomly generated element id's which will change from session to session, instance to instance. For help with XPath select teh next tab.

To playback the test you just recorded (and edited) all you need to do is push the Play button. Of course, depending on where you started recording from, you may need to log out or go to a different worksite.

Sakai 2.5 Selenium scripts

https://source.sakaiproject.org/contrib/qa/trunk/functional/2.5

Sakai 2.6 Selenium scripts

https://source.sakaiproject.org/contrib/qa/trunk/functional/2.6

Sakai 2.7 Selenium scripts

https://source.sakaiproject.org/contrib/qa/trunk/functional/2.7/Selenium

Test Suite Automation

Selenium IDE

To automate your tests there are a few things you need to do. First of all you need to make sure all the tests you made in Selenium IDE are saved as .html or .htm files. You can save your test as an html or htm file when you create it.

Now, in the directory of all your tests, you need to make an html file called TestSuite.htm (a sample can be found in SVN). This file should contain a simple array of links to each of your test html's. Remember TestSuite.htm should be kept in the same directory as all your tests.

Next, open Firefox and Selenium IDE. From the Selenium IDE File menu select Open Test Suite... and then select the TestSuite.htm. You will now have the Test Suite loaded into the sidebar of Selenium IDE. If you select the the first Play button you will run through the entire suite, while selecting the second Play button will run through only the test you have selected.

Using the TestNG testing framework with Selenium

Running your test suites in Selenium IDE is ok, but it doesn't provide the hands off automation and reporting features of a full testing framework. No worries, Selenium works great with TestNG. Go here for more detail.

{card}
{card:label=XPath}
{composition-setup}{composition-setup}

Practical XPath Examples

To see code examples select the XPath notation

Any element that has an attribute (The first matching element will be selected):

{toggle-cloak:id=1}
//input[@value='submit']

{cloak:id=1}
<input type="image" src="/library/skin/rsmart/images/loginButton.gif" value="submit"/>
{cloak}

Any element that 'contains' an attribute with specific text:

{toggle-cloak:id=2}
//a[contains(@href,'resources.doc&')]

{cloak:id=2}
<a title="Attach a copy" href="localhost:8080/resources.doc&sakai_action=doAttachitem">Attach a copy</a>
{cloak}

Any element that 'contains' specific text but has no attribute:

{toggle-cloak:id=3}
//label[contains(text(),'Correct Answer (optional)')]

{cloak:id=3}
<label>Correct Answer (optional)</label>
{cloak}

Any element that has specific text that is surrounded by white space and has no usable attribute:

{toggle-cloak:id=4}
//a[normalize-space(.)='Assignment 1']

{cloak:id=4}
<a href="http://localhost:8080?assignmentId=/assignment/a/=Main&sakai_action=doView_assignment">
			Assignment 1                                     </a>
{cloak}

Any element that has specific text that is preceded by another element that 'contains' specific text:

{toggle-cloak:id=5}
//td[contains(text(),'Rose, Emma(erose)')]/div/a[text()='Grade']

{cloak:id=5}
<td headers="studentname">
Rose, Emma(erose)
<div class="itemAction">
<a title="Grade submission" href="http://localhost:8080=Main&sakai_action=doGrade_submission">Grade</a>
</div>
{cloak}

Some more examples using sample code

Axes break xpaths into "steps". /descendant:: and /following-sibling:: will probably both come in handy someday.

//table/descendant::td[5]

<table>
    <tbody>
        <tr>
            <td />
            <td />
            <td />
            <td />
            <td result="true" />

Predicates refine an xpath, without being included in the results. and and or can be used to combine multiple conditions in a single predicate.

//table/descendant::td[@class='foo']

<table>
    <tbody>
        <tr>
            <td class="koo" />
            <td class="foo" result="true" />

Functions that are useful in predicates: contains(), starts-with(), position(), normalize-space()

//table/descendant::td[@class='foo' and contains(text(), 'bar')]

<table>
    <tbody>
        <tr>
            <td class="foo">moo</td>
            <td class="foo" result="true">candybar</td>
            <td class="foo">hoo</td>

Each step typically evaluates to a "nodeset", basically a list of results. The results from the previous step are the input into the next step.

//table/descendant::td[@class='foo' and contains(text(), 'bar')]/a

<table>
    <tbody>
        <tr>
            <td class="foo">moo</td>
            <td class="foo">candybar <a result="true">crunch</a></td>

Helpful Links

XPath Tutorial

XPath Reference

Selenium XPath Wiki

Useful Firefox Add-ons

Firebug

XPath Checker and XPather

{card}
{deck}