Ilan Malyanker, automation developer at LivePerson presented: "Selenium WebDriver Element locators" As part of "Selenium Israel Meetup #3", at Google Campus TLV (http://www.meetup.com/Selenium-Israel/events/169326892/)
In continuous integration world, stability and reliability of tests are placed much higher in the priority list of more and more organizations. System tests involving web sites simulation & verification would be more robust and reliable when the locators used, are carefully selected and configured.
For our tests to survive version changes,GUI updates & modifications, the following is required:
1. Use the correct locating strategy
2. Supply the appropriate locator string with maximum focus and minimum external dependencies
This is an overview of all WebDriver locator strategies, provided by selenium module.
The credit for some of the ideas and samples should be given to:
- http://www.w3schools.com/cssref/css_selectors.asp
- Selenium Testing Tools Cookbook
- http://stackoverflow.com
2. Connection Before Content
creates meaningful, real time
customer connections that help
businesses increase conversions and
improve consumer experience.
LivePerson is hiring- peoplejobs@liveperson.com
Ilan Malyanker Works in LP for 3 years.
8 years as an automation engineer.
Blog- http://software-automation-development.blogspot.com
mail- ilanm@liveperson.com / malyankeri@yahoo.com
3. Purpose & Motivation
• Identify elements to simulate operations
• Identify elements to verify their status
• Help create robust testing framework
• Share knowledge
• Expose new options for automation
developers
4. Terms & Code Alignment - Demo
• HTML terms in WebDriver context
• WebDriver basic usage
• Think of WebDriver as a browser instance
• WebElement- as any seen object on the page
5. “By” class
• Selenium WebDriver provides By class
to support various locator strategies
• Find methods take a locator or query
object as an instance of By class as an
argument
9. 0 matches: throws exception (org.openqa.selenium.NoSuchElementException)
1 match: returns list of 1 WebElement instance
2+ matches: returns only first appearance in DOM
1 match: returns WebElement instance
0 matches: returns an empty list
2+ matches: returns list with all matching instances
FindElement vs. FindElements
findElement()
findElements()
10. Id
driver.findElement(By.id(“<some_id>"));
• Seems like the ideal solution
• Id‟s don‟t always exist
• Their uniqueness is not enforced
• What about dynamic elements?
• Might be used for other future purposes
• Code injected from different sources (potential override)
• Against web developers best practices
11. Links
Find elements by the text displayed on
the link
driver.findElement(By.linkText(“<link_text>"));
driver.findElement(By.partialLinkText(“<link_partial_text>"))
12. Tag Names
Find web elements based on their HTML
tags
< class="form-inline">
< class="editable-controls">
<input class="editable-has-buttons" type="text">
<span class="editable-buttons">
<button class="btn btn-primary" type="submit">
<button class="btn btn-danger">
</span>
</div>
</form>
driver.findElement(By.tagName("input"));
*See that your tag is unique
13. CSS Selectors (1)
• Cascading Style Sheets- language used for
describing the presentation semantics of a document
written in a markup language such as HTML or XML.
• Browsers implement CSS parsing engines for
formatting or styling the pages using CSS syntax.
Absolute path:
driver.findElement(By.cssSelector(“html>body>div>p>input"));
Relative path:
driver.findElement(By.cssSelector(“input")) *the first instance found
14. CSS Selectors (2)
Regular attribute:
tag with attribute value:
driver.findElement(By.cssSelector(“button[name=„cancel‟]"));
Special attributes:
id:
driver.findElement(By.cssSelector(“#save"));
tag & id:
driver.findElement(By.cssSelector(“button#save"));
class attribute:
driver.findElement(By.cssSelector(“.yoyo"));
tag & class attribute:
driver.findElement(By.cssSelector(“input.username"));
15. CSS Selectors (3)
tag with attribute value:
driver.findElement(By.cssSelector(“img[alt=„kuku‟]"));
tag which has attribute:
driver.findElement(By.cssSelector(“img[alt]"));
tag which doesn‟t have attribute:
driver.findElement(By.cssSelector(“img:not([alt])"));
16. CSS Selectors, advanced (last css slide)
The first child of a tag with id:
driver.findElement(By.cssSelector(“div#students:first-child"));
The n-th child of a tag with id :
driver.findElement(By.cssSelector(“form#loginForm:nth-child(3)"));
Second descendent of div with id :
driver.findElement(By.cssSelector(“div#ilan>p+*+p"));
(first) tag which is enabled:
driver.findElement(By.cssSelector(“button:enabled"));
17. Xpath (1)
• Xpath is a query language for selecting nodes from an
XML document.
• Xpath is based on a tree representation of the XML
document and provides the ability to navigate around
the tree.
Absolute path:
driver.findElement(By.xpath(“html/body/div/p/input"));
Relative path:
driver.findElement(By.xpath(“//input"))
18. Xpath (2)
Tag with attribute value:
driver.findElement(By.xpath(“//input[@id=„username‟]"));
Any tag with id:
driver.findElement(By.xpath(“//*[@id=„myId']"));
Operator „and‟:
driver.findElement(By.xpath(“//input[@type='submit'][@value='Login']”));
driver.findElement(By.xpath(“//input[@type='submit„ and @value='Login']”));
Opertor or:
driver.findElement(By.xpath(“//input[@type='stam„ or @class=„LP']"));
19. Xpath (3)
Attribute which starts with
driver.findElement(By.xpath(“//input[starts-with(@class,„tbl_')]"));
*there‟s also- ends-with()
Attribute contains text:
driver.findElement(By.xpath(“//input[contains(@id,'userName')]"));
Match value to any attribute:
driver.findElement(By.xpath("//input[@*='username']"));
20. Xpath (4)
Ancestor, descendant, following, following-sibling, preceding, preceding-sibling
driver.findElement(By.xpath(“//td[text()='Product 1']/ancestor::table"));
element.findElement(By.xpath(“/table/descendant::td/input"));
*can only be applied from another WebElement
Use parent to get to same-hierarchy object:
driver.findElement(By.xpath("//div/input[@class=„kuku‟]/../button"));
21. Text – CSS Selectors
See if element‟s attribute contains specified text
driver.findElement(By.cssSelector(“div[id*=„my_id„]"));
(Also- ^ starts with, $ ends with)
See if element contains specified text
driver.findElement(By.cssSelector(“input:contains(„Some Text')"));
*deprecated from CSS3 specification
innerText attribute
driver.findElement(By.cssSelector("td[innerText=„Some Text']"));
*Doesn‟t work in FireFox
textContent:
driver.findElement(By.cssSelector("td[textContent=„text']"));
*For FireFox
22. Text – XPath
Locate element by matching exact text value
driver.findElement(By.xpath(“//td/span[text()=„Some Text‟]"));
OR
driver.findElement(By.xpath("//td/span[.=„Some Text‟]"));
See if Element contains specified text
driver.findElement(By.xpath("//td[contains(text(),„Some Text')]"));
23. What‟s better, xpath or css selectors?
• CSS Selectors method is faster
• Browsers themselves use css selectors
• Latest browsers optimize the use of css
Selectors
• Xpath- common language for xml/html parsing
• Xpath is a two-way search mechanism
(up&down the DOM tree)
• Xpath handles text recognition better
24. JavaScript Executor for JS & JQuery
JavaScript syntax as a Java String:
String script = "return document.getElementById(„some-id');";
OR
Jquery syntax as a Java String:
String script = "return jQuery('#some-id').get(0);";
JavascriptExecutor executor = (JavascriptExecutor)driver;
WebElement element = (WebElement)executor.executeScript(script);
• Opens a world of client side manipulations
• jQuery() method uses- css selectors
i. jQuery lib should be loaded on the page
ii. Same executor runs both types of scripts
iii. jQuery returns a collection, hence extract the first
instance
iv. The “$” – sign could also represent jQuery namespace
25. Tips & Best Practices
• Locators location
• Use Enums
• Know all your working tools
• Element Detection & Highlighting
• Expose locators and not just the methods
• Work close to client developers (4 non agile developers)
• Optimize your locators !!
i Maximum focus
ii Minimum dependencies
26. Visit my blog - software-automation-development.blogspot.com
Notas del editor
- All examples are in Java - FindElements() - find from another element - Best practice