XPath Functions & XPath Operators in Selenium

XPath Functions

XPath includes a variety of functions that enhance its querying capabilities, allowing for more dynamic and flexible element selection. These functions are instrumental in handling complex scenarios where standard attribute-based locators fall short.

Common XPath Functions

  1. contains(): Checks if an attribute contains a specific substring.
  2. starts-with(): Checks if an attribute starts with a specific substring.
  3. text(): Selects elements based on their visible text.
  4. normalize-space(): Removes leading and trailing whitespaces from the text.
  5. last(): Selects the last element in a set.
  6. position(): Identifies the position of a node within a node set.
  7. count(): Counts the number of nodes matching a particular criteria.

Let’s explore each function with detailed explanations, HTML examples, and Selenium WebDriver implementations.


1. contains() Function

Description:
The contains() function checks if a specified attribute contains a given substring. It’s particularly useful for locating elements with dynamic or partially known attribute values.

Syntax:

contains(@attribute, 'value')

Example:

//input[contains(@name, 'user')]

This XPath selects <input> elements where the name attribute includes the substring 'user'.

HTML Example:

<input type="text" name="username">
<input type="email" name="userEmail">
<button class="btn primary-button">Submit</button>
<button class="btn secondary-button">Cancel</button>

XPath Expressions and Selenium Examples:

  1. Selecting Inputs with ‘user’ in Name:

    //input[contains(@name, 'user')]
    

    Selenium Example:

    // Locate input fields containing 'user' in their name attribute
    List<WebElement> userInputs = driver.findElements(By.xpath("//input[contains(@name, 'user')]"));
    for(WebElement input : userInputs) {
        input.sendKeys("TestUser");
    }
    
  2. Selecting Buttons with ‘primary’ in Class:

    //button[contains(@class, 'primary')]
    

    Selenium Example:

    // Locate the primary button
    WebElement primaryButton = driver.findElement(By.xpath("//button[contains(@class, 'primary')]"));
    primaryButton.click();
    

2. starts-with() Function

Description:
The starts-with() function checks if a specified attribute starts with a given substring. This is useful for targeting elements with predictable attribute prefixes, especially when dealing with dynamically generated IDs or classes.

Syntax:

starts-with(@attribute, 'value')

Example:

//button[starts-with(@id, 'submit')]

This XPath selects <button> elements where the id attribute starts with 'submit'.

HTML Example:

<input type="text" id="user_123" name="username">
<input type="text" id="user_456" name="useremail">
<button id="submitBtn1">Submit</button>
<button id="submitBtn2">Confirm</button>

XPath Expressions and Selenium Examples:

  1. Selecting Inputs with IDs Starting with ‘user_’:

    //input[starts-with(@id, 'user_')]
    

    Selenium Example:

    // Locate input fields with IDs starting with 'user_'
    List<WebElement> userInputs = driver.findElements(By.xpath("//input[starts-with(@id, 'user_')]"));
    for(WebElement input : userInputs) {
        input.sendKeys("DynamicUser");
    }
    
  2. Selecting Buttons with IDs Starting with ‘submit’:

    //button[starts-with(@id, 'submit')]
    

    Selenium Example:

    // Locate the submit button
    WebElement submitButton = driver.findElement(By.xpath("//button[starts-with(@id, 'submit')]"));
    submitButton.click();
    

3. text() Function

Description:
The text() function selects elements based on their visible text content. This is particularly useful for locating elements like buttons, links, or headings that display specific text to users.

Example:

//a[text()='Home']

This XPath selects <a> elements with the exact visible text 'Home'.

HTML Example:

<a href="/home">Home</a>
<a href="/about">About Us</a>
<button>Submit</button>
<button>Cancel</button>

XPath Expressions and Selenium Examples:

  1. Selecting Link with Exact Text ‘Home’:

    //a[text()='Home']
    

    Selenium Example:

    // Locate the 'Home' link
    WebElement homeLink = driver.findElement(By.xpath("//a[text()='Home']"));
    homeLink.click();
    
  2. Selecting Button with Text ‘Submit’:

    //button[text()='Submit']
    

    Selenium Example:

    // Locate the 'Submit' button
    WebElement submitButton = driver.findElement(By.xpath("//button[text()='Submit']"));
    submitButton.click();
    

4. normalize-space() Function

Description:
The normalize-space() function removes leading and trailing whitespaces from the text content of an element and replaces sequences of whitespace characters with a single space. This ensures accurate text matching, especially when dealing with inconsistent spacing in the HTML.

Example:

//div[normalize-space(text())='Welcome']

This XPath selects <div> elements whose text content, after normalizing spaces, equals 'Welcome'.

HTML Example:

<div> Welcome </div>
<div>Welcome to the site!</div>
<div>
    Welcome
</div>

XPath Expressions and Selenium Examples:

  1. Selecting Div with Text ‘Welcome’:
    //div[normalize-space(text())='Welcome']
    
    Selenium Example:
    // Locate the div with text 'Welcome' after normalizing spaces
    WebElement welcomeDiv = driver.findElement(By.xpath("//div[normalize-space(text())='Welcome']"));
    System.out.println("Div Text: " + welcomeDiv.getText());
    

5. last() Function

Description:
The last() function selects the last element in a set of nodes. It’s particularly useful when you need to interact with the last occurrence of an element within a specific context.

Example:

(//tr)[last()]

This XPath selects the last <tr> element in the document.

HTML Example:

<table>
    <tr><td>Row 1</td></tr>
    <tr><td>Row 2</td></tr>
    <tr><td>Row 3</td></tr>
</table>

XPath Expressions and Selenium Examples:

  1. Selecting the Last Table Row:
    (//tr)[last()]
    
    Selenium Example:
    // Locate the last table row
    WebElement lastRow = driver.findElement(By.xpath("(//tr)[last()]"));
    System.out.println("Last Row Text: " + lastRow.getText());
    

6. position() Function

Description:
The position() function identifies the position of a node within a node set. It allows you to select elements based on their sequence in the document.

Example:

(//input)[position()=3]

This XPath selects the third <input> element in the document.

HTML Example:

<form>
    <input type="text" name="input1">
    <input type="password" name="input2">
    <input type="email" name="input3">
    <input type="submit" value="Submit">
</form>

XPath Expressions and Selenium Examples:

  1. Selecting the Third Input Field:

    (//input)[position()=3]
    

    Selenium Example:

    // Locate the third input field
    WebElement thirdInput = driver.findElement(By.xpath("(//input)[position()=3]"));
    thirdInput.sendKeys("third@example.com");
    
  2. Selecting the Second Button in a Form:

    (//form//button)[position()=2]
    

    Selenium Example:

    // Locate the second button within the form
    WebElement secondButton = driver.findElement(By.xpath("(//form//button)[position()=2]"));
    secondButton.click();
    

7. count() Function

Description:
The count() function returns the number of nodes that match a specific XPath expression. It’s useful for verifying the presence or quantity of elements on a page.

Example:

count(//div[@class='container'])

This XPath returns the count of <div> elements with class='container'.

HTML Example:

<div class="container">Content 1</div>
<div class="container">Content 2</div>
<div class="container">Content 3</div>

XPath Expressions and Selenium Examples:

  1. Counting Containers:

    count(//div[@class='container'])
    

    Selenium Example:

    // Execute JavaScript to get the count of container divs
    Long containerCount = (Long) ((JavascriptExecutor) driver).executeScript(
        "return document.querySelectorAll('div.container').length;");
    System.out.println("Number of Container Divs: " + containerCount);
    

    Note: Selenium’s XPath does not directly return the count. To obtain the count, you can use JavaScript execution or iterate through elements and count them.

  2. Verifying Number of Input Fields:

    count(//input)
    

    Selenium Example:

    // Execute JavaScript to count input fields
    Long inputCount = (Long) ((JavascriptExecutor) driver).executeScript(
        "return document.querySelectorAll('input').length;");
    System.out.println("Number of Input Fields: " + inputCount);
    

XPath Operators

XPath supports various operators to refine searches and perform logical operations, allowing for more precise and dynamic element selection.

Logical Operators

  1. and: Combines multiple conditions that must all be true.
  2. or: Combines multiple conditions where at least one must be true.
  3. not(): Negates a condition.

Comparison Operators

  1. =: Equal to.
  2. !=: Not equal to.
  3. <, >, <=, >=: Less than, greater than, less than or equal to, greater than or equal to.

Let’s explore these operators with detailed explanations, HTML examples, and Selenium WebDriver implementations.


1. Logical Operators

1.1 and Operator

Description:
The and operator combines multiple conditions that must all be true for an element to be selected. It allows for more specific element targeting by ensuring that all specified criteria are met.

Example:

//input[@type='text' and @name='username']

This XPath selects <input> elements with type='text' and name='username'.

HTML Example:

<input type="text" name="username" id="user1">
<input type="password" name="password" id="pass1">
<input type="text" name="email" id="email1">

XPath Expressions and Selenium Examples:

  1. Selecting Username Input:

    //input[@type='text' and @name='username']
    

    Selenium Example:

    // Locate the username input field with type='text' and name='username'
    WebElement usernameInput = driver.findElement(By.xpath("//input[@type='text' and @name='username']"));
    usernameInput.sendKeys("TestUser");
    
  2. Selecting a Button with Multiple Attributes:

    //button[@type='submit' and @name='login']
    

    Selenium Example:

    // Locate the submit button with type='submit' and name='login'
    WebElement submitButton = driver.findElement(By.xpath("//button[@type='submit' and @name='login']"));
    submitButton.click();
    

1.2 or Operator

Description:
The or operator combines multiple conditions where at least one must be true for an element to be selected. It’s useful when you want to target elements that can satisfy any one of several criteria.

Example:

//button[@id='submit' or @name='submit']

This XPath selects <button> elements with id='submit' or name='submit'.

HTML Example:

<button id="submit">Submit</button>
<button name="submit">Confirm</button>
<button id="cancel">Cancel</button>

XPath Expressions and Selenium Examples:

  1. Selecting Submit Buttons:

    //button[@id='submit' or @name='submit']
    

    Selenium Example:

    // Locate buttons with id='submit' or name='submit'
    List<WebElement> submitButtons = driver.findElements(By.xpath("//button[@id='submit' or @name='submit']"));
    for(WebElement button : submitButtons) {
        button.click();
    }
    
  2. Selecting Links by Text or ID:

    //a[@id='homeLink' or text()='Home']
    

    Selenium Example:

    // Locate the 'Home' link either by id or visible text
    WebElement homeLink = driver.findElement(By.xpath("//a[@id='homeLink' or text()='Home']"));
    homeLink.click();
    

1.3 not() Function

Description:
The not() function negates a condition, allowing you to exclude certain elements from your selection. It’s useful for filtering out elements that meet a specific criterion.

Example:

//input[not(@type='hidden')]

This XPath selects <input> elements that do not have type='hidden'.

HTML Example:

<input type="text" name="username" id="user1">
<input type="hidden" name="sessionToken" id="token1">
<input type="password" name="password" id="pass1">

XPath Expressions and Selenium Examples:

  1. Selecting Visible Input Fields:

    //input[not(@type='hidden')]
    

    Selenium Example:

    // Locate all input fields that are not hidden
    List<WebElement> visibleInputs = driver.findElements(By.xpath("//input[not(@type='hidden')]"));
    for(WebElement input : visibleInputs) {
        System.out.println("Visible Input Name: " + input.getAttribute("name"));
    }
    
  2. Excluding Specific Classes:

    //div[not(@class='advertisement')]
    

    Selenium Example:

    // Locate all divs that do not have class='advertisement'
    List<WebElement> contentDivs = driver.findElements(By.xpath("//div[not(@class='advertisement')]"));
    for(WebElement div : contentDivs) {
        System.out.println("Content Div: " + div.getText());
    }
    

2. Comparison Operators

Comparison operators allow you to compare values within XPath expressions, enabling more dynamic and conditional element selection.

  1. =: Equal to.
  2. !=: Not equal to.
  3. <, >, <=, >=: Less than, greater than, less than or equal to, greater than or equal to.

2.1 = Operator (Equal to)

Description:
The = operator checks if an attribute or value is exactly equal to a specified value.

Example:

//input[@type='text' and @name='username']

This XPath selects <input> elements where type='text' and name='username'.

HTML Example:

<input type="text" name="username" id="user1">
<input type="password" name="password" id="pass1">
<input type="text" name="email" id="email1">

XPath Expressions and Selenium Examples:

  1. Selecting Username Input:

    //input[@type='text' and @name='username']
    

    Selenium Example:

    // Locate the username input field
    WebElement usernameInput = driver.findElement(By.xpath("//input[@type='text' and @name='username']"));
    usernameInput.sendKeys("TestUser");
    
  2. Selecting Password Input:

    //input[@type='password' and @name='password']
    

    Selenium Example:

    // Locate the password input field
    WebElement passwordInput = driver.findElement(By.xpath("//input[@type='password' and @name='password']"));
    passwordInput.sendKeys("SecurePass123");
    

2.2 != Operator (Not Equal to)

Description:
The != operator checks if an attribute or value is not equal to a specified value.

Example:

//input[@type!='hidden']

This XPath selects <input> elements where type is not 'hidden'.

HTML Example:

<input type="text" name="username" id="user1">
<input type="hidden" name="sessionToken" id="token1">
<input type="password" name="password" id="pass1">

XPath Expressions and Selenium Examples:

  1. Selecting Non-Hidden Inputs:

    //input[@type!='hidden']
    

    Selenium Example:

    // Locate all input fields that are not hidden
    List<WebElement> visibleInputs = driver.findElements(By.xpath("//input[@type!='hidden']"));
    for(WebElement input : visibleInputs) {
        System.out.println("Visible Input ID: " + input.getAttribute("id"));
    }
    
  2. Excluding Specific Buttons:

    //button[@type!='submit']
    

    Selenium Example:

    // Locate all buttons that are not of type 'submit'
    List<WebElement> nonSubmitButtons = driver.findElements(By.xpath("//button[@type!='submit']"));
    for(WebElement button : nonSubmitButtons) {
        System.out.println("Button Text: " + button.getText());
    }
    

2.3 <, >, <=, >= Operators (Less Than, Greater Than, etc.)

Description:
These operators allow you to compare numerical values within XPath expressions, enabling selection based on quantitative criteria.

Examples:

//tr[position() < 3]

This XPath selects all <tr> elements with a position less than 3.

//input[@maxlength >= 10]

This XPath selects <input> elements with a maxlength attribute value greater than or equal to 10.

HTML Example:

<table>
    <tr><td>Row 1</td></tr>
    <tr><td>Row 2</td></tr>
    <tr><td>Row 3</td></tr>
    <tr><td>Row 4</td></tr>
</table>

<form>
    <input type="text" name="input1" maxlength="8">
    <input type="text" name="input2" maxlength="12">
    <input type="text" name="input3" maxlength="15">
</form>

XPath Expressions and Selenium Examples:

  1. Selecting First Two Table Rows:

    //tr[position() < 3]
    

    Selenium Example:

    // Locate the first two table rows
    List<WebElement> firstTwoRows = driver.findElements(By.xpath("//tr[position() < 3]"));
    for(WebElement row : firstTwoRows) {
        System.out.println("Row Content: " + row.getText());
    }
    
  2. Selecting Inputs with Maxlength >= 10:

    //input[@maxlength >= 10]
    

    Selenium Example:

    // Locate input fields with maxlength >= 10
    List<WebElement> longInputs = driver.findElements(By.xpath("//input[@maxlength >= 10]"));
    for(WebElement input : longInputs) {
        System.out.println("Input Name: " + input.getAttribute("name") + ", Maxlength: " + input.getAttribute("maxlength"));
    }
    

Example Combining Logical Operators

Description:
Combining logical operators like and and or allows for highly specific and dynamic element selection based on multiple criteria.

Example:

//input[@type='text' and (@name='username' or @id='userInput')]

This XPath selects <input> elements with type='text' and either name='username' or id='userInput'.

HTML Example:

<input type="text" name="username" id="user1">
<input type="text" name="userInput" id="userInput">
<input type="text" name="email" id="email1">

XPath Expression and Selenium Example:

// XPath to select inputs with type='text' and (name='username' or id='userInput')
WebElement specificInput = driver.findElement(By.xpath("//input[@type='text' and (@name='username' or @id='userInput')]"));
specificInput.sendKeys("CombinedUser");

Explanation:

  • @type='text': The input must be of type text.
  • @name='username' or @id='userInput': The input must have either the name ‘username’ or the id ‘userInput’.
  • Combined with and: Both conditions must be satisfied for the element to be selected.

Complete Example Incorporating Functions and Operators

To solidify your understanding, let’s consider a comprehensive example that utilizes both XPath functions and operators within an HTML structure, followed by corresponding Selenium WebDriver code.

HTML Example:

<!DOCTYPE html>
<html>
<head>
    <title>XPath Functions and Operators Example</title>
</head>
<body>
    <form id="registrationForm">
        <div class="form-group">
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" maxlength="15">
        </div>
        <div class="form-group">
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" maxlength="20">
        </div>
        <div class="form-group">
            <label for="email">Email:</label>
            <input type="email" id="email" name="userEmail" maxlength="25">
        </div>
        <button type="submit" id="submitBtn" class="btn primary-button">Register</button>
        <button type="button" id="cancelBtn" class="btn secondary-button">Cancel</button>
    </form>
</body>
</html>

XPath Expressions and Selenium Examples:

  1. Using contains() to Locate the Submit Button:

    //button[contains(@class, 'primary')]
    

    Selenium Example:

    // Locate the submit button using contains()
    WebElement submitButton = driver.findElement(By.xpath("//button[contains(@class, 'primary')]"));
    submitButton.click();
    
  2. Using starts-with() to Locate Email Input:

    //input[starts-with(@name, 'user')]
    

    Selenium Example:

    // Locate the email input field using starts-with()
    WebElement emailInput = driver.findElement(By.xpath("//input[starts-with(@name, 'user')]"));
    emailInput.sendKeys("user@example.com");
    
  3. Using text() to Locate the Register Button:

    //button[text()='Register']
    

    Selenium Example:

    // Locate the Register button using text()
    WebElement registerButton = driver.findElement(By.xpath("//button[text()='Register']"));
    registerButton.click();
    
  4. Using normalize-space() to Ensure Accurate Text Matching:

    //button[normalize-space(text())='Cancel']
    

    Selenium Example:

    // Locate the Cancel button using normalize-space()
    WebElement cancelButton = driver.findElement(By.xpath("//button[normalize-space(text())='Cancel']"));
    cancelButton.click();
    
  5. Using last() to Select the Last Input Field:

    (//input)[last()]
    

    Selenium Example:

    // Locate the last input field in the form
    WebElement lastInput = driver.findElement(By.xpath("(//form[@id='registrationForm']//input)[last()]"));
    lastInput.sendKeys("lastinput@example.com");
    
  6. Using position() to Select the Second Input Field:

    (//input)[position()=2]
    

    Selenium Example:

    // Locate the second input field (Password)
    WebElement passwordInput = driver.findElement(By.xpath("(//input)[position()=2]"));
    passwordInput.sendKeys("SecurePass123");
    
  7. Using count() to Verify Number of Input Fields:

    count(//form[@id='registrationForm']//input)
    

    Selenium Example:

    // Execute JavaScript to count input fields within the form
    Long inputCount = (Long) ((JavascriptExecutor) driver).executeScript(
        "return document.querySelectorAll('#registrationForm input').length;");
    System.out.println("Number of Input Fields: " + inputCount);
    
  8. Combining Logical Operators to Locate Specific Input:

    //input[@type='text' and (@name='username' or @id='userInput')]
    

    Selenium Example:

    // Locate the username input field using combined logical operators
    WebElement usernameInput = driver.findElement(By.xpath("//input[@type='text' and (@name='username' or @id='userInput')]"));
    usernameInput.sendKeys("CombinedUser");
    

Conclusion

Mastering XPath Functions and XPath Operators significantly enhances your ability to interact with web elements in Selenium WebDriver. These tools provide the flexibility and precision needed to navigate complex DOM structures, handle dynamic content, and create robust automated tests.

Key Takeaways:

  • XPath Functions like contains(), starts-with(), text(), normalize-space(), last(), position(), and count() empower you to perform dynamic and conditional element selection.

  • Logical Operators (and, or, not()) and Comparison Operators (=, !=, <, >, <=, >=) allow for sophisticated queries, ensuring that your locators are both precise and resilient.

  • Best Practices include preferring relative XPath, using unique and stable attributes, minimizing indexing, leveraging functions and operators judiciously, and maintaining readable and maintainable XPath expressions.

By integrating these functions and operators into your automation scripts, you can tackle a wide range of testing scenarios with confidence and efficiency.