When you record with the dashboard composer or the CLI, your prompt is the assertion screencli verifies — the agent reads it, drives your app in a real browser to exercise it, and returns a pass / fail / inconclusive verdict. A good prompt names a concrete, observable outcome; a vague one gives you a vague verdict. This page shows how the agent reads a prompt and how to write one that verifies exactly what you intend.
Where you write prompts
| Surface | You write | Notes |
|---|---|---|
| Dashboard composer | The what to record box (required) | One prompt per run, against the URL you enter. |
| CLI | The -p "<prompt>" flag |
npx screencli record <url> -p "<prompt>" for a recording, or npx screencli verify <url> -p "<prompt>" to check a change before opening a PR. |
| Baseline tests | The prompt on each entry |
Smoke checks that run on every PR for a connected repo, in addition to the PR-derived test. |
For a GitHub App pull-request run you don't write a prompt — the agent reads the PR diff and the source and decides which behaviors to verify on its own. Prompts are the lever for the composer, the CLI, and baseline tests, where you're pointing the agent at a URL rather than a diff.
How the agent reads your prompt
For a prompt-driven run the agent treats your text as the assertion to verify and does this:
- If the app's source is available (a connected repo), it reads the relevant files to understand routes and components — but it never decides the verdict from code alone.
- It writes a single Playwright test that navigates to your URL, performs the flow, and asserts on observed runtime behavior in a real browser.
- It runs the test, iterating only on harness issues (selectors, timing) — it never weakens your assertion to force a pass.
- It returns one verdict as the recording's result.
Two consequences shape how you should write:
- Describe things a person could see happen in the browser. The agent verifies by doing, so the assertion has to be exercisable in the running app. "The pricing page shows three plans" is checkable; "the migration ran" or "the cache header is set" is not something the browser flow observes, and phrasing an assertion the agent can't exercise tends to come back
inconclusive. - State the assertion, not just the tour. A prompt that only says "look around" produces a demo recording with no verdict. Add the thing that must be true and you get a
pass/fail.
Anatomy of a good prompt
Strong prompts name three things: where to start, what to do, and what must be true afterward.
Open the pricing page, click "Start free trial" on the Pro plan,
and confirm the signup form appears with an email field.
- Where — "the pricing page"
- What — "click Start free trial on the Pro plan"
- What must be true — "the signup form appears with an email field"
The composer's own placeholder is a good template — a start state, an action, and a checkable outcome:
Sign in with demo@example.com and confirm the dashboard loads with no console errors
Concrete vs. vague
| Vague (avoid) | Concrete (prefer) |
|---|---|
| "Test the app." | "From the home page, add the first product to the cart and confirm the cart count shows 1." |
| "Make sure login works." | "Sign in with the test account and confirm you land on /dashboard and see the account menu." |
| "Check the new button." | "Click Export on a recording and confirm an MP4 download starts." |
If you're pointing at a URL and aren't sure what to write, the composer's Try: suggestion chips pre-fill a real URL and prompt — for example, "Walk through the top three stories on the front page, briefly narrating what each is about." — that you can adapt.
Prompts that need a login
If verifying your assertion means signing in first, give the agent a way in — it can't guess credentials:
- CLI — add
--loginto sign in manually before the agent takes over, and--auth <name>to save and reuse that session. See Record an app that needs login. - GitHub App — fill in the repo's Authentication section (test email, password, and plain-language auth instructions). The agent performs those steps before your assertion. Use
{{email}}and{{password}}placeholders — they're substituted server-side just before the run, so the raw values never sit in the agent's context. See Authentication.
Write the assertion assuming you're already signed in; the login is a separate, prepended step.
How your wording maps to the verdict
Your phrasing decides which of the three verdicts you can get:
pass— every behavior your prompt named held in the running app.fail— a behavior you asserted is broken. You only get afailfor something you actually asked the agent to check, so name the specific outcome you care about.inconclusive— the agent couldn't reach a decision: the page was unreachable, a login blocked it, or the assertion wasn't something it could exercise in the browser. Tighten the prompt to a visible outcome (and supply auth if needed) to turn aninconclusiveinto a realpass/fail.
For a complex app the agent has to map first, turn on the composer's Recon toggle — it runs an unrecorded scouting pass so the recorded run heads straight for the outcome your prompt describes.
Baseline test prompts
Baseline tests are prompts that run on every PR for a connected repo, alongside the PR-derived test — use them for the always-true smoke checks the per-PR agent might not think to run. Each entry pairs a short name (shown in the verdict) with a prompt written exactly like a composer assertion:
{
"baseline": [
{ "name": "smoke-homepage", "prompt": "The homepage loads with no console errors and the primary CTA is visible." },
{ "name": "signup-reachable", "prompt": "Clicking Get Started opens the signup form with an email field." }
]
}
Any failing check — baseline or PR-derived — makes the PR's overall verdict fail; an inconclusive with no failures makes it inconclusive; all passing makes it pass. See Verdicts for the aggregation rules.
Notes & limits
- Prompts are for URL-pointed runs. The composer, the CLI, and baseline tests take a prompt; a per-PR GitHub App run derives its own checks from the diff.
- The agent won't lower the bar. It fixes flaky selectors and timing on its own but never softens the assertion you wrote to make a run pass — a
passmeans the behavior actually held. - One assertion, one run — but you can chain. A single prompt can walk through several steps in one session ("sign in, open settings, change the name, and confirm it saves"); the agent asserts each and reports one verdict covering them.
- Keep it observable. Phrase every check as something visible in the browser; assertions about back-end state the flow never surfaces will come back
inconclusive.