Creating your own locator delegate functions
Custom locator delegates help simplify complex selector strategies by providing a more concise and readable way to define element locators. They leverage existing locator delegate functions to create domain-specific, reusable locator methods.
Motivation
When working with web applications, you often find yourself repeating similar selector patterns. Custom locator delegates allow you to:
- Reduce boilerplate code.
- Improve readability of element locators.
- Encapsulate complex selector logic.
- Maintain consistent locator strategies across your test suite.
Creating custom locator delegates
Creating a custom locator delegate involves:
- Creating a new locator delegate function using an existing locator delegate (like
xPath
). - Defining a specific selector (query string) strategy.
- Delegating the optional configuration parameters to the existing locator delegate function.
Example: data-test attribute locator delegates
In many modern web applications, elements are annotated with data-test attributes for easier testing. Here's how you can create custom locator delegates for such scenarios.
// Single element locator for data-test attribute.
fun SearchContext.dataTest(
value: String,
cacheLookup: Boolean = true,
wait: Wait = defaultWaitConfig,
readyCondition: WebElement.() -> Boolean = defaultElementReadyCondition,
) = xPath("//*[@data-test='$value']", cacheLookup, wait, readyCondition)
// Multiple elements locator for data-test attribute.
fun SearchContext.dataTests(
value: String,
cacheLookup: Boolean = true,
wait: Wait = defaultWaitConfig,
readyCondition: WebElements.() -> Boolean = defaultElementsReadyCondition,
) = xPaths("//*[@data-test='$value']", cacheLookup, wait, readyCondition)
note
The data-test
and data-tests
locator delegates have been available in Kolibrium's Selenium module since version 0.6.0.
Usage in Page Objects
private val sortMenu by driver.dataTest("product-sort-container")
private val products by driver.dataTests("inventory-item")