Write and run browser tests from natural language specifications. Supports functional tests, visual regression, and self-healing selectors. Use when asked to test a website, verify UI behavior, check for regressions, create a test suite, run automated tests, or validate that a page works correctly.
Write, manage, and execute browser-based tests from natural language specifications. Tests use the browser tool for navigation, interaction, and assertions, with the kb tool for baseline storage and result tracking.
| Mode | What it does | When to use |
|---|---|---|
| Single Test | Translate a spec into browser actions, run, report | Ad-hoc verification of one behavior |
| Visual Regression | Screenshot baseline + comparison via vision | Detect layout/style drift |
| Suite Run | Execute all (or tagged) test files, produce summary | CI-style batch testing |
Translate a natural language spec into a three-phase browser test: setup, actions, assertions.
User says something like: "Verify the login form accepts valid credentials."
Break it down:
browser(action="navigate", url="<target-url>")
Wait for page load if needed:
browser(action="wait_for", selector="<ready-indicator>")
Use self-healing selectors (see references/selector-strategies.md for the full fallback chain).
Prefer semantic selectors over brittle CSS:
browser(action="type", selector="input[name='email']", text="[email protected]")
browser(action="type", selector="input[name='password']", text="secret")
browser(action="click", selector="button:has-text('Sign in')")
If a selector fails, try alternatives in this order:
[name] or [id] attribute[role] + accessible name: [role="button"][aria-label="Submit"]button:has-text("Submit")input[placeholder="Email address"]input linked by <label>Read page state and compare against expected values:
browser(action="get_text", selector="h1.welcome")
Expected: contains "Welcome back". If mismatch, the test fails.
For URL checks:
browser(action="evaluate", expression="window.location.pathname")
Expected: /dashboard.
For element existence:
browser(action="get_elements", selector=".success-banner")
Expected: at least one element returned.
On any assertion failure, capture evidence:
browser(action="screenshot")
Output a structured result per test:
## Test: <test name>
- **Status:** PASS | FAIL
- **URL:** <tested url>
- **Steps completed:** <n>/<total>
- **Failed step:** <description> (if FAIL)
- **Expected:** <expected value>
- **Actual:** <actual value>
- **Screenshot:** <attached if FAIL>
Detect layout and style drift by comparing screenshots across runs using vision.
Navigate to the target page and take a screenshot:
browser(action="navigate", url="<target-url>")
browser(action="wait_for", selector="<ready-indicator>")
browser(action="screenshot")
Store baseline metadata in KB:
kb(action="store", topic="projects", title="test baseline: <page-name>", content="URL: <url>\nCaptured: <date>\nViewport: <width>x<height>\nDescription: <what the page should look like>", tags=["test-baseline", "<project>"])
Navigate to the same page and screenshot again:
browser(action="navigate", url="<target-url>")
browser(action="screenshot")
Use the current screenshot and the baseline description to assess differences. Compare:
Report differences with specifics:
If changes are intentional, update the KB entry:
kb(action="search", query="test baseline: <page-name>", topic="projects")
kb(action="store", topic="projects", title="test baseline: <page-name>", content="<updated metadata>", tags=["test-baseline", "<project>"])
Tests are stored as markdown files in ~/.picobot/workspace/tests/. Each file defines one or more test cases.
---