Bird
Raised Fist0
Selenium Pythontesting~8 mins

XPath with contains and starts-with in Selenium Python - Framework Patterns

Choose your learning style10 modes available
Framework Mode - XPath with contains and starts-with
Folder Structure
selenium_python_project/
├── src/
│   ├── pages/
│   │   └── login_page.py          # Page Object classes with XPath locators
│   ├── tests/
│   │   └── test_login.py           # Test cases using page objects
│   ├── utils/
│   │   └── helpers.py              # Utility functions (e.g., wait helpers)
│   └── config/
│       └── config.yaml             # Environment and browser settings
├── requirements.txt                # Python dependencies
├── pytest.ini                     # Pytest configuration
└── conftest.py                    # Fixtures for setup/teardown
    
Test Framework Layers
  • Driver Layer: Manages WebDriver setup and teardown (in conftest.py).
  • Page Objects: Classes in src/pages/ define web elements using XPath with contains() and starts-with() for flexible locators.
  • Tests: Test scripts in src/tests/ use page objects to perform actions and assertions.
  • Utilities: Helper functions for waits, logging, or data handling in src/utils/.
  • Configuration: Environment variables, browser options, and credentials stored in src/config/config.yaml.
Configuration Patterns

Use a YAML file (config.yaml) to store environment URLs, browser choices, and credentials. Load this config in conftest.py to initialize WebDriver accordingly.

# Example config.yaml
base_url: "https://example.com"
browser: "chrome"
credentials:
  username: "testuser"
  password: "securepass"
    

This keeps sensitive data separate and allows easy switching between environments.

Test Reporting and CI/CD Integration
  • Use pytest with plugins like pytest-html to generate readable HTML reports.
  • Integrate tests into CI/CD pipelines (e.g., GitHub Actions, Jenkins) to run tests automatically on code changes.
  • Reports help quickly see which XPath locators passed or failed, especially those using contains() and starts-with().
Best Practices
  • Use contains() in XPath to locate elements with partial attribute values, making tests resilient to small UI changes.
  • Use starts-with() to match elements whose attributes begin with a known string, useful for dynamic IDs.
  • Keep XPath expressions readable and maintainable by defining them as variables or constants in page objects.
  • Use explicit waits to ensure elements located by XPath are present before interacting.
  • Separate locators from test logic by using the Page Object Model for cleaner, reusable code.
Self Check

Where in this framework structure would you add a new XPath locator using contains() for a "Sign Up" button?

Key Result
Use Page Object Model with XPath contains() and starts-with() for flexible, maintainable element locators in Selenium Python tests.

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