Selenium Testing Tools Cookbook Pdf Download
Chapter 1. Locating Elements
In this chapter, we will cover:
-
Using browser tools for inspecting elements and page structure
-
Locating an element using the findElement method
-
Locating elements using findElements method
-
Locating links
-
Locating elements by tag name
-
Locating elements using CSS selectors
-
Locating elements using XPath
-
Locating elements using text
-
Locating elements using advanced CSS selectors
-
Using jQuery selectors
-
Locating table rows and cells
-
Locating child elements in a table
Introduction
The success of automated GUI ( Graphical User Interface ) tests depends on identifying and locating GUI elements from the application under test and then performing operations and verifications on these elements to achieve the test flow. This boils down to the test tool's ability to recognize various GUI elements effectively.
Selenium WebDriver provides one of the advanced techniques for locating elements on web pages. Selenium's feature-rich API provides multiple locator strategies such as Name, ID, CSS selectors, XPath, and so on. We can also implement custom locator strategies for locating elements.
In this chapter, we will explore more on how to use locator strategies by starting with ID, Name, and Class.
In any web development project, it is always a good practice to assign attributes such as Name, IDs, or Class to GUI elements. This makes the application more testable and conforms to accessibility standards. However, following these practices is not always possible. For such scenarios, we have to use advanced locator strategies such as CSS selector and XPath.
While CSS selector and XPath are popular among Selenium users, CSS selector is highly recommended over XPath due to its simplicity, speed, and performance.
Using browser tools for inspecting elements and page structure
Before we start exploring locators, we need to analyze the page and elements to understand how these are structured in the application, what properties or attributes are defined for the elements, how JavaScript or AJAX calls are made from the application, and so on.
Browsers render visual elements of the application for end users by hiding the HTML code and other resources. When we want to automate interaction with the application using Selenium WebDriver, we need to look carefully at the background code written to render pages and elements in browsers. We need to identify information such as attribute values and elements structure for locating elements and perform user actions using Selenium WebDriver API.
Here is an example of a BMI Calculator application page and HTML code written to render this page in a browser as displayed in the following screenshots:
You can view the code written for a page by right-clicking in the browser window and selecting the View Page Source option from the pop-up menu. This will display the HTML code of the page in a separate window. This might look messy and difficult to understand.
We need special tools that can display this information in a structured and easy to understand format. In this recipe we will briefly explore few of these tools before we dive into locators.
How to do it...
In the following sections we will explore some of the tools which are in-built in browsers and plugins to analyze elements and page structure. These tools will help us to understand how elements and their attributes are defined on a page, DOM structure, JavaScript calls, CSS Style attributes, and so on.
Inspecting pages and elements with Firefox using Firebug add-in
The newer versions of Firefox provide in-built ways to analyze the page and elements; however, we will use the Firebug add-in which has more powerful features. You need to install the Firebug add-in in Firefox from https://addons.mozilla.org/en-us/firefox/addon/firebug/.
To inspect an element from the page, move the mouse over the desired element and right-click to open the pop-up menu. Select the Inspect Element with Firebug option as shown in the following screenshot:
This will display Firebug with HTML code in a tree format as shown in the following screenshot:
Firebug provides various other debugging features. It also generates XPath and CSS selectors for elements. For this, select the desired element in the tree and right-click and select Copy XPath or Copy CSS Path option from the pop-up menu as shown in the following screenshot:
This will paste the possible XPath or CSS selector value on the clipboard.
Inspecting pages and elements with Google Chrome
Google Chrome provides an in-built feature to analyze pages and elements. This is very similar to Firebug. You can move the mouse over a desired element on the page and right-click to open the pop-up menu, then select Inspect element option. This will open Developer Tools in the browser, which displays information similar to that of Firebug, as shown in the following screenshot:
Chrome Developer Tools also provide a feature where you can get XPath for an element by right-clicking on the desired element in the tree and selecting the Copy XPath option from the pop-up menu.
Inspecting pages and elements with Internet Explorer
Similar to Google Chrome, Microsoft Internet Explorer also provides an in-built feature to analyze pages and elements.
To open the Developer Tools, press the F12 key. The Developer Tools section will be displayed as shown in the following screenshot:
To inspect an element, click on the pointer ( ) icon and hover over the desired element on the page. Developer Tools will highlight the element with a blue outline and display the HTML code in a tree as shown in the following screenshot:
How it works...
Browser Developer Tools come in handy during test development. These tools will help you in finding the locator details for elements. These tools parse the code for a page and display the information in a hierarchal tree. These tools also provide information on how styles have been applied, page resources, page DOM (Document Object Model), JavaScript code, and so on.
Some of these tools also provide the ability to run JavaScript code for debugging and testing.
In the following recipes we will explore various types of locators that are supported by Selenium WebDriver and these tools will help you in finding and deciding various locator strategies or methods provided by Selenium WebDriver API.
Locating an element using the findElement method
Locating elements in Selenium WebDriver is done by using the findElement()
and findElements()
methods provided by WebDriver and WebElement class.
The findElement()
method returns a WebElement
object based on a specified search criteria or throws up an exception if it does not find any element matching the search criteria.
The findElements()
method returns a list of WebElements
matching the search criteria. If no elements are found, it returns an empty list.
Find methods take a locator or query object as an instance of By
class as an argument. Selenium WebDriver provides By
class to support various locator strategies. The following table lists various locator strategies supported by Selenium WebDriver:
Strategy | Syntax | Description |
---|---|---|
By ID | Java: C#: Python: Ruby: | Locates an element the using ID attribute |
By name | Java: C#: Python: Ruby: | Locates an element using the Name attribute |
By class name | Java: C#: Python: Ruby: | Locates an element using the Class attribute |
By tag name | Java: C#: Python: Ruby: | Locates an element using the HTML tag |
By link text | Java: C#: Python: Ruby: | Locates link using it's text |
By partial link text | Java: C#: Python: Ruby: | Locates link using it's partial text |
By CSS | Java: C#: Python: Ruby: | Locates element using the CSS selector |
By XPath | Java: C#: Python: Ruby: | Locates element using XPath query |
In this recipe, we will use the findElement()
method to locate elements.
How to do it...
Locating elements using id
, name
, or class
attributes is the preferred way to find elements. Let's try using these methods to locate elements as described in the following sections.
Finding elements by the ID attribute
Using the id
attribute is the most preferable way to locate elements on a page. The W3C standard recommends that developers provide an id
attribute for elements that are unique to each element. Having a unique id
attribute provides a very explicit and reliable way to locate elements on the page.
While processing the DOM, browsers use id
as the preferred way to identify the elements and this provides the fastest locator strategy.
Let's now look at how to use id
attributes for locating elements on a login form.
<form name="loginForm"> <label for="username">UserName: </label> <input type="text" id="username" /><br/> <label for="password">Password: </label> <input type="password" id="password" /><br/> <input name="login" type="submit" value="Login" /> </form>
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
To locate the User Name and Password fields, we can use the id
attribute in the following way:
WebElement username = driver.findElement(By.id("username")); WebElement password = driver.findElement(By.id("password"));
Finding elements by the Name attribute
Locating elements with the id
attribute is the most preferred locator strategy, but you might find situations where you cannot use the id
attribute due to the following reasons:
-
Not all elements on a page have the
id
attribute specified -
The
id
attributes are not specified for key elements on a page -
The
id
attribute values are dynamically generated
In this example, the login form elements use the name
attribute instead of the id
attribute:
<form name="loginForm"> <label for="username">UserName: </label> <input type="text" name="username" /><br/> <label for="password">Password: </label> <input type="password" name="password" /><br/> <input name="login" type="submit" value="Login" /> </form>
We can use the name
attribute to locate elements in the following way:
WebElement username = driver.findElement(By.name("username")); WebElement password = driver.findElement(By.name("password"));
Unlike id
, the name
attribute may not be unique on a page. You might find multiple elements with similar name
attributes and in such a case, the first element on the page with the specified value will be selected, which may not be the element you are looking for. This may cause the test to fail.
Tip
When building a testable application, you should recommend that the developers add the id
attribute for key elements as well as other unique attributes to enable the easy location of elements.
Finding elements by the Class attribute
Apart from using the id
and name
attributes, you can also use the class
attribute to locate elements. The class
attribute is provided to apply CSS to an element.
In this example, the login form elements use the class
attribute instead of the id
attribute:
<form name="loginForm"> <label for="username">UserName: </label> <input type="text" class="username" /></br> <label for="password">Password: </label> <input type="password" class="password" /></br> <input name="login" type="submit" value="Login" /> </form>
We can use the class
attribute to locate elements in the following way:
WebElement username = driver.findElement(By.className("username")); WebElement password = driver.findElement(By.className("password"));
How it works...
Selenium WebDriver API provides the findElement()
method to locate the elements that are required in a test from the page under test.
When locating an element matching specified criteria, it looks through the DOM ( Document Object Model ) for matching elements and returns the first matching element to the test.
There's more...
The WebElement
class also supports find methods that find child elements. For example, imagine that there are some duplicate elements on a page. However, they are located in separate <div>
elements. We can first locate the parent <div>
element and then locate the child element within the context of the <div>
element in the following way:
WebElement div = driver.findElement(By.id("div1")); WebElement topLink = div.findElement(By.linkText("top"));
You can also a use a shortcut method in the following way:
WebElement topLink = driver.findElement(By.id("div1")).findElement(By.linkText("top"));
NoSuchElementFoundException
The findElement()
and FindElements()
methods throw up the NoSuchElementFoundException
exception when they fail to find the desired element using the specified locator strategy.
See also
-
The Locating elements using findElements method recipe
Locating elements using findElements method
Selenium WebDriver provides the findElements()
method, which enables the acquisition of a list of elements matching the specified search criteria. This method is useful when we want to work with a group of similar elements. For example, we can get all the links displayed on a page or get rows from a table, and so on.
In this recipe, we will get all the links and print their targets by using the findElements()
method.
How to do it...
Let's create a test which will get all the links from a page and verify the count of links and print target for each link as follows:
@Test public void testFindElements() { //Get all the links displayed on Page List<WebElement> links = driver.findElements(By.tagName("a")); //Verify there are four links displayed on the page assertEquals(4, links.size()); //Iterate though the list of links and print //target for each link for(WebElement link : links) System.out.println(link.getAttribute("href")); }
How it works...
The findElements()
method returns all the elements matching with the locator specified as a list of WebElements
. In Java, we can use the List
class to create an instance of list of WebElements
.
List<WebElement> links = driver.findElements(By.tagName("a"));
The size()
method of the List
class will tell us how many elements are there in the list.
assertEquals(4, links.size());
We can iterate using this list in the following way, getting a link and printing its target value:
for(WebElement link : links) System.out.println(link.getAttribute("href"));
See also
-
The Locating an element using the findElement method recipe
Locating links
Selenium WebDriver provides multiple ways to locate links. You can locate a link either by its text or by partial text.
Locating links with partial text comes in handy when links have dynamic text. In this recipe, we will see how to use these methods to locate the links on page.
How to do it...
Let's create a sample test to see how locating links work in Selenium WebDriver with the following options.
Finding a link by its text
Selenium WebDriver's By
class provides the linkText()
method to locate links using the text displayed for the link. In the following example, we will locate the GMail link:
WebElement gmailLink = driver.findElement(By.linkText("GMail")); assertEquals("http://mail.google.com/", gmailLink.getAttribute("href"));
Finding a link by partial text
Selenium WebDriver's By
class also provides a method to locate links using partial text. This method is useful where developers create links with dynamic text. In this example, a link is provided to open inbox. This link also displays the number of new e-mails which may change dynamically. Here we can use the partialLinkText()
method to locate the link using a fixed or known portion of the link text, in this case it would be inbox.
WebElement inboxLink = driver.findElement(By.partialLinkText("Inbox")); System.out.println(inboxLink.getText());
How it works...
The linkText
and partialLinkText
locator methods query the driver for all the links that meet the specified text and returns the matching link(s).
There's more...
You can also locate links using id
, name
, or class
attributes if developers have provided these attributes.
Note
Locating elements based on text can cause issues while testing applications in multiple locales. Using parameterized text locator value could work in such applications.
See also
-
The Locating an element using the findElement method recipe
-
The Locating elements using findElements method recipe
Locating elements by tag name
Selenium WebDriver's By
class provides a tagName()
method to find elements by their HTML tag name. This is similar to the getElementsByTagName()
DOM method in JavaScript.
This comes in handy when you want to locate elements using their tag name. For example, locating all <tr>
tags in a table and so on.
In this recipe, we will briefly see how to use the tagName
locator method.
How to do it...
Let's assume you have a single button element on a page. You can locate this button by using its tag in the following way:
WebElement loginButton = driver.findElement(By.tagName("button")); loginButton.click();
Take another example where we want to count how many rows are displayed in <table>
. We can do this in the following way:
WebElement table = driver.findElement(By.id("summaryTable")); List<WebElement> rows = table.findElements(By.tagName("tr")); assertEquals(10, rows.size());
How it works...
The tagName
locator method queries the DOM and returns a list of matching elements for the specified tag name. This method may not be reliable while locating individual elements and the page might have multiple instances of these elements.
See also
-
The Locating elements using findElements method recipe
Locating elements using CSS selectors
Cascading Style Sheets ( CSS ) is a style sheet language used for describing the presentation semantics (the look and formatting) of a document written in a markup language such as HTML or XML.
Major browsers implement CSS parsing engines for formatting or styling the pages using CSS syntax. CSS was introduced to keep the presentation information separate from the markup or content. For more information on CSS and CSS selectors, visit http://en.wikipedia.org/wiki/Cascading_Style_Sheets.
In CSS, pattern-matching rules determine which style should be applied to elements in the DOM. These patterns, called selectors, may range from simple element names to rich contextual patterns. If all conditions in the pattern are true for a certain element, the selector matches the element and the browser applies the defined style in CSS syntax.
Selenium WebDriver uses same principles of CSS selectors to locate elements in DOM. This is a much faster and more reliable way to locate the elements when compared with XPaths.
In this recipe, we will explore some basic CSS selectors and then later on we will dive into advanced CSS selectors.
How to do it...
Let's explore some basic CSS selectors that can be used in Selenium WebDriver. Selenium WebDriver's By
class provides the cssSelector()
method for locating elements using CSS selectors.
Finding elements with absolute path
CSS absolute paths refer to the very specific location of the element considering its complete hierarchy in the DOM. Here is an example where the Username Input field is located using the absolute path. While providing absolute path, a space is given between the elements.
WebElement userName = driver.findElement(By.cssSelector("html body div div form input"));
You can also use the previous selector in the following way by describing the direct parent to child relationships with >
separator:
WebElement userName = driver.findElement(By.cssSelector("html > body > div > div > form > input"));
However, this strategy has limitations as it depends on the structure or hierarchy of the elements on a page. If this changes, the locator will fail to find the element.
Finding elements with relative path
With relative path we can locate an element directly, irrespective of its location in the DOM. For example, we can locate the Username Input field in the following way, assuming it is the first <input>
element in the DOM:
WebElement userName = driver.findElement(By.cssSelector("input"));
The following CSS selectors use the Class and ID attributes to locate the elements using relative paths. This is same as the className()
and id()
locator methods. However, there is another strategy where we can use any other attribute of the element that is not covered in the By
class.
Finding elements using the Class selector
While finding elements using the CSS selector, we can use the Class attribute to locate an element. This can be done by specifying the type of HTML tag, then adding a dot followed by the value of the class
attribute in the following way:
WebElement loginButton = driver.findElement(By.cssSelector("input.login"));
This will find the Login button's <input>
tag whose Class attribute is login
.
There is also a shortcut where you can put a .
and class attribute value and ignore the HTML tag. However, this will return all the elements with class as login
and the test may not return the correct element.
WebElement loginButton = driver.findElement(By.cssSelector(".login"));
This method is similar to the className()
locator method.
Finding elements using ID selector
We can locate the element using the IDs assigned to elements. This can be done by specifying the type of HTML tag, then entering a hash followed by the value of the Class attribute, as shown:
WebElement userName = driver.findElement(By.cssSelector("input#username"));
This will return the username <input>
element using its id
attribute.
There is also a shortcut where you can enter #
and a class attribute value and ignore the HTML tag. However, this will return all the elements with the id
set as username
and the test may not return the correct element. This has to be used very carefully.
WebElement userName = driver.findElement(By.cssSelector("#username"));
This method is similar to the id
locator strategy.
Finding elements using attributes selector
Apart from the class
and id
attributes, CSS selectors also enable the location of elements using other attributes of the element. In the following example, the Name attribute is used to locate an <input>
element.
WebElement userName = driver.findElement(By.cssSelector("input[name=username]"));
Using the name
attribute to locate an element is similar to the name()
locator method of the By
class.
Let's use some other attribute to locate an element. In the following example, the <img>
element is located by using its alt
attribute.
WebElement previousButton = driver.findElement(By.cssSelector("img[alt='Previous']"));
You might come across situations where one attribute may not be sufficient to locate an element and you need to combine additional attributes for a precise match. In the following example, multiple attributes are used to locate the Login button's <input>
element:
WebElement previousButton = driver.findElement(By.cssSelector("input[type='submit'][value='Login']"));
Finding elements using Attributes Name Selector
This strategy is a bit different from the earlier strategy where we want to locate elements based on only the specific attribute defined for them but not attribute values. For example, we want to lookup all the <img>
elements which have alt
attribute specified.
List<WebElement> imagesWithAlt = driver.findElements(By.cssSelector("img[alt]"));
A Boolean not()
pseudo-class can also be used to locate elements not matching the specified criteria. For example, to locate all the <img>
elements that do not have the alt
attribute, the following method can be used:
List<WebElement> imagesWithoutAlt = driver.findElements(By.cssSelector("img:not([alt])"));
Performing partial match on attribute values
CSS selector provides a way to locate elements matching partial attribute values. This is very useful for testing applications where attribute values are dynamically assigned and change every time a page is requested. For example, ASP.NET applications exhibit this kind of behavior, where IDs are generated dynamically. The following table explains the use of CSS partial match syntax:
Syntax | Example | Description |
---|---|---|
| | Starting with: For example, if the ID of an element is |
| | Ending with: For example, if the ID for an element is |
| | Containing: For example, if the ID of an element is |
How it works...
CSS selector is a pattern and the part of a CSS rule that matches a set of elements in an HTML or XML document.
The majority of browsers support CSS parsing for applying styles to these elements. Selenium WebDriver uses CSS parsing engine to locate the elements on a page. CSS selectors provide various methods, rules, and patterns to locate the element from a page. This is also a more reliable and fast method when compared with XPath locators.
Using CSS selector, the test can locate elements in multiple ways using Class, ID, attribute values, and text contents as described in this recipe.
See also
-
The Locating elements using advanced CSS selectors recipe
Locating elements using XPath
XPath, the XML path language, is a query language for selecting nodes from an XML document. All the major browsers support XPath as HTML pages are represented as XHTML documents in DOM.
The XPath language is based on a tree representation of the XML document and provides the ability to navigate around the tree, selecting nodes using a variety of criteria.
Selenium WebDriver supports XPath for locating elements using XPath expressions or queries.
Locating elements with XPath works very well with a lot of flexibility. However, this is the least preferable locator strategy due its slow performance.
One of the important differences between XPath and CSS is, with XPath we can search elements backward or forward in the DOM hierarchy while CSS works only in a forward direction. This means that with XPath we can locate a parent element using a child element.
In this recipe, we will explore some basic XPath queries to locate elements and then examine some advanced XPath queries.
How to do it...
Let's explore some basic XPath expressions that can be used in Selenium WebDriver. Selenium WebDriver provides the xpath()
method for locating elements using XPaths.
Finding elements with absolute path
Similar to CSS absolute paths, XPath absolute paths refer to the very specific location of the element, considering its complete hierarchy in the DOM. Here is an example where Username Input field is located using the absolute path. While providing absolute path a space is given between the elements.
WebElement userName = driver.findElement(By.xpath("html/body/div/div/form/input"));
However, this strategy has limitations as it depends on the structure or hierarchy of the elements on a page. If this changes, the locator will fail to get the element.
Finding elements with relative path
With relative path, we can locate an element directly irrespective of its location in the DOM. For example, we can locate the Username Input field in the following way, assuming it is the first <input>
element in the DOM:
WebElement userName = driver.findElement(By.xpath("//input"));
Finding elements using index
In the previous example, the XPath query will return the first <input>
element that it finds in the DOM. There could be multiple elements matching the specified XPath query. If the element is not the first element, we can also locate the element by using its index in DOM. For example in our login form, we can locate the Password field which is the second <input>
element on the page in the following way:
WebElement userName = driver.findElement(By.xpath("//input[2]"));
Finding elements using attributes values with XPath
Similar to CSS, we can also locate elements using their attribute values in XPath. In the following example, the Username field is located using the ID attribute:
WebElement userName = driver.findElement(By.xpath("//input[@id='username']"));
Here is another example where the image is located using the alt
attribute:
WebElement previousButton = driver.findElement(By.xpath("img[@alt='Previous']"));
You might come across situations where one attribute may not be sufficient to locate an element and you need combined additional attributes for a precise match. In the following example, multiple attributes are used to locate the <input>
element for the Login button:
WebElement previousButton = driver.findElement(By.xpath("//input[@type='submit'][@value='Login']"));
The same result can be achieved by using XPath and
operator.
WebElement previousButton = driver.findElement(By.xpath("//input[@type='submit'and @value='Login']"));
In the following example, either of the attributes is used to locate the elements using XPath or
operator:
WebElement previousButton = driver.findElement(By.xpath("//input[@type='submit'or @value='Login']"));
Finding elements using attributes with XPath
This strategy is a bit different from the earlier strategy where we want to locate elements based only on the specific attribute defined for them but not attribute values. For example, we want to lookup all the <img>
elements that have the alt
attribute specified.
List<WebElement> imagesWithAlt = driver.findElements(By.xpath ("img[@alt]"));
Performing partial match on attribute values
Similar to CSS selector, XPath also provides a way to locate elements matching partial attribute values using XPath functions. This is very useful for testing applications where attributes values are dynamically assigned and change every time a page is requested. For example, ASP.NET applications exhibit this kind of behavior where IDs are generated dynamically. The following table explains the use of these XPath functions:
Syntax | Example | Description |
---|---|---|
| | Starting with: For example, if the ID of an element is |
| | Ending with: For example, if the ID of an element is |
| | Containing: For example, if the ID for an element is |
Matching any attribute using a value
XPath matches the attribute for all the elements for a specified value and returns the element. For example, in the following XPath query, 'userName'
is specified. XPath will check all the elements and their attributes to see if they have this value and return the matching element.
WebElement userName = driver.findElement(By.xpath("//input[@*='username']"));
Locating elements with XPath axis
XPath axes help to locate elements based on the element's relationship with other elements in a document. Here are some examples for some common XPath axes used to locate elements from a <table>
element. This can be applied to any other element structure from your application.
Here is the graphical representation of the HTML elements:
Axis | Description | Example | Result |
---|---|---|---|
| Selects all ancestors (parent, grandparent, and so on) of the current node. | | This will get the table element. |
| Selects all descendants (children, grandchildren, and so on) of the current node. | | This will get the input element from the third column of the second row from the table. |
| Selects everything in the document after the closing tag of the current node. | | This will get the second row from the table. |
| Selects all siblings after the current node. | | This will get the second column from the second row immediately after the column that has |
| Selects all nodes that appear before the current node in the document, except ancestors, attribute nodes, and namespace nodes. | | This will get the header row. |
| Selects all siblings before the current node. | | This will get the first column of third row from the table. |
You can find more about XPath axis at http://www.w3schools.com/xpath/xpath_axes.asp.
How it works...
XPath is a powerful language for querying and processing DOM in browsers. XPath is used to navigate through elements and attributes in a DOM. XPath provides rules, function, and syntax to locate the elements.
The majority of browsers support XPath and Selenium WebDriver provides the ability to locate elements using the XPath language.
Using the xpath()
method of the By
class we can locate elements using XPath syntax. XPath is little slower than the CSS selectors as XPath provides the ability to search elements bi-directionally. You can search for the parent element if you know the child or you can locate a child element using its relationship with the parent and siblings.
Using XPath, a test can locate elements in multiple ways based on the structure of the document, attribute values, text contents and so on, as described in this recipe.
Locating elements using text
While testing web applications, you will also encounter situations where developers don't assign any attributes to the elements and it becomes difficult to locate elements.
Using the CSS selectors or XPath, we can locate elements based on their text contents. In this recipe, we will explore methods to locate elements using text values.
How to do it...
For locating elements by using their text contents, CSS selectors and XPath provide methods to find text within the elements. If an element contains specific text, this will return the element back to the test.
Using CSS selector Contains Pseudo-Class
CSS selectors provide the contains()
pseudo-class which can be used to see if an element contains the specified text. For example, a test wants to locate the cell of a table using its contents in the following way:
WebElement cell = driver.findElement(By.cssSelector("td:contains('Item 1')"));
The contains()
pseudo-class accepts the text to be searched as a parameter. It then checks all the <td>
elements in DOM for the specified text.
Note
The contains(
) pseudo-class may not work with browsers that don't natively support CSS selectors. Also, it has been deprecated from CSS3 specification.
As an alternative for contains()
pseudo-class, you can use the innerText
attribute (does not work with Firefox) or textContent
attribute (for Firefox) in the following ways:
WebElement cell = driver.findElement(By.cssSelector("td[innerText='Item 1']"));
Or
WebElement cell = driver.findElement(By.cssSelector("td[textContent='Item 1']"));
You can also use jQuery selectors which support the contains()
pseudo-class.
Using XPath text function
XPath provides the text()
function which can be used to see if an element contains the specified text in the following way:
WebElement cell = driver.findElement(By.xpath("//td[contains(text(),'Item 1')]"));
Here we are using the contains
function along with the text()
function. The text()
function returns the complete text from the element and the contains()
function checks for the specific value that we have mentioned.
Finding elements using exact text value in XPath
With XPath, elements can be located by exact text value in the following way:
WebElement cell = driver.findElement(By.xpath("//td[.='Item 1']"));
This will locate the <td>
element matching with exact text.
How it works...
CSS selector and XPath provide methods with which to locate elements based on their text contents. This approach comes in handy when elements don't have enough attributes or when no other strategies work when attempting to locate these elements .
For locating elements using their text, both CSS selector and XPath search through the DOM for elements that have the specified text value and return the matching element(s).
Locating elements using advanced CSS selectors
We saw some basic CSS selectors in earlier recipes. In this recipe, we will explore some advanced CSS selectors for locating elements.
How to do it...
In the Locating elements using CSS selectors recipe, we explored some basic CSS selectors. Let's explore advanced CSS selectors such as adjacent sibling combinators and pseudo-classes as described in the following sections.
Finding child elements
CSS selectors provide various ways to locate child elements from parent elements.
For example, to locate the Username Field in the login form, we can use the following selector. Here, >
is used denote the parent and child relationship.
WebElement userName = driver.findElement(By.cssSelector("form#loginForm > input"));
Similarly the nth-child()
method can be used in the following way:
WebElement userName = driver.findElement(By.cssSelector("form#loginForm :nth-child(2)"));
Here, the second element in <form>
is the Username field. The following table shows some of the structural pseudo-classes used to locate child elements:
Pseudo-class | Example | Description |
---|---|---|
| | This will locate the first element under the form, that is, the label for username. |
| | This will locate the last element under the form, that is, the Logi n button. |
| | This will locate the second child element under the form, that is, the Username field. |
Finding sibling elements
With CSS selector, we can locate sibling elements using the +
operator. For example, on the sample page the <p>
element with Description for Product 2
text is selected in the following way:
WebElement productDescription = driver.findElement(By.cssSelector("div#top5 > p + p"));
In this example, the first child of div#top5
will be <p>
with Description for Product 1
and its immediate sibling will be Description for Product 2
. Here are few more adjacent sibling combinators for locating siblings:
| | Immediately following sibling. This will locate |
| | Following sibling with one intermediary. This will locate |
Using user action pseudo-classes
Using the user action :focus
pseudo-class, we can locate the element which has current input focus in the following way:
WebElement productDescription = driver.findElement(By.cssSelector("input:focus"));
This will locate any element that currently has the input focus. You can also locate elements using :hover
and :active
pseudo-classes.
Using UI state pseudo-classes
Using UI state pseudo-classes, we can locate elements for various states such as control is enabled, disabled, and checked. The following table describes these in detail:
Pseudo-class | Example | Description |
---|---|---|
| | This will locate all the elements that are enabled for user input. |
| | This will locate all the elements that are disabled for user input. |
| | This will locate all the elements (checkboxes) that are checked. |
How it works...
Apart from the basic CSS selectors, you can also use various advanced CSS selector methods such as pseudo-classes or adjacent sibling combinators to locate the elements with Selenium WebDriver API.
Visit http://www.w3schools.com/cssref/css_selectors.asp for an exhaustive list of CSS selectors and their usage.
See also
-
The Locating elements using CSS selectors recipe
Using jQuery selectors
jQuery selectors is one of the important feature of the jQuery library. jQuery Selectors are based on CSS1-3 selectors along with some additional selectors. These selectors use the familiar CSS Selector syntax to allow developers to quickly and easily identify page elements to operate upon with the jQuery library methods. Similar to CSS selectors, these selectors allow us to locate and manipulate HTML elements as a single element or list of elements.
jQuery selectors can be used where CSS selectors are not supported natively by the browsers.
In this recipe, we will explore in brief how to use jQuery selectors with Selenium WebDriver.
How to do it...
Let's create a test which checks that specified checkboxes are selected when page is displayed, as follows:
@SuppressWarnings("unchecked") @Test public void testDefaultSelectedCheckbox() { WebDriver driver = new ChromeDriver(); driver.get("http://dl.dropbox.com/u/55228056/Locators.html"); //Expected list of selected Checkbox List<String> checked = Arrays.asList(new String[]{"user1_admin", "user3_browser"}); //Create an instance of JavaScript Executor from driver JavascriptExecutor js = (JavascriptExecutor) driver; //Locate all the Checkbox which are checked by calling jQuery //find() method. //find() method returns elements in array List<WebElement> elements = (List<WebElement>) js.executeScript("return jQuery.find(':checked')"); //Verify two Checkbox are selected assertEquals(elements.size(),2); //Verify correct Checkbox are selected for (WebElement element : elements) assertTrue(checked.contains(element.getAttribute("id"))); driver.close(); }
How it works...
Selenium WebDriver can be enhanced by jQuery selectors using the jQuery API. However, we need to make sure that the page has jQuery API loaded before using these selectors. The jQuery API provides the find()
function through which we can search for elements. We need to use the JavaScriptExecutor
class to use jQuery's find()
method. In this example, we will locate all the selected checkboxes on a page by calling the find()
method.
//Locate all the Checkbox which are checked by calling jQuery find() method. //find() method returns elements in array List<WebElement> elements = (List<WebElement>) js.executeScript("return jQuery.find(':checked')");
The find()
method returns a WebElement or list of WebElements matching the selector criteria back to the test. For more details and a list of available jQuery selectors, please visit http://api.jquery.com/category/selectors/.
You can also use the CSS Selectors described in this chapter with the jQuery find()
method.
There's more...
For using jQuery selectors, the page under test should have jQuery library loaded. If your application does not use jQuery, you can load the jQuery on the page by attaching jQuery library at runtime with the following utility methods:
private void injectjQueryIfNeeded() { if (!jQueryLoaded()) injectjQuery(); } public Boolean jQueryLoaded() { Boolean loaded; try { loaded = (Boolean) driver.executeScript("return jQuery()!=null"); } catch (WebDriverException e) { loaded = false; } return loaded; } public void injectjQuery() { driver.executeScript(" var headID = document.getElementsByTagName(\"head\")[0];" + "var newScript = document.createElement('script');" + "newScript.type = 'text/javascript';" + "newScript.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';" + "headID.appendChild(newScript);"); }
The injectjQueryIfNeeded()
method will internally call the jQueryLoaded()
method to see if the jQuery object is available on the page. If the page does not have the jQuery object defined, the injectjQueryIfNeeded()
method will call the injectjQuery()
method to attach the jQuery library to the page header at runtime. This is done by adding a <script
> element, which refers the Google CDN (Content Delivery Network) for jQuery library file, to the page. You may change the version used in this example to the latest version of the jQuery library.
Locating table rows and cells
While working with tables, we can locate the rows and cells effectively by using a set of the By
class methods.
In this recipe, we will see how to locate rows and columns in table.
How to do it...
Let's create a simple test that will print data from a table, locating its rows and columns as follows:
@Test public void testTable() { WebElement simpleTable = driver.findElement(By.id("items")); //Get all rows List<WebElement> rows = simpleTable.findElements(By.tagName("tr")); assertEquals(3, rows.size()); //Print data from each row for (WebElement row : rows) { List<WebElement> cols = row.findElements(By.tagName("td")); for (WebElement col : cols) { System.out.print(col.getText() + "\t"); } System.out.println(); } }
How it works...
A table in HTML is a collection of <tr>
and <td>
elements for rows and cells, respectively. In the sample test, the table can be located as a WebElement using its ID as follows:
WebElement simpleTable = driver.findElement(By.id("items"));
To get all the rows from a table, the findElements()
method is called on simpleTable
and the tagName
strategy is used to get all <tr>
elements. These are rows of a table.
List<WebElement> rows = simpleTable.findElements(By.tagName("tr"));
Each <tr>
element then holds the <td>
elements, which are the columns or cells of the table. The test iterates through the row and columns to print the data in the following way:
//Print data from each row for (WebElement row : rows) { List<WebElement> cols = row.findElements(By.tagName("td")); for (WebElement col : cols) { System.out.print(col.getText() + "\t"); } System.out.println(); }
This method comes in handy when you have a test that needs to verify data in a table.
There's more…
We can also use CSS selectors or XPath for locating table rows and cells using index matching. In the following example, CSS selector is used to locate the first cell of the second row in the table:
WebElement cell = driver.findElement(By.cssSelector("table#items tbody tr:nth-child(2) td"));
Similarly using XPath, it can be done in the following way:
WebElement cell = driver.findElement(By.xpath("//table[@id='items']/tbody/tr[2]/td"));
See also
-
The Locating child elements in a table recipe
-
The Locating elements using FindElements method recipe
Locating child elements in a table
Working with simple tables is relatively easy. However, you will come across complex tables where other than data, table cells have child elements for user interaction. For example, in an e-commerce application when you open the shopping cart page, it looks a simple table but inside there are many complex elements.
Furthermore, these elements are dynamically created based on user actions and may have attribute values generated at runtime. Locating these elements may become a challenging task.
In this recipe, we will explore strategies to locate child elements within tables using CSS and XPath.
How to do it...
Here is sample table that lists users of a system and their details including what access rights are assigned to these users. A test needs to select a given checkbox and see if the selected access is granted to the user.
If we look at the code for this table, each record or row has the following code:
<tr> <td>Nash</td> <td><a href="mailto:[email protected]">[email protected]</a></td> <td> <div> <label for="user128_admin">Admin</label> <input type="checkbox" id="user128_admin" checked="true"/> <label for="user128_cm">Content Manager</label> <input type="checkbox" id="user128_cm"/> <label for="user128_browser">Browser</label> <input type="checkbox" id="user128_browser"/> </div> </td> </tr>
The checkbox has dynamic IDs that we cannot correlate to a user. However, we can deal with such issues by using CSS selectors or XPath. In this example, we want to grant user Nash with admin access. This can be done using CSS selectors in the following way:
WebElement adminCheckBox = driver.findElement(By.cssSelector("td:contains('Nash')+td+td>div>label:contains('Admin')+input")); adminCheckBox.click();
We can also use XPath in the following way:
WebElement adminCheckBox = driver.findElement(By.xpath("//td[contains(text(),'Nash')]/following-sibling::td/descendant::div/label[contains(text(),'Admin')]/following-sibling::input")); adminCheckBox.click();
How it works...
Parent, child, and sibling in CSS or XPath axes become a great help in correlating users with roles and developing a generic locator strategy for this feature. In simple terms, these strategies help to locate elements based on the element's relationship with other elements in a document.
Coming back to the problem, first we need to find a unique way to identify a user in the table. For this, we will locate a cell which contains username. We will locate this cell using its inner text in the following way:
CSS | XPath |
---|---|
| |
Next, we need to find the cell which contains the child elements. This is the second cell from the cell containing username.
CSS | XPath |
---|---|
| |
In the next step, we need to locate the label with the correct option. The next sibling of this label will be the checkbox we are looking for.
CSS | XPath |
---|---|
| |
See also
-
The Locating elements using CSS selectors recipe
-
The Locating elements using advanced CSS selectors recipe
-
The Locating elements using XPath recipe
Source: https://www.packtpub.com/product/selenium-testing-tools-cookbook/9781849515740
Posted by: retapowale0198439.blogspot.com
Post a Comment for "Selenium Testing Tools Cookbook Pdf Download"