Bird
Raised Fist0
Selenium Pythontesting~5 mins

XPath with contains and starts-with in Selenium Python

Choose your learning style10 modes available
Introduction

XPath with contains and starts-with helps find elements when you only know part of their attribute or text. This makes tests more flexible and less fragile.

When the exact attribute value changes but has a common part.
When you want to find buttons or links starting with certain text.
When elements have dynamic IDs but share a prefix.
When you want to locate elements by partial text content.
When you want to avoid brittle tests that break on small UI changes.
Syntax
Selenium Python
//*[contains(@attribute, 'value')]
//*[starts-with(@attribute, 'value')]

contains() checks if the attribute or text has the given substring anywhere.

starts-with() checks if the attribute or text begins exactly with the given substring.

Examples
Finds any <button> element whose id attribute contains 'submit' anywhere.
Selenium Python
//button[contains(@id, 'submit')]
Finds any <a> link element whose visible text starts with 'Log'.
Selenium Python
//a[starts-with(text(), 'Log')]
Finds any element with a class attribute containing 'active'.
Selenium Python
//*[contains(@class, 'active')]
Finds any <input> element whose name attribute starts with 'user'.
Selenium Python
//input[starts-with(@name, 'user')]
Sample Program

This script opens a simple HTML page with buttons and links. It uses XPath with contains and starts-with to find elements by partial attribute values and text. It prints the found elements' text or tag name to show the correct elements were found.

Selenium Python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

# Setup WebDriver (make sure chromedriver is in PATH)
options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)

# Open a simple test page with buttons
html = '''
<html>
  <body>
    <button id="btn_submit_123">Submit</button>
    <button id="btn_cancel_456">Cancel</button>
    <a href="#" class="link active">Login</a>
    <a href="#" class="link">Logout</a>
  </body>
</html>
'''

# Use data URL to load HTML
driver.get("data:text/html;charset=utf-8," + html)

# Find button with id containing 'submit'
submit_button = driver.find_element(By.XPATH, "//button[contains(@id, 'submit')]")
print(submit_button.text)  # Should print 'Submit'

# Find link starting with text 'Log'
link = driver.find_element(By.XPATH, "//a[starts-with(text(), 'Log')]")
print(link.text)  # Should print 'Login'

# Find element with class containing 'active'
active_link = driver.find_element(By.XPATH, "//*[contains(@class, 'active')]")
print(active_link.tag_name)  # Should print 'a'

# Find button starting with id 'btn_cancel'
cancel_button = driver.find_element(By.XPATH, "//button[starts-with(@id, 'btn_cancel')]")
print(cancel_button.text)  # Should print 'Cancel'

# Close driver
driver.quit()
OutputSuccess
Important Notes

Always prefer unique and stable attributes for locating elements.

Using contains and starts-with helps when attributes change dynamically.

Test your XPath expressions in browser DevTools before using them in code.

Summary

contains() finds elements with attribute or text containing a substring.

starts-with() finds elements with attribute or text starting with a substring.

These XPath functions make locating elements more flexible and reliable.

Practice

(1/5)
1. Which XPath function would you use to find an element whose id attribute contains the text "submit" anywhere inside it?
easy
A. starts-with(@id, 'submit')
B. contains(@id, 'submit')
C. ends-with(@id, 'submit')
D. equals(@id, 'submit')

Solution

  1. Step 1: Understand the contains() function

    The contains() function checks if an attribute or text includes a specific substring anywhere inside it.
  2. Step 2: Apply contains() to the id attribute

    Using contains(@id, 'submit') finds elements where the id attribute has 'submit' anywhere in its value.
  3. Final Answer:

    contains(@id, 'submit') -> Option B
  4. Quick Check:

    contains() = substring anywhere [OK]
Hint: Use contains() to match substring anywhere in attribute [OK]
Common Mistakes:
  • Using starts-with() when substring is not at start
  • Using ends-with() which is not supported in XPath 1.0
  • Using equals() which requires exact match
2. Which of the following is the correct XPath syntax to select elements whose class attribute starts with "btn-"?
easy
A. //element[@class^='btn-']
B. //element[contains(@class, 'btn-')]
C. //element[starts-with(@class, 'btn-')]
D. //element[@class*='btn-']

Solution

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

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

    The correct syntax is //element[starts-with(@class, 'btn-')]. Options C and D use invalid XPath syntax for this purpose.
  3. Final Answer:

    //element[starts-with(@class, 'btn-')] -> Option C
  4. Quick Check:

    starts-with() = prefix match [OK]
Hint: Use starts-with() for prefix matching in XPath [OK]
Common Mistakes:
  • Using contains() instead of starts-with() for prefix
  • Using CSS selector syntax like ^= or *= in XPath
  • Missing parentheses in function call
3. What will be the result of this XPath query?
//div[contains(text(), 'Error') and starts-with(@class, 'alert-')]

Assuming the HTML contains:
<div class="alert-danger">Error: Invalid input</div>
<div class="alert-success">Success</div>
<div class="message-error">Error occurred</div>
medium
A. Selects only the div with class 'alert-danger'
B. Selects no elements
C. Selects all div elements containing 'Error'
D. Selects the first and second div elements

Solution

  1. Step 1: Analyze contains(text(), 'Error')

    This matches div elements whose visible text includes 'Error'. The first and third divs contain 'Error'.
  2. Step 2: Analyze starts-with(@class, 'alert-')

    This matches div elements whose class attribute starts with 'alert-'. The first and second divs match this.
  3. Step 3: Combine both conditions with AND

    Only the first div satisfies both: text contains 'Error' and class starts with 'alert-'.
  4. Final Answer:

    Selects only the div with class 'alert-danger' -> Option A
  5. Quick Check:

    AND filters to first div only [OK]
Hint: AND requires both conditions true for selection [OK]
Common Mistakes:
  • Assuming contains() matches attribute instead of text
  • Ignoring the starts-with() condition
  • Selecting all divs with 'Error' ignoring class prefix
4. You wrote this XPath to find buttons starting with "save":
//button[contains(@id, 'save-')]

But it also matches buttons with id "disable-save". How to fix it?
medium
A. //button[starts-with(@id, 'save-')]
B. //button[contains(text(), 'save-')]
C. //button[@id='save-']
D. //button[ends-with(@id, 'save-')]

Solution

  1. Step 1: Understand why contains() matches unwanted ids

    contains(@id, 'save-') matches any id containing 'save-' anywhere, including 'disable-save'.
  2. Step 2: Use starts-with() to match only ids beginning with 'save-'

    starts-with(@id, 'save-') ensures only ids starting exactly with 'save-' are matched.
  3. Final Answer:

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

    starts-with() fixes unwanted matches [OK]
Hint: Use starts-with() to avoid partial matches inside strings [OK]
Common Mistakes:
  • Using contains() when prefix match is needed
  • Using ends-with() which XPath 1.0 does not support
  • Matching text() instead of attribute
5. You want to select all <a> elements where the href attribute starts with "https://" and the link text contains "Learn". Which XPath expression correctly does this?
hard
A. //a[contains(@href, 'https://') and contains(text(), 'Learn')]
B. //a[contains(text(), 'https://') and starts-with(@href, 'Learn')]
C. //a[starts-with(text(), 'Learn') and contains(@href, 'https://')]
D. //a[starts-with(@href, 'https://') and contains(text(), 'Learn')]

Solution

  1. Step 1: Match href attribute starting with 'https://'

    Use starts-with(@href, 'https://') to ensure href begins exactly with 'https://'.
  2. Step 2: Match link text containing 'Learn'

    Use contains(text(), 'Learn') to find links whose visible text includes 'Learn' anywhere.
  3. Step 3: Combine both conditions with AND

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

    //a[starts-with(@href, 'https://') and contains(text(), 'Learn')] -> Option D
  5. Quick Check:

    starts-with() + contains() combined correctly [OK]
Hint: Combine starts-with() for attribute and contains() for text [OK]
Common Mistakes:
  • Using contains() for href prefix instead of starts-with()
  • Swapping text() and attribute in functions
  • Using starts-with() on text when contains() is needed
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