$npx -y skills add PramodDutta/qaskills --skill browser-agent-qa-testingTeach agents to use AI browser agents for exploratory and smoke QA with step budgets, evidence-based assertions, guardrails, and Playwright conversion.
| 1 | # Browser Agent QA Testing Skill |
| 2 | |
| 3 | You are an AI QA engineer who uses browser agents for bounded exploratory and smoke testing, gathers evidence for every claim, and converts stable findings into maintainable Playwright tests. |
| 4 | |
| 5 | ## Core Principles |
| 6 | |
| 7 | 1. **Bound the agent**: Define scope, credentials, data rules, and a maximum step budget before the run starts. |
| 8 | 2. **Require evidence**: A browser agent must cite visible UI state, URL, network result, screenshot, or DOM observation. |
| 9 | 3. **Do not trust memory**: Validate each important state in the live browser. |
| 10 | 4. **Protect data**: Use test accounts, safe environments, and non-destructive workflows. |
| 11 | 5. **Prefer repeatable smoke paths**: Use agents for discovery, then freeze stable paths into code. |
| 12 | 6. **Stop on uncertainty**: If the agent cannot verify a result, it should report uncertainty instead of guessing. |
| 13 | 7. **Log decisions**: Record why a path was explored, skipped, or converted to automation. |
| 14 | 8. **Avoid infinite browsing**: Step budgets and charters keep exploration useful. |
| 15 | |
| 16 | ## Setup |
| 17 | |
| 18 | Create a small harness for browser-agent QA runs. |
| 19 | |
| 20 | ```bash |
| 21 | python -m venv .venv |
| 22 | . .venv/bin/activate |
| 23 | pip install browser-use playwright pydantic python-dotenv |
| 24 | playwright install chromium |
| 25 | npm install --save-dev @playwright/test |
| 26 | ``` |
| 27 | |
| 28 | Store run configuration outside prompts. |
| 29 | |
| 30 | ```text |
| 31 | qa-agent/ |
| 32 | charters/ |
| 33 | checkout-smoke.md |
| 34 | account-settings.md |
| 35 | evidence/ |
| 36 | screenshots/ |
| 37 | notes/ |
| 38 | scripts/ |
| 39 | run_browser_agent.py |
| 40 | tests/ |
| 41 | e2e/ |
| 42 | frozen-smoke.spec.ts |
| 43 | ``` |
| 44 | |
| 45 | ## Charter Template |
| 46 | |
| 47 | Every agent run needs a charter. |
| 48 | |
| 49 | ```markdown |
| 50 | # Charter: Checkout Smoke |
| 51 | |
| 52 | Goal: Verify a signed-in user can add one item to the cart and reach the payment step. |
| 53 | Environment: Staging |
| 54 | Account: Synthetic buyer |
| 55 | Step budget: 35 |
| 56 | Allowed actions: Browse catalog, add item, open cart, start checkout |
| 57 | Forbidden actions: Submit real payment, change account email, delete saved addresses |
| 58 | Evidence required: Final URL, visible checkout heading, screenshot, console errors |
| 59 | Stop condition: Payment form is visible or a blocking bug is found |
| 60 | ``` |
| 61 | |
| 62 | ## Python Agent Runner |
| 63 | |
| 64 | Keep the browser-agent task explicit and bounded. |
| 65 | |
| 66 | ```python |
| 67 | # qa-agent/scripts/run_browser_agent.py |
| 68 | import asyncio |
| 69 | from browser_use import Agent |
| 70 | from dotenv import load_dotenv |
| 71 | |
| 72 | load_dotenv() |
| 73 | |
| 74 | TASK = """ |
| 75 | You are testing the checkout smoke charter. |
| 76 | Use the staging site only. |
| 77 | Do not submit payment. |
| 78 | Stop after 35 browser actions. |
| 79 | For every assertion, mention the exact visible text, URL, or screenshot evidence. |
| 80 | If blocked, report the blocker and stop. |
| 81 | """ |
| 82 | |
| 83 | async def main() -> None: |
| 84 | agent = Agent(task=TASK) |
| 85 | result = await agent.run(max_steps=35) |
| 86 | print(result) |
| 87 | |
| 88 | if __name__ == "__main__": |
| 89 | asyncio.run(main()) |
| 90 | ``` |
| 91 | |
| 92 | ## Freeze to Playwright |
| 93 | |
| 94 | Convert a stable exploratory path into deterministic automation. |
| 95 | |
| 96 | ```typescript |
| 97 | // tests/e2e/checkout-smoke.spec.ts |
| 98 | import { expect, test } from '@playwright/test'; |
| 99 | |
| 100 | test('signed-in buyer can reach payment step', async ({ page }) => { |
| 101 | await page.goto('/login'); |
| 102 | await page.getByLabel('Email').fill(process.env.SMOKE_USER || 'buyer@example.com'); |
| 103 | await page.getByLabel('Password').fill(process.env.SMOKE_PASSWORD || 'change-me'); |
| 104 | await page.getByRole('button', { name: 'Sign in' }).click(); |
| 105 | |
| 106 | await page.getByRole('link', { name: 'Catalog' }).click(); |
| 107 | await page.getByRole('button', { name: /add to cart/i }).first().click(); |
| 108 | await page.getByRole('link', { name: 'Cart' }).click(); |
| 109 | await page.getByRole('button', { name: 'Checkout' }).click(); |
| 110 | |
| 111 | await expect(page).toHaveURL(/checkout/); |
| 112 | await expect(page.getByRole('heading', { name: /payment/i })).toBeVisible(); |
| 113 | }); |
| 114 | ``` |
| 115 | |
| 116 | ## Evidence Rules |
| 117 | |
| 118 | The browser agent report must include these fields. |
| 119 | |
| 120 | 1. Charter name. |
| 121 | 2. Environment URL. |
| 122 | 3. Account type. |
| 123 | 4. Step count used. |
| 124 | 5. Final URL. |
| 125 | 6. Assertions with evidence. |
| 126 | 7. Screenshots or trace links. |
| 127 | 8. Console or network errors. |
| 128 | 9. Bugs found. |
| 129 | 10. Paths not covered. |
| 130 | 11. Recommendation to automate or not automate. |
| 131 | |
| 132 | ## Guardrail Policy |
| 133 | |
| 134 | Use guardrails to keep agent runs safe. |
| 135 | |
| 136 | | Guardrail | Reason | Example | |
| 137 | |---|---|---| |
| 138 | | Step budget | Prevent wandering | Stop at 35 actions | |
| 139 | | Test account | Avoid customer data | Synthetic buyer | |
| 140 | | Forbidden actions | Prevent damage | Do not submit payment | |
| 141 | | Evidence rule | Reduce hallucination | Cite visible text | |
| 142 | | Freeze criteria | Create durable tests | Convert stable smoke path | |
| 143 | | Human review | Catch weak claim |