Bird
Raised Fist0
Selenium Javatesting~15 mins

XPath functions (contains, starts-with) in Selenium Java - Build an Automation Script

Choose your learning style10 modes available
Verify login button using XPath functions contains and starts-with
Preconditions (1)
Step 1: Locate the login button using XPath with contains() function on the button's class attribute containing 'btn-login'
Step 2: Verify the login button is displayed
Step 3: Locate the login button using XPath with starts-with() function on the button's id attribute starting with 'loginBtn'
Step 4: Verify the login button is enabled
✅ Expected Result: The login button is found using both XPath functions and is displayed and enabled
Automation Requirements - Selenium WebDriver with Java
Assertions Needed:
Assert that the login button located by contains() XPath is displayed
Assert that the login button located by starts-with() XPath is enabled
Best Practices:
Use explicit waits to wait for the login button to be present and visible
Use By.xpath locator with correct XPath syntax
Use meaningful variable names
Close the browser after test execution
Automated Solution
Selenium Java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Duration;

public class LoginButtonXPathTest {
    private WebDriver driver;
    private WebDriverWait wait;

    @BeforeEach
    public void setUp() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        driver.get("https://example.com/login");
    }

    @Test
    public void testLoginButtonUsingXPathFunctions() {
        // Locate login button using contains() on class attribute
        By loginBtnContains = By.xpath("//button[contains(@class, 'btn-login')]");
        WebElement buttonContains = wait.until(ExpectedConditions.visibilityOfElementLocated(loginBtnContains));
        assertTrue(buttonContains.isDisplayed(), "Login button located by contains() should be displayed");

        // Locate login button using starts-with() on id attribute
        By loginBtnStartsWith = By.xpath("//button[starts-with(@id, 'loginBtn')]");
        WebElement buttonStartsWith = wait.until(ExpectedConditions.elementToBeClickable(loginBtnStartsWith));
        assertTrue(buttonStartsWith.isEnabled(), "Login button located by starts-with() should be enabled");
    }

    @AfterEach
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

This test uses Selenium WebDriver with Java to automate the manual test case.

In setUp(), we open the Chrome browser and navigate to the login page.

In the test method, we use By.xpath with contains() to find the login button by part of its class attribute. We wait explicitly until it is visible, then assert it is displayed.

Next, we use starts-with() to find the login button by the start of its id attribute. We wait until it is clickable, then assert it is enabled.

Finally, in tearDown(), we close the browser to clean up.

This approach uses explicit waits to avoid timing issues and uses clear assertions to verify the button's presence and state.

Common Mistakes - 3 Pitfalls
Using Thread.sleep() instead of explicit waits
Using absolute XPath instead of relative XPath with functions
Not verifying element visibility or enabled state before interacting
Bonus Challenge

Now add data-driven testing with 3 different button class name fragments to locate the login button using contains()

Show Hint

Practice

(1/5)
1. Which XPath function would you use to locate elements whose attribute contains a specific substring anywhere within it?
easy
A. starts-with()
B. ends-with()
C. contains()
D. equals()

Solution

  1. Step 1: Understand the purpose of contains()

    The contains() function checks if an attribute or text contains a given substring anywhere inside it.
  2. Step 2: Compare with other functions

    starts-with() checks only the beginning, ends-with() is not standard XPath 1.0, and equals() is not an XPath function.
  3. Final Answer:

    contains() -> Option C
  4. Quick Check:

    Substring anywhere = contains() [OK]
Hint: Use contains() for substring anywhere inside attribute [OK]
Common Mistakes:
  • Confusing contains() with starts-with()
  • Using ends-with() which is not standard XPath 1.0
  • Trying to use equals() as XPath function
2. Which of the following is the correct XPath syntax to find a button element whose id attribute starts with "submit"?
easy
A. //button[contains(@id, 'submit')]
B. //button[@id*='submit']
C. //button[@id^='submit']
D. //button[starts-with(@id, 'submit')]

Solution

  1. Step 1: Identify the correct XPath function for 'starts with'

    The function starts-with() is used to check if an attribute starts with a substring.
  2. Step 2: Check syntax correctness

    //button[starts-with(@id, 'submit')] is correct XPath syntax. Options B and C use invalid XPath operators.
  3. Final Answer:

    //button[starts-with(@id, 'submit')] -> Option D
  4. Quick Check:

    Starts with = starts-with() [OK]
Hint: Use starts-with(@attr, 'text') for prefix matching [OK]
Common Mistakes:
  • Using contains() instead of starts-with() for prefix
  • Using CSS selector syntax like ^= in XPath
  • Incorrect function syntax or missing parentheses
3. Given the following HTML snippet:
<input type="text" id="user_email" value="test@example.com"/>

What is the result of this XPath query?
//*[@id[contains(., 'user')]]
medium
A. Syntax error due to incorrect XPath function usage
B. Selects all elements with any id attribute
C. Selects the input element because its id contains 'user'
D. Selects no elements because 'user' is not in the value attribute

Solution

  1. Step 1: Analyze the XPath syntax

    The XPath //*[@id[contains(., 'user')]] is syntactically incorrect because @id is an attribute node and cannot be used as a function or have predicates applied directly like this.
  2. Step 2: Correct XPath syntax

    To check if the id attribute contains 'user', the correct XPath is //*[@id[contains(., 'user')]] is invalid; instead use //*[contains(@id, 'user')].
  3. Final Answer:

    Syntax error due to incorrect XPath function usage -> Option A
  4. Quick Check:

    Attribute predicates must be correctly formed [OK]
Hint: Use contains(@id, 'user') not @id[contains()] [OK]
Common Mistakes:
  • Using predicates directly on attribute nodes
  • Assuming . refers to attribute value in this context
  • Incorrect predicate syntax
4. You wrote this XPath to find links starting with "http":
//a[contains(starts-with(@href, 'http'))]
Why does this XPath fail to find any elements?
medium
A. Because @href attribute is missing
B. Because contains() cannot wrap starts-with() function
C. Because starts-with() requires two arguments
D. Because the syntax is correct but no links start with 'http'

Solution

  1. Step 1: Understand function nesting rules in XPath

    The contains() function expects two string arguments, but here it wraps starts-with() which returns a boolean, causing a syntax error.
  2. Step 2: Correct usage

    Use either starts-with(@href, 'http') alone or contains(@href, 'http'), but not nested.
  3. Final Answer:

    Because contains() cannot wrap starts-with() function -> Option B
  4. Quick Check:

    Do not nest contains() and starts-with() [OK]
Hint: Do not nest XPath functions like contains(starts-with()) [OK]
Common Mistakes:
  • Nesting contains() and starts-with() incorrectly
  • Assuming starts-with() returns string for contains()
  • Ignoring function argument requirements
5. You want to locate all <div> elements whose class attribute starts with "alert" but excludes those that contain "dismiss" anywhere in the class. Which XPath expression correctly achieves this?
hard
A. //div[starts-with(@class, 'alert') and not(contains(@class, 'dismiss'))]
B. //div[contains(@class, 'alert') and not(starts-with(@class, 'dismiss'))]
C. //div[starts-with(@class, 'alert') or not(contains(@class, 'dismiss'))]
D. //div[contains(@class, 'alert') or contains(@class, 'dismiss')]

Solution

  1. Step 1: Use starts-with() to match class beginning

    The expression starts-with(@class, 'alert') selects elements whose class attribute begins with "alert".
  2. Step 2: Exclude elements containing 'dismiss'

    The not(contains(@class, 'dismiss')) excludes elements whose class contains "dismiss" anywhere.
  3. Step 3: Combine conditions with and

    Both conditions must be true, so use and to combine them.
  4. Final Answer:

    //div[starts-with(@class, 'alert') and not(contains(@class, 'dismiss'))] -> Option A
  5. Quick Check:

    Starts with alert AND no dismiss = //div[starts-with(@class, 'alert') and not(contains(@class, 'dismiss'))] [OK]
Hint: Combine starts-with() and not(contains()) with and [OK]
Common Mistakes:
  • Using or instead of and causing wrong matches
  • Mixing contains() and starts-with() incorrectly
  • Forgetting to negate contains() for exclusion
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard