Loading...
Loading...
AI-agent-driven browser automation via a persistent Playwright daemon. Use for QA verification, visual checks, form interaction, auth testing, screenshots, and automated healthchecks against web applications.
npx skill4agent add forjd/browse bun-browserbrowsebrowse goto https://staging.example.com # navigate
browse snapshot # see page structure with refs
browse screenshot # capture the page
browse quit # shut down the daemonbrowse goto <url>browse snapshotbrowse screenshotbrowse goto <url> Navigate to URL, return page title
browse text Return visible text content of the page
browse quit Shut down the daemon
browse wipe Clear all session data (cookies, storage, buffers, refs)
browse benchmark [--iterations N] Measure command latency (p50/p95/p99)--timeout <ms>browse goto https://slow-page.example.com --timeout 60000--timeouttimeoutquitbenchmarkbrowse snapshot Interactive elements with refs (@e1, @e2, ...)
browse snapshot -i Include structural elements (headings, text)
browse snapshot -f Full accessibility tree dump
browse click @eN Click element by ref
browse fill @eN "value" Fill input by ref (clears first)
browse select @eN "option" Select dropdown option by visible textbrowse screenshot [path] Full-page screenshot (auto-generates path if omitted)
browse screenshot --viewport Viewport only (no scroll)
browse screenshot --selector ".css" Element-level screenshot
browse console Console messages since last call (drains buffer)
browse console --level error Filter to a specific level (error, warning, log, info, debug)
browse console --keep Return messages without clearing the buffer
browse network Failed requests (4xx/5xx) since last call (drains buffer)
browse network --all All requests including successful ones
browse network --keep Return requests without clearing the bufferbrowse auth-state save <path> Export cookies + localStorage to file
browse auth-state load <path> Restore session from file
browse login --env <name> Automated login using configured environment
browse tab list Show open tabs with indices
browse tab new [url] Open new tab (optionally navigating to URL)
browse tab switch <index> Switch to tab by 1-based index
browse tab close [index] Close tab by index (defaults to current)browse flow list List configured flows from browse.config.json
browse flow <name> --var key=value Execute a named flow with variable substitution
browse assert visible <selector> Assert element is visible on page
browse assert not-visible <selector> Assert element is not visible
browse assert text-contains <text> Assert page body contains text
browse assert text-not-contains <text> Assert page body does not contain text
browse assert url-contains <substring> Assert current URL contains substring
browse assert url-pattern <regex> Assert current URL matches regex
browse assert element-text <sel> <text> Assert element's text contains string
browse assert element-count <sel> <n> Assert element count equals n
browse assert permission <name> granted Check permission via config (navigates to page)
browse assert permission <name> denied Check permission denial via config
browse healthcheck --var base_url=<url> Run healthcheck across configured pages
browse wipe Clear cookies, storage, buffers, refs, close extra tabsbrowse snapshotsnapshotgotobrowse snapshot@e1@e2@e3browse snapshot # see what's on the page
browse fill @e3 "test" # fill the search field
browse click @e4 # click a button
browse snapshot # re-snapshot after the page changes"Refs are stale""Unknown ref"browse snapshotbrowse goto <url>browse snapshotbrowse screenshotbrowse console --level errorbrowse fillbrowse clickbrowse selectbrowse snapshotbrowse screenshotbrowse healthcheckbrowse login --env stagingbrowse.config.jsonbrowse goto https://app.example.com/login
browse snapshot
browse fill @e1 "user@example.com"
browse fill @e2 "password123"
browse click @e3
browse snapshot # verify redirect / dashboard loadedbrowse auth-state save /tmp/auth.json # after logging in
browse auth-state load /tmp/auth.json # in a future sessionbrowse wipe| Symptom | Cause | Fix |
|---|---|---|
| Page changed since last snapshot | Run |
| Ref doesn't exist in current snapshot | Run |
| Daemon crashed or was killed | Just run the command again — CLI auto-restarts the daemon and retries once |
| Page is slow or unresponsive | Use |
| Daemon restart also failed | Check system resources, try |
| CSS selector is wrong | Check the selector, use |
| Login fails | Credentials missing or wrong | Check env vars, verify login URL, use |
browse.config.jsonenvironments{
"environments": {
"staging": {
"loginUrl": "https://staging.example.com/login",
"userEnvVar": "BROWSE_STAGING_USER",
"passEnvVar": "BROWSE_STAGING_PASS",
"usernameField": "input[name=email]",
"passwordField": "input[name=password]",
"submitButton": "button[type=submit]",
"successCondition": { "urlContains": "/dashboard" }
}
},
"flows": {
"signup": {
"description": "Test the signup flow",
"variables": ["base_url", "test_email", "test_pass"],
"steps": [
{ "goto": "{{base_url}}/register" },
{ "fill": { "input[name=email]": "{{test_email}}" } },
{ "click": "button[type=submit]" },
{ "wait": { "urlContains": "/welcome" } },
{ "screenshot": true },
{ "assert": { "textContains": "Welcome" } }
]
}
},
"permissions": {
"create-user": {
"page": "{{base_url}}/admin/users",
"granted": { "visible": "button.create-user" },
"denied": { "textContains": "Access denied" }
}
},
"healthcheck": {
"pages": [
{ "url": "{{base_url}}/dashboard", "screenshot": true, "console": "error" },
{ "url": "{{base_url}}/settings", "assertions": [{ "visible": ".settings-form" }] }
]
},
"timeout": 45000
}