Here is my answer to the question from Quora
What are some locator strategies that can be used in Selenium WebDriver?
Selenium WebDriver has several locator strategies — or methods for locating elements.
Whey you want to find an element, you need to locate it on the page. The way Selenium does this is by using Javascript to parse the HTML source content. In Javascript you can do the following:
document.getElementById(locator)
document.getElementsByName(locator)
document.getElementsByTagName(locator)
document.getElementsByClassName(locator)
WebDriver has corresponding locator strategies:
driver.findElement(By.id(locator))
driver.findElement(By.name(locator))
driver.findElement(By.tagName(locator))
driver.findElement(By.className(locator))
It also has additional methods for locating by XPATH, CSS Selector, and link text:
driver.findElement(By.xpath(locator))
driver.findElement(By.cssSelector(locator))
driver.findElement(By.linkText(locator))
driver.findElement(By.partialLinkText(locator))
XPath and CSS selectors are ways to parse the HTML document and give more precise locators including a combination of element tag hierarchies, attributes, CSS classes, and relative position (parent, child, sibling). I won’t go into details, but these are powerful strategies for parsing a document and finding specific elements based on several criteria.
LinkText and PartialLinkText searches for anchor <a> tags that contain the given text for the locator.
By.linkText(“Click Here”)
By.partialLinkText(“Click”)
WebDriver also has corresponding findElements() (plural) methods that can locate a list of matching elements. For instance, you can find all elements with tag name <div> or matching xpath //table/h1 (find all H1 tags within a table). By default, findElement() (singular) will return the first matching element.
Selenium 4 also introduced Relative Locators which can modify an existing locator with terms “above”, “below”, “rightOf”, “leftOf” or “near” (near meaning within 50 pixels). In practice, relative locators are often not reliable, because layout typically depends on a fixed screen size and layout. One use for relative locators is to check responsive layouts given a known screen size. For example, to make sure a button is below a div on mobile devices, but beside it on a full screen:
By mobileButton = RelativeLocator.with(By.id(“myButton”)).below(By.id(“myDiv”))
By desktopButton = RelativeLocator.with(By.id(“myButton”)).rightOf(By.id(“myDiv”))
Now, the next question is: Which locator strategy should I use — and why?
By.id is the most efficient locator, the most concise, and the least likely to change. But not every element has a unique id attribute. Use it when you can.
<button id=”login”>
driver.findElement(By.id(“login”))
By.name is useful for form elements, and is also concise and specific.
<input name=”email”>
driver.findElement(By.name(“email”))
Tag and and class name are often useful for finding all elements that match that specific criteria:
driver.findElements(By.tagName(“a”)) ← this will find all links on the page
driver.findElements(By.className(“dark”)) ← this will find all elements with the “dark” class attribute.
XPATH is definitely the most versatile, but can be very ugly and easy to break
driver.findElement(By.xpath(“//table/*/div[\@class=’result’]/a[contains(text(), ‘edit’)]") ← find the edit link in the first table that contains a div element with class name “result”
But CSS selectors can do most of the same things as XPATH (except finding parent, child, sibling, or text nodes) and is often more readable.
driver.findElement(By.cssSelector(“table div.result > a”)) ← find the first link in the first table within a div with class name “result”.
Note: CSS selector cannot find elements by specific text.
As you can see, CSS (and XPATH) locators can incorporate the above strategies (tag name, class name, id) into one locator. Many people prefer to use one of these locator strategies exclusively for consistency.
However, an important “strategy” when using XPATH or CSS selectors is to not use complex selectors that depend on the document hierarchy. You should try to find a unique locator as specifically as possible, by id, name, or tag/class combination that will not be likely to change as the page layout changes.
If you cannot identify a single element definitively, you can look for the closest unique parent element. Using a relative XPATH or CSS selector (different from a relative locator like “above” or “below”) from that parent is a good strategy.
driver.findElement(By.cssSelector(“#uniqueId > div”)) ← find the first div child of an element with the uniqueId.
In CSS Selectors:
div#uniqueID ← search for a <div id=”uniqueId”> element with ID attribute
div.className ← search for a <div class”=myClass”> element with class attribute
Personally, I recommend that given the choice between XPATH and CSS selectors, to choose CSS when possible. Both for readability, and as a practical consideration — web developers know CSS selectors well, but usually do not use XPATH.
Finally, you can locate one element, and then search for other elements below it by performing two searches.
driver.findElement(By.xpath(“//table”)).findElement(By.cssSelector(“.results”)) ← find the first table, then find the element with className “results”.
This does incur a slight performance penalty by making multiple WebDriver findElement calls. You should try to find elements with a single locator when possibly, but not at the expense of either readability (complex locators) or maintainability (likely to change). These often coincide.
In summary, you should try to find unique locators for elements that will not break as the page layout changes. Finding elements by ID is the most efficient. XPATH, and then CSS selectors are the most versatile, and you can often get whatever you want with one of these two. You should strive for simple locators that identify an element uniquely, but avoid complex hierarchical locator strategies when possible because they can lead to difficult to maintain code.