Skip to main content

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 function that composes an existing locator delegate (for example, cssSelector or xpath).
  • Defining the selector (query string) strategy.
  • Passing through the optional configuration parameters (such as cacheLookup, waitConfig, and readyWhen) to the underlying locator delegate.

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,
waitConfig: WaitConfig? = null,
readyWhen: (WebElement.() -> Boolean)? = null,
) = cssSelector(
value = "[data-test=\"$value\"]",
cacheLookup = cacheLookup,
waitConfig = waitConfig,
readyWhen = readyWhen,
)

// Multiple elements locator for data-test attribute.
fun SearchContext.dataTests(
value: String,
waitConfig: WaitConfig? = null,
readyWhen: (WebElements.() -> Boolean)? = null,
) = cssSelectors(
value = "[data-test=\"$value\"]",
waitConfig = waitConfig,
readyWhen = readyWhen,
)
note

Kolibrium already provides dataTest and dataTests delegates in the Selenium module. Use this example as a template for creating your own attribute-based delegates.

Usage in Page Objects

private val sortMenu by driver.dataTest("product-sort-container")

private val products by driver.dataTests("inventory-item")