dánwòdánwò

Test API

agent

Plain-English steps: act, assert, extract and waitFor, verified and cached for replay.

tests/upgrade.danwo.ts
await agent.act("upgrade the workspace to the Pro plan")
await agent.assert("the invoice preview shows a prorated amount")

Plain-language steps (act), claims (assert), typed reads (extract) and waits (waitFor). A verified step is recorded and replays with no model call.

Agent

interface

The agent fixture: steps and claims in plain language, replayed from recordings when it can.

MemberDescription
act(instruction: string, options?: ActOptions): Promise<ActResult>Carries out instruction on the page, replaying a recording of it when there is one.
extract<T>(instruction: string, schema: z.ZodType<T>, options?: ExtractOptions): Promise<T>Reads typed data off the page: extract("the account balance", z.object({ balance: z.number() })). The model points at the elements that show each value and the runner reads them, so values come from the page, never from the model; the result is checked against schema. A recording of where each value was read replays with no model call.
assert(claim: string, options?: AssertOptions): Promise<void>Asks the judge whether claim holds for the page as it is now; throws when it does not. With poll, asks again until it holds or the time is up.
waitFor(condition: string, options?: WaitForOptions): Promise<void>Waits until condition holds, e.g. waitFor("the order shows as paid"). The judge looks at the page until it does and names text on it that shows so; a recording of that text replays by waiting for it to appear, with no model call. Throws WAIT_TIMED_OUT when time runs out.

ActOptions

interface

Options of agent.act.

MemberDescription
params?: ParamsValues the instruction names in braces, e.g. { params: { email: unique("ada@x.test") } }.
files?: Readonly<Record<string, string>>Files the step may upload, by name: { files: { avatar: "fixtures/avatar.png" } }. The agent sees only the names; paths resolve against the project root. A recording keeps the names, so a replay needs the same names offered again.
budget?: BudgetLimits for this step, over the session's: turns, model calls, cost and wall time.
effects?: booleanWhether a replay of this step must have the effects its recording had, on the page and behind it (default true, unless the session turned effects off). false replays its actions only.
vision?: VisionChoiceWhether the step may see the page as an image, over the session's vision: true shows a screenshot with every view, "auto" offers it when the text view misses something, false keeps to the text view. Actions on a screenshot replay by finding their place by how it looks.
time?: booleanWhether the step may move time forward with the travel_time tool (default false), e.g. "wait until the trial ends". Each move is recorded, so a replay travels the same way.

ActResult

interface

What agent.act resolves with.

MemberDescription
summary: stringWhat the step did, in the agent's words (or the replay's).
modelCalls: numberModel calls the step made; 0 when it replayed a recording.
actions: numberActions taken on the page.

AssertOptions

interface

Options of agent.assert.

MemberDescription
poll?: PollOptionAsk the judge again until the claim holds or time runs out, instead of once.
vision?: VisionChoiceWhether the judge also sees a screenshot: true always, "auto" when the page has parts the text view misses (a canvas, unnamed buttons, unlisted frames), false never.
replay?: booleanfalse asks the judge on every run and keeps no recording, for a claim whose meaning can change while its text stays (the total is right). Default true: a replay waits for the text the judge named, with no model call.

ExtractOptions

interface

Options of agent.extract.

MemberDescription
params?: ParamsValues the instruction names in braces, as for act.
vision?: VisionChoiceWhether values may be read off a screenshot when the text view does not show them (a canvas, a chart): true always offers it, "auto" when the page has such parts, false never. Values read off a screenshot are checked by the schema, and the step then needs the model again on every run, since what an image shows cannot be read back without one.

WaitForOptions

interface

Options of agent.waitFor.

MemberDescription
timeout?: numberHow long to wait, in milliseconds; default 30 000.
interval?: numberHow often the judge looks while the condition does not hold yet; default 1 000.
params?: ParamsValues the condition names in braces, as for act.

PollOption

type

boolean | { readonly timeout?: number; readonly interval?: number }

How long to keep looking, and how often; true takes the session's assertion timeout.

Budget

interface

What may be spent; an absent limit is no limit.

MemberDescription
turns?: numberRounds of model call and actions in one step (only steps count turns).
modelCalls?: number
costUsd?: numberIn US dollars, as the gateway bills it; calls with no reported cost count as free.
ms?: numberWall time in milliseconds.

On this page

Run it on every pull request

A GitHub check and one comment per pull request, with the flight records attached.

Set up CI