Some webpage elements can be tricky to locate, especially when they do not have id or name attributes. For such cases, testers can combine CSS selectors.
Let’s look at one example below. Using Firebug, inspecting the value of the PAYABLE AT THE HOTEL – BALANCE field in the page show us its location.
As displayed, the element tell us that it is a table data (hence td) that has a right-label class and some style:
td class=”right-label” style=”width: 30%; padding-top: 7px;”
Which we can try to target in the following three ways:
- Element Selector: css=td
- Text Selector: css=td:contains(“PHP 2,559.78”)
- Class Selector: css=td.right-label
All three selectors will fail though. The first (element) selector will point the automated test case to the first td in the table, not the last. The second (text) selector will correctly refer the automated test to the desired element but will fail when there are two or more elements in the page with the same value; also, what if we want to get the value of the element assuming that they do not know its value yet? The third (class) selector will direct the test to the first td in the table with a right-label class, which in the page is the prepayment, not the balance payable.
In order to target specific page elements having the same attributes as other elements in the page, commonly found in tables, we need to combine selectors of different elements. To do this, we need to remember two things:
- + (to be used when an element selector and the succeeding element selector share the same parent selector)
- > (to be used when the succeeding element selector is a child of the preceding element selector)
Looking back at our example, we can see that our target element has a sibling (the td above it), as shown below:
And using this information, we can now modify our class selector (using +) and test it in Selenium IDE:
css=td + td.right-label
This will, however, still point our test towards an incorrect element, and thus needs further modification. Let’s try adding the parent element (using >) above our desired element and do another test.
css=tr.price-light > td + td.right-label
Our automated test now points us to the prepayment value. Close, but not quite. Lets do one more modification, adding the next tr element above our parent element, which is it’s sibling.
css=tr.price-light + tr.price-light > td + td.right-label
Now, that works! 🙂