Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add tmj-90/gaffer --skill e2e-browser-testgit clone --depth 1 https://github.com/tmj-90/gafferWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/tmj-90/gaffer/e2e-browser-test)<a href="https://agentmods.dev/skills/tmj-90/gaffer/e2e-browser-test"><img src="https://agentmods.dev/badge/skills/tmj-90/gaffer/e2e-browser-test/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/tmj-90/gaffer/e2e-browser-test"><img src="https://agentmods.dev/badge/skills/tmj-90/gaffer/e2e-browser-test.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00087 | $0.01291 |
| Opus 5.5 | $0.00035 | $0.00516 |
| Sonnet 5.5 | $0.00017 | $0.00258 |
| Haiku 4.5 | $0.00009 | $0.00129 |
Grade A, and why
e2e-browser-test scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 16d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 82 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Write an end-to-end browser test
An end-to-end test proves a user journey works through the real UI against a real (or faithfully stubbed) backend. It is the slowest and most flake-prone test in the suite — Google's data shows flakiness grows with test size and with WebDriver-style tooling — so it earns its place by covering a journey no cheaper test can, and by being deterministic: no sleeps, no order dependence, no data another test created.
Procedure
- Find the harness. Locate the repo's browser setup (
playwright.config.*,cypress/, atest:e2escript). Use it exactly — its browsers, base URL,webServerblock and CI command. Do not add a second framework. If none exists and the ticket does not ask for one, raiserequest_decisionwith the smallest viable setup. (Independent tester: never raiserequest_decision; followblack-box-test— scaffold a disposable rig in a test directory only with what the repo already has installed, run the spec once, and recordmanual_noterows.) - Push coverage down first. For each acceptance criterion ask whether a component or
integration test proves it (the
frontend-testingandadd-integration-testskills). Only journeys that need the real browser, routing, cookies or the full stack belong here. - Write the journey in plain words: start state → user actions → what the user must observe. Map each AC to one observable outcome on screen or one persisted result. Name the test after the journey and cite the AC.
- Own your data. Create what the test needs through an API call, seed script or
factory inside the test (or a fixture), with unique values, and clean up. Never depend
on another test's leftovers or a shared account; each test gets a fresh browser context.
Save authenticated state once (
storageState) rather than logging in through the UI in every test. - Locate like a user.
getByRolewith the accessible name, thengetByLabel,getByText; chain andfilter({ hasText })to scope.getByTestIdonly when no accessible handle exists, with a comment why. No XPath or styling-class CSS selectors. - Use web-first assertions; never wait for time.
await expect(locator).toBeVisible(),toHaveText,toHaveURL,page.waitForResponse. NeverwaitForTimeout/cy.wait(ms), and neverexpect(await locator.isVisible()).toBe(true)— it does not retry. Every Playwright call is awaited (@typescript-eslint/no-floating-promisescatches misses). - Assert the outcome, not the DOM. What the user sees, and what the system persisted: reload the page or query the API to prove a save survived, check the stub outbox for the email. A toast saying "Saved" is not proof the data was saved.
- Stub only what you do not control. Third-party services go through
page.route(...)/cy.interceptwith recorded responses; your own backend stays real. - When an AC concerns concurrent users or failure, drive it for real: two browser
contexts editing the same record (assert the documented conflict behaviour, no silent
overwrite); the backend returning an error or going offline via
page.route→abort(); the user sees the documented error and can retry. - Keep failures diagnosable. Traces on first retry (
trace: 'on-first-retry'), screenshots on failure. Retries may be on in CI to collect traces, but a test that passes only on retry is flaky and not done. - Run it until stable: the spec three times in a row headless, e.g.
npx --no -- playwright test <spec> --repeat-each=3, then the repo's CI command. Record the command and result with therecord-evidenceskill (test_output) per AC.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 16d ago Changed · +21 lines 0012eb8f24a9
- 19d ago First seen · 61 lines · 87 tokens per session scan A b574fc6d8036
e2e-browser-test is a skill published in the GitHub repository tmj-90/gaffer (2 stars, last pushed 17d ago), licensed Apache-2.0. It adds 87 tokens to every session and 1,291 once invoked, about $0.0003 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-28.
Other skills, from other repositories
test-fixture-creation
Guidelines for creating unbiased test fixtures that integrate with project infrastructure. Use when creating fixtures for manual testing, setting up E2E test scenarios, or building code samples with deliberate issues for LLM review. Ensures fixtures work with hook automation and pass Phase 1 checks.
agent-browser
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
browser-testing-with-screenshots
Use when testing web applications with visual verification - automates Chrome browser interactions, element selection, and screenshot capture for confirming UI functionality.
e2e-testing
Playwright E2E testing patterns, Page Object Model, configuration, CI/CD integration, artifact management, and flaky test strategies. Use when writing Playwright tests, structuring page objects, or fixing flaky E2E runs in CI.
dogfood
Exploratory QA of web apps: find bugs, evidence, reports.
e2e-testing-patterns
Master end-to-end testing with Playwright and Cypress to build reliable test suites that catch bugs, improve confidence, and enable fast deployment. Use when implementing E2E tests, debugging flaky tests, or establishing testing standards.