page.find() — Smart Selector with Failover

A locator wrapper that automatically tries fallback selectors when the primary one cannot be found, reducing test failures from minor markup changes.

page.find returns a SmartSelector — a locator wrapper that automatically tries a list of fallback selectors when the primary one cannot be found. Use it for elements whose selector may drift between deployments, reducing the frequency of test failures due to minor markup changes.

Signature

page.find(
  selector: string,
  options?: {
    failover?: string[];
    frame?: string;
  }
): SmartSelector

Parameters

ParameterTypeDefaultDescription
selectorstringThe primary CSS selector or Playwright locator expression
options.failoverstring[][]Ordered list of fallback selectors to try if the primary fails
options.framestringSelector for the iframe to search within

Return type

A SmartSelector that supports the same interaction methods as a Playwright Locator (.click(), .fill(), .isVisible(), etc.).

Basic usage

import { test } from 'donobu';

test('submit the form', async ({ page }) => {
  await page.goto('https://app.example.com/form');

  const submitButton = page.find('[data-testid="submit-btn"]', {
    failover: ['button:has-text("Submit")', 'button:has-text("Continue")'],
  });

  await submitButton.click();
});

Donobu tries the selectors in order: [data-testid="submit-btn"] first, then button:has-text("Submit"), then button:has-text("Continue"). The first one that locates a visible element wins.

Within an iframe

const acceptButton = page.find('#accept-cookies', {
  frame: 'iframe[title="Cookie Consent"]',
  failover: ['button:has-text("Accept")'],
});

await acceptButton.click();

When to use page.find vs. page.locator

Use page.find when…Use page.locator when…
The element may have different selectors across environments or versionsYou are confident the selector is stable
You want to future-proof a critical interaction without relying solely on self-healingYou need the full Playwright locator API (chaining, filtering, etc.)
The element is inside an iframeThe element is in the main frame with a stable selector

Notes

  • page.find uses the same type of selectors that Donobu generates when caching a page.ai call. When page.ai records an action like a click during an autonomous run, it stores the element's selector — potentially with failover alternatives — in the cache. page.find gives you the same multi-selector mechanism so you can apply it in your own hand-written interactions.
  • Selectors are tried in the order they appear in the failover array.
  • If all selectors fail, SmartSelector throws the same error as a Playwright Locator that cannot find its element.
  • page.find is synchronous — the SmartSelector is constructed immediately, just like Playwright's page.locator(). The selector evaluation happens when you call an action (e.g. .click()), not when page.find is called.