Selectorless testing eliminates the need for brittle selectors like CSS classes, IDs, or XPath.

Instead, TestDriver uses natural language prompts and AI-powered vision to interact with applications as a user would. This makes tests more resilient to UI changes and reduces maintenance overhead.

  • Selectorless testing focuses on what the user sees rather than how the UI is implemented.
  • Tests are resilient to changes like text updates, class renaming, or minor layout adjustments.
  • By using natural language and AI vision, TestDriver simplifies test creation and maintenance.

What’s selectorless testing?

The following is an example of a TestDriver test.

version: 4.2.18
steps:
  - prompt: Click the "Sign Up" button
    commands:
      - command: hover-text
        text: Sign Up
        description: button in the header for user registration
        action: click
  - prompt: Assert the registration form is displayed
    commands:
      - command: assert
        expect: The registration form is visible

This allows TestDriver locates the target for hover-text based on its context and description. The agent will search for elements: in the following order.

  • text - exact element to match
  • description - a description of the element given the exact text isn’t found, or there are multiple matches
  • prompt - a high level prompt used to regenerate the test if no match is found

What happens when “Sign Up” changes to “Register”?

If the button text changes to “Register,” TestDriver’s AI vision will still locate the button based on its context and description. You don’t need to update the test manually. TestDriver will then update the test to reflect the new UI by modifying the text field. Then, it will open a new pull request with the changes.

version: 4.2.18
steps:
  - prompt: Click the "Register" button
    commands:
      - command: hover-text
        text: Register
        description: button in the header for user registration
        action: click

Why selectorless testing?

Traditional testing frameworks rely on selectors tightly coupled to the codebase. For example:

const button = await page.$('button[class="sign-up-btn"]');
When using legacy frameworks, if the class name changes, the test will break, requiring updates to the test code!
Selectorless testing avoids this by focusing on the intent of the interaction rather than the implementation details.