search ESC

Searching…

No results for "".

Type at least 2 characters to search.

Docs
You are viewing an older version (0.0.1). Go to the latest.

dusk:find

Mint a re-resolvable q handle backed by one or more predicates (text, semanticsLabel, key). Mirrors Playwright's Locator semantics: every action call against a qN handle re-walks the live Semantics tree on each invocation, so the handle survives intermediate widget rebuilds without going stale.

qN and eN token spaces are disjoint. A handle minted by dusk:find is always qN; a handle harvested from dusk:snap is always eN. The dispatcher distinguishes by prefix, but action commands accept either shape via --ref=.


Table of contents


Synopsis

dart run fluttersdk_dusk dusk:find [--text=]
                                    [--contains=]
                                    [--semanticsLabel=]
                                    [--key=]

dusk:find requires a running Flutter session (CommandBoot.connected). It dials the VM Service URI, calls ext.dusk.find with the supplied predicates, and prints the minted handle envelope as pretty-printed JSON.

At least one of the four options must be non-empty; an empty params map returns exit code 1 with a CLI-side error before the VM Service call.


Arguments

Option Type Default Description
--text string unset Exact match against the widget's visible text label (the Semantics value or rendered Text content). Most common predicate; mirrors Playwright's getByText with exact-match semantics.
--contains string unset Substring match against the visible text label or Semantics label (case-sensitive). Use when the label is dynamic (counters, timestamps, plurals) and exact --text is too brittle.
--semanticsLabel string unset Exact match against the widget's accessibility label (the explicit Semantics(label: ...) value set by the widget tree). Use when the visible text and the a11y label diverge.
--key string unset Match the widget's ValueKey identifier (the Key('signin-button') form). Most precise; survives label and copy changes.

The predicates compose AND: a dusk:find --text=Sign --key=signin-button call returns the widget that matches both. Use a single predicate when the agent only needs one axis.

The CLI guards an empty params map (Provide at least one of --text / --contains / --semanticsLabel / --key.) so the VM Service handler never sees a zero-predicate call.


Returns

dusk:find returns an integer exit code via Future:

Exit code Meaning
0 Handle minted (or re-used; the registry is content-addressed). The handler emits the JSON envelope below.
1 No predicate supplied. The CLI guard fires before the VM Service call.
non-zero VM Service handler returned ServiceExtensionResponse.error. Typical cause: the predicate matched zero widgets (no matches surfaces as a structured failure so the agent knows to broaden the predicate).

Success envelope (illustrative):

{
  "ref": "q1",
  "matchCount": 1,
  "rect": [120, 400, 240, 48],
  "role": "button",
  "label": "Sign in"
}

matchCount > 1 indicates the predicate is ambiguous: the handle still resolves to the first match, but the agent should narrow with an extra predicate (typically --key) before acting.

Error envelope:

The VM Service handler propagates errors as ServiceExtensionResponse.error(extensionError, message). The CLI surfaces them via ArtisanContext.callExtension and exits non-zero. Common messages include No widget matched predicates: {...}.


Re-resolution semantics

A qN handle stores the predicate map, not the matched widget. Every action call (dusk:tap --ref=q1, dusk:type --ref=q1, etc.) re-executes the query against the live Semantics tree. Three consequences:

  1. Widget rebuilds don't invalidate the handle. A ListView swap, a navigation transition, or a state-driven rebuild all leave the handle valid as long as the predicates still match something.
  2. The query is re-run on every action. Cheap (a Semantics walk on each call), but emergent if the predicate is broad: prefer --key over --text for hot paths.
  3. dusk:find itself is idempotent in the registry. Calling it twice with the same predicate map returns the same qN; the registry is content-addressed.

eN handles minted by dusk:snap work the opposite way: they freeze the matched widget at snap time and go stale on the next rebuild. Use eN for one-shot reads, qN for any sequence that spans more than one frame.


Examples

1. Mint a handle by visible text

dart run fluttersdk_dusk dusk:find --text="Sign in"

Expected output (illustrative):

{
  "ref": "q1",
  "matchCount": 1,
  "rect": [120, 400, 240, 48],
  "role": "button",
  "label": "Sign in"
}

Reuse q1 across subsequent action calls:

dart run fluttersdk_dusk dusk:tap --ref=q1

2. Mint a handle by accessibility label

dart run fluttersdk_dusk dusk:find --semanticsLabel="Submit form"

Use when the rendered button text is an icon and the only stable predicate is the a11y label.

3. Mint a handle by widget key (most precise)

dart run fluttersdk_dusk dusk:find --key="signin-submit"

Survives copy changes and a11y-label changes. Pair with a widget-side Key('signin-submit') declaration.

4. Mint a handle by substring (dynamic label)

dart run fluttersdk_dusk dusk:find --contains="pushed the button"

Useful when the visible label is dynamic, e.g. "You have pushed the button 5 times:" (counter changes per tap). --text would only match the exact string at the moment of capture; --contains survives the counter advancing.

5. Compose two predicates to disambiguate

dart run fluttersdk_dusk dusk:find --text="Save" --key="monitor-form-save"

The two predicates AND together; useful when the screen has multiple "Save" buttons but only one with the canonical key.


See also

  • dusk:snap: produce eN refs for one-shot reads.
  • dusk:tap: consume the qN ref to synthesise a tap.
  • dusk:observe: structured candidate list of every interactive widget; useful when the agent doesn't know which predicate to query.