To write useful end to end tests that are stable and reliable, we have to select the correct elements all the time.
In this article, we’ll look at the optimal selector strategies to do that.
IDs
IDs are the best selectors since there’s only one of them on the page.
If it’s there, then you can select it and it’ll return the right element.
If e don’t have IDs for the element we want to select, then we should add an id
attribute to the element we want to select.
We can select an ID with the #
sign. For instance, we can write #foo
to select an element with ID foo
.
CSS and Xpath Locators
If we don’t have IDs, then we can select an element with CSS selectors.
They include classes, which is the value of the class
attribute.
For instance, if we have:
<div id=”main”>
<p>Introduction</p>
<ul>
<li> Item 1</li>
</ul>
</div>
and we want to select the li
element, then we have to use CSS selectors to select the element.
The easiest way to get the CSS selector is to right click on the li
element.
Then click on Inspect Element in the context menu. This menu item should be available in Chromium browsers and Firefox.
This should open the developer console with the li
element highlighted.
Then we right click on the element, click Copy, and click on Copy Selector. This should copy the CSS selector for the li
to the clipboard.
Once we did this, we get #”main” > ul > li
as the CSS, which is what we want.
Alternatively, we can use the XPath to select an element with Selenium.
It’s an expression to select nodes in HTML and XML documents.
To get the XPath, we go the developer console and right click on the element and click Copy as we did before.
Then we click Copy XPath to copy the XPath. We should get //*[@id="”main”"]/ul/li
as the expression copied.
This is the relative path to the li
element.
We can also click Copy Full XPath on the same menu to copy the full XPath. If we do this, we get /html/body/div/ul/li
copied
Using SelectorsHub
Another way to copy an XPath is to use the SelectorsHub extension.
It’s a browser addon that’s available for Chromium browsers and Firefox.
To install the addon for Chromium browsers, we go to https://chrome.google.com/webstore/detail/selectorshub/ndgimibanhlabgdgjcpbbndiehljcpfh?hl=en
Then to use it, we right click on the element, click on SelectorsHub, then click on Copy Relative XPath.
Once we do that, we get //li[normalize-space()='Item 1']
This works if the ‘Rel XPath’ option is checked in the SelectorsHub addon and the ‘ContextMenu’ option is turned on.
We can also use it to get the CSS selector of an element.
To do this, we click on Copy Rel CSSSelector to get the CSS selector of the element in the page.
If we did that with the same example HTML above, we get div[id='”main”'] ul li
.
The Copy Abs XPath option lets us copy the absolute XPath, which is the same as the full XPath in the console.
If we click that, we get /html[1]/body[1]/div[1]/ul[1]/li[1]
copied to the clipboard.
Fragility
CSS Selectors and XPath are more fragile than IDs since elements may change their position in the DOM tree.
If an element changes position in the tree, then the selectors or XPath used in the current test may no longer work.
Then we have a broken test and we have to go back and fix it.
If we have to use CSS selectors and XPath, then we should make the path as short as possible to reduce complexity and the chance that the path will be outdated.
Conclusion
The best selector to use for end to end tests are always IDs.
However, if we have to use CSS selectors or XPaths, we should keep them short to improve reliability.
To get selectors for elements, we can use the browser’s development console or the SelectorHub addon.