Selenium
Selenium provides multiple locators to find elements:
Difference between
linkTextandpartialLinkTextin Selenium →linkTextMatches the entire visible text of a link (
<a>tag).Must match exactly — case-sensitive.
//<a href="https://example.com">Click Here to Login</a> driver.findElement(By.linkText("Click Here to Login")).click();
partialLinkTextMatches part of the visible text of a link.
Useful when the full text changes dynamically or is too long.
//<a href="https://example.com">Click Here to Login</a> driver.findElement(By.partialLinkText("Click Here")).click();
What is XPath?
XPath (XML Path Language) is a syntax used to navigate and locate elements in an XML or HTML document.
In Selenium, we use XPath to find elements in the DOM when other locators like
idornameare not reliable.
Types of XPath
Absolute XPath
Starts from the root node (
html) and follows the entire path.Uses
/to move down step-by-step.❌ Breaks easily if page structure changes.
Example:
/html/body/div[1]/form/input[1]
Relative XPath ✅ (Recommended)
Starts from any node, not necessarily the root.
Uses
//to search anywhere in the document.Example:
//input[@id='username']
How to Write XPath
XPath syntax:
tagname[@attribute='value']
tagname→ HTML tag (e.g.,input,button,a).@attribute→ HTML attribute (e.g.,id,name,class).'value'→ Value of the attribute.
Five important XPath axes →
1. ancestor:: — Move Up Through All Parents
The ancestor:: axis selects all parent, grandparent, and higher-level elements of the current node.
HTML Example:
<div class="item">
<span class="name">Laptop</span>
<span class="price">$999</span>
</div>
XPath:
//span[@class='price']/ancestor::div[@class='item']
2. parent:: — Select Only the Immediate Parent
The parent:: axis moves one level up from the current node.
HTML Example:
<form id="searchForm">
<input type="text" id="searchBox" placeholder="Search...">
</form>
XPath:
//input[@id='searchBox']/parent::form
3. child:: — Get Direct Children
The child:: axis selects only direct children of the current node.
HTML Example:
<ul id="menu">
<li>Home</li>
<li>About</li>
</ul>
XPath:
//ul[@id='menu']/child::li
5. preceding-sibling:: — Move to Siblings Before the Current Node
The preceding-sibling:: axis selects elements at the same level that appear before the current node.
HTML Example:
htmlCopyEdit<p>Intro paragraph</p>
<h2>Section B</h2>
XPath:
//h2[text()='Section B']/preceding-sibling::p
Most Useful XPath Functions in Selenium
1.
text()Purpose: Matches elements based on their visible text.
Example:
//button[text()='Login']
Finds <button> with exact text Login.
2. contains()
Purpose: Matches elements whose attribute or text contains a substring.
Example (Attribute):
//input[contains(@id,'user')]
Matches <input> if its id contains "user".
- Example (Text):
//a[contains(text(),'Forgot')]
Matches <a> if visible text contains "Forgot".
3. starts-with()
Purpose: Matches elements whose attribute starts with a given string.
Example:
//input[starts-with(@name,'email')]
Matches <input> if name starts with "email".
4. normalize-space()
Purpose: Removes extra spaces from text before matching.
Example:
//button[normalize-space(text())='Sign In']
Matches <button> even if there are leading/trailing spaces.
5. last()
Purpose: Selects the last element in a set.
Example:
(//input[@type='text'])[last()]
Selects the last <input> with type='text'.
6. position()
Purpose: Selects elements based on their position in a list.
Example:
(//input[@type='text'])[1]
Selects the first <input> with type='text'.
7. not()
Purpose: Matches elements that do not have a given condition.
Example:
xpathCopyEdit//input[not(@type='submit')]
Matches <input> elements except those with type='submit'.
8. and / or
Purpose: Combine multiple conditions.
Example:
//input[@type='text' and @name='username']
Matches <input> that has both type='text' and name='username'.
Diagram: XPath Functions in Action
bashCopyEditHTML:
<div>
<input id="user1" type="text" name="username">
<input id="user2" type="text" name="email_user">
<input id="submitBtn" type="submit" value="Login">
</div>
Examples:
1. //input[contains(@id,'user')] → Matches user1 & user2
2. //input[starts-with(@name,'email')] → Matches user2
3. //input[not(@type='submit')] → Matches user1 & user2
4. (//input[@type='text'])[last()] → Matches user2
Why We Need Waits in Selenium
We need waits in Selenium because web elements don’t always load instantly — they may take some time to appear, become clickable, or be ready for interaction due to:
Network delays
JavaScript rendering time
Animations / transitions
AJAX requests (dynamic content loading)
If Selenium tries to interact with an element before it’s ready, you’ll get errors like:
NoSuchElementException(element not found yet)ElementNotInteractableException(found but not clickable)