XPath functions (contains, starts-with) in Selenium Java - Build an Automation Script
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.
Now add data-driven testing with 3 different button class name fragments to locate the login button using contains()
Practice
Solution
Step 1: Understand the purpose of
Thecontains()contains()function checks if an attribute or text contains a given substring anywhere inside it.Step 2: Compare with other functions
starts-with()checks only the beginning,ends-with()is not standard XPath 1.0, andequals()is not an XPath function.Final Answer:
contains() -> Option CQuick Check:
Substring anywhere = contains() [OK]
- Confusing contains() with starts-with()
- Using ends-with() which is not standard XPath 1.0
- Trying to use equals() as XPath function
id attribute starts with "submit"?Solution
Step 1: Identify the correct XPath function for 'starts with'
The functionstarts-with()is used to check if an attribute starts with a substring.Step 2: Check syntax correctness
//button[starts-with(@id, 'submit')]is correct XPath syntax. Options B and C use invalid XPath operators.Final Answer:
//button[starts-with(@id, 'submit')] -> Option DQuick Check:
Starts with = starts-with() [OK]
- Using contains() instead of starts-with() for prefix
- Using CSS selector syntax like ^= in XPath
- Incorrect function syntax or missing parentheses
<input type="text" id="user_email" value="test@example.com"/>
What is the result of this XPath query?
//*[@id[contains(., 'user')]]Solution
Step 1: Analyze the XPath syntax
The XPath//*[@id[contains(., 'user')]]is syntactically incorrect because@idis an attribute node and cannot be used as a function or have predicates applied directly like this.Step 2: Correct XPath syntax
To check if theidattribute contains 'user', the correct XPath is//*[@id[contains(., 'user')]]is invalid; instead use//*[contains(@id, 'user')].Final Answer:
Syntax error due to incorrect XPath function usage -> Option AQuick Check:
Attribute predicates must be correctly formed [OK]
- Using predicates directly on attribute nodes
- Assuming . refers to attribute value in this context
- Incorrect predicate syntax
//a[contains(starts-with(@href, 'http'))]Why does this XPath fail to find any elements?
Solution
Step 1: Understand function nesting rules in XPath
Thecontains()function expects two string arguments, but here it wrapsstarts-with()which returns a boolean, causing a syntax error.Step 2: Correct usage
Use eitherstarts-with(@href, 'http')alone orcontains(@href, 'http'), but not nested.Final Answer:
Because contains() cannot wrap starts-with() function -> Option BQuick Check:
Do not nest contains() and starts-with() [OK]
- Nesting contains() and starts-with() incorrectly
- Assuming starts-with() returns string for contains()
- Ignoring function argument requirements
<div> elements whose class attribute starts with "alert" but excludes those that contain "dismiss" anywhere in the class. Which XPath expression correctly achieves this?Solution
Step 1: Use starts-with() to match class beginning
The expressionstarts-with(@class, 'alert')selects elements whose class attribute begins with "alert".Step 2: Exclude elements containing 'dismiss'
Thenot(contains(@class, 'dismiss'))excludes elements whose class contains "dismiss" anywhere.Step 3: Combine conditions with and
Both conditions must be true, so useandto combine them.Final Answer:
//div[starts-with(@class, 'alert') and not(contains(@class, 'dismiss'))] -> Option AQuick Check:
Starts with alert AND no dismiss = //div[starts-with(@class, 'alert') and not(contains(@class, 'dismiss'))] [OK]
- Using or instead of and causing wrong matches
- Mixing contains() and starts-with() incorrectly
- Forgetting to negate contains() for exclusion
Ready to prove it?
Pass the test and this pattern moves unknown
