Agentic Browser Testing
petrkindlmann/qa-skills
Goal-driven E2E testing where a browser agent (Playwright MCP / computer-use) reads a natural-language goal and explores the app via the accessibility tree to assert outcomes — no pre-written script.
Run QA testing on a page, feature, or full site at one of three depth tiers (smoke, standard, full).
$ npx skills add rampstackco/claude-skills --skill qa-testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install rampstackco/claude-skills qa-testing --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/rampstackco/claude-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/qa-testing .claude/skills/qa-testing && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "qa-testing" agent skill from https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testing into .claude/skills/qa-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "qa-testing", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add rampstackco/claude-skills --skill qa-testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install rampstackco/claude-skills qa-testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rampstackco/claude-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/qa-testing .agents/skills/qa-testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "qa-testing" agent skill from https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testing into .agents/skills/qa-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "qa-testing", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add rampstackco/claude-skills --skill qa-testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install rampstackco/claude-skills qa-testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rampstackco/claude-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/qa-testing .cursor/skills/qa-testing && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "qa-testing" agent skill from https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testing into .cursor/skills/qa-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "qa-testing", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/rampstackco/claude-skills.git --path skills/qa-testing--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add rampstackco/claude-skills --skill qa-testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install rampstackco/claude-skills qa-testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rampstackco/claude-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/qa-testing .gemini/skills/qa-testing && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "qa-testing" agent skill from https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testing into .gemini/skills/qa-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "qa-testing", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install rampstackco/claude-skills qa-testingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add rampstackco/claude-skills --skill qa-testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/rampstackco/claude-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/qa-testing .github/skills/qa-testing && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "qa-testing" agent skill from https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testing into .github/skills/qa-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "qa-testing", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add rampstackco/claude-skills --skill qa-testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install rampstackco/claude-skills qa-testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rampstackco/claude-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/qa-testing .opencode/skills/qa-testing && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "qa-testing" agent skill from https://github.com/rampstackco/claude-skills/tree/main/skills/qa-testing into .opencode/skills/qa-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "qa-testing", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
qa-testingRun QA testing on a page, feature, or full site at one of three depth tiers (smoke, standard, full).
QA Testing is an agent skill from rampstackco/claude-skills. Run QA testing on a page, feature, or full site at one of three depth tiers (smoke, standard, full). Use this skill whenever the user asks to QA a page or site, run a smoke test after a deploy, verify a page before launch, or run a regression sweep. Triggers on QA, QA sweep, smoke test, regression test, post-deploy check, pre-launch check, verify the deploy, test this page, does the page render, broken link, 404, image not loading. Also triggers proactively after a deploy or a new page launch where verification…
Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `README.md` and `references/qa-report-template.md`).
It sits in Testing & QA, covering QA and bug reports and Accessibility. The repository describes itself as: Stack-agnostic Claude Skills covering the full website lifecycle: brand, design, content, SEO, dev, ops, growth, and research. Build, ship, audit, optimize. The licence is MIT.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 482c9bf. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
QA Testing loads about 3.2k tokens when it runs, and up to ~4.3k if it reads all its reference files. Until then it costs about 189 tokens; SKILL.md has 890 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from rampstackco/claude-skills at commit 482c9bf, republished under its MIT licence (© rampstackco). 890 words, ~3,224 tokens.
.claude/skills/qa-testing/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.Verify that a page, feature, or site is working before declaring it shipped. Stack-agnostic. Console-snippet driven for speed.
This skill is faster than accessibility-audit (which goes deeper on WCAG) and performance-optimization (which goes deeper on Core Web Vitals). Use this skill for general QA. Use the specialists for deep audits.
accessibility-audit)performance-optimization)code-review-web)seo-technical)QA scales with the stakes. Pick the tier that matches the context.
| Tier | When to run | Time | Coverage |
|---|---|---|---|
| Smoke | After every deploy | 2 minutes | Critical signals only |
| Standard | New page or feature | 10 minutes | On-page basics, accessibility, structure |
| Full | Major release, pre-launch | 30+ minutes | Comprehensive across all dimensions |
The 2-minute "did the deploy break anything obvious?" check. Run after every deploy.
Console snippet (paste in browser dev tools):
const smoke = {
title: document.title,
titleLen: document.title.length,
canonical: document.querySelector('link[rel="canonical"]')?.href,
h1Count: document.querySelectorAll('h1').length,
missingAlts: [...document.querySelectorAll('img')].filter(i => !i.hasAttribute('alt')).length,
schema: [...document.querySelectorAll('script[type="application/ld+json"]')]
.map(s => { try { return JSON.parse(s.innerText)['@type'] } catch(e) { return 'invalid' } }),
brokenImages: [...document.querySelectorAll('img')].filter(i => !i.complete || i.naturalWidth === 0).length,
};
console.log(JSON.stringify(smoke, null, 2));Pass criteria:
alt attribute. An empty alt="" on a decorative image is correct markup and passes; only an absent attribute fails.invalid entries in the snippet output). Whether the types are the right ones for the page is a Full-tier check, against the Rich Results Test.If any of these fail, do not proceed with deeper testing until the smoke issue is fixed.
The 10-minute new-page-or-feature audit. Covers the on-page basics plus accessibility and structure.
Console snippet:
const audit = {
title: document.title,
titleLen: document.title.length,
canonical: document.querySelector('link[rel="canonical"]')?.href,
metaDesc: document.querySelector('meta[name="description"]')?.content,
metaDescLen: document.querySelector('meta[name="description"]')?.content?.length,
ogImage: document.querySelector('meta[property="og:image"]')?.content,
ogTitle: document.querySelector('meta[property="og:title"]')?.content,
twitterCard: document.querySelector('meta[name="twitter:card"]')?.content,
h1Count: document.querySelectorAll('h1').length,
h1Text: document.querySelector('h1')?.innerText,
h2Count: document.querySelectorAll('h2').length,
h2s: [...document.querySelectorAll('h2')].map(h => h.innerText.trim().slice(0, 60)),
totalImages: document.querySelectorAll('img').length,
missingAlts: [...document.querySelectorAll('img')].filter(i => !i.hasAttribute('alt')).length,
brokenImages: [...document.querySelectorAll('img')].filter(i => !i.complete || i.naturalWidth === 0).length,
externalLinksWithoutNoopener: [...document.querySelectorAll('a[target="_blank"]')]
.filter(a => !a.rel?.includes('noopener')).length,
schema: [...document.querySelectorAll('script[type="application/ld+json"]')]
.map(s => {
try {
const d = JSON.parse(s.innerText);
return d['@graph'] ? d['@graph'].map(x => x['@type']) : d['@type'];
} catch(e) { return 'invalid' }
}),
hasSkipLink: [...document.querySelectorAll('a[href^="#"]')].slice(0, 3)
.some(a => /skip/i.test(a.textContent) && !!document.getElementById(a.getAttribute('href').slice(1))),
pageLanguage: document.documentElement.lang || 'NOT SET',
hasFavicon: !!document.querySelector('link[rel*="icon"]'),
};
console.log(JSON.stringify(audit, null, 2));Pass criteria (in addition to smoke):
target="_blank" have rel="noopener"lang attribute on <html>)The 30-minute pre-launch check. Cover all dimensions.
| Dimension | Pass criteria |
|---|---|
| Smoke and standard | All pass |
| Accessibility (basic) | Run browser audit tool (e.g., Lighthouse), score above 90 |
| Performance (basic) | Every threshold in the report template's Performance checklist, INP included |
| Mobile responsiveness | Every viewport in the report template's responsiveness checklist |
| Cross-browser | Tested in Chrome, Safari, Firefox (and Edge if relevant audience) |
| Forms | All forms submit successfully and validate correctly |
| Internal links | No broken internal links (sample 20 random) |
| External links | All return 200 (sample 10) |
| Sitemap | Returns 200, lists canonical URLs only |
| robots.txt | Allows production crawlers, blocks staging if applicable |
| Security headers | HSTS, X-Frame-Options, X-Content-Type-Options present |
| HTTPS | All resources load over HTTPS, no mixed content |
| 404 handling | 404 pages return HTTP 404 (not soft 200) |
| Schema validation | All schema validates in Rich Results Test |
| Analytics | Events fire as expected on key user actions |
| Cache behavior | Cache headers appropriate for page type |
For headers, run:
fetch(window.location.origin, { method: 'HEAD' })
.then(r => {
const headers = {};
for (const [k, v] of r.headers.entries()) headers[k] = v;
console.log(JSON.stringify(headers, null, 2));
});Look for: strict-transport-security, x-frame-options, x-content-type-options.
const imgs = [...document.querySelectorAll('img')].map(i => ({
src: i.src.split('/').pop().split('?')[0].slice(0, 60),
alt: i.hasAttribute('alt') ? (i.alt === '' ? 'DECORATIVE (empty alt)' : i.alt) : 'MISSING',
width: i.naturalWidth,
height: i.naturalHeight,
loaded: i.complete && i.naturalWidth > 0,
}));
console.table(imgs);
console.log({
total: imgs.length,
broken: imgs.filter(i => !i.loaded).length,
noAlt: imgs.filter(i => i.alt === 'MISSING').length,
decorative: imgs.filter(i => i.alt.startsWith('DECORATIVE')).length,
});const headings = [...document.querySelectorAll('h1, h2, h3, h4, h5, h6')].map(h => ({
level: parseInt(h.tagName[1]),
text: h.innerText.trim().slice(0, 80),
}));
console.table(headings);
// Check for skipped levels
const levels = headings.map(h => h.level);
let skipped = false;
for (let i = 1; i < levels.length; i++) {
if (levels[i] > levels[i-1] + 1) {
console.warn(`Skipped from H${levels[i-1]} to H${levels[i]}: "${headings[i].text}"`);
skipped = true;
}
}
if (!skipped) console.log('No skipped heading levels');function contrast(bg, fg) {
function lum(hex) {
return [hex.slice(1,3), hex.slice(3,5), hex.slice(5,7)]
.map(h => parseInt(h, 16) / 255)
.map(v => v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4))
.reduce((a, v, i) => a + v * [0.2126, 0.7152, 0.0722][i], 0);
}
const [l1, l2] = [lum(bg), lum(fg)];
const r = ((Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05)).toFixed(2);
return r + ':1 ' + (parseFloat(r) >= 4.5 ? 'PASS body' : parseFloat(r) >= 3 ? 'PASS large only' : 'FAIL');
}
// Examples
contrast('#FFFFFF', '#4B5563'); // body color check
contrast('#FFFFFF', '#9CA3AF'); // verify gray choices[...document.querySelectorAll('form')].forEach((form, i) => {
const fields = [...form.querySelectorAll('input, select, textarea')].map(field => ({
type: field.type || field.tagName.toLowerCase(),
name: field.name,
hasLabel: !!form.querySelector(`label[for="${field.id}"]`) || !!field.closest('label'),
required: field.required,
}));
console.log(`Form ${i + 1}:`);
console.table(fields);
});const externalLinks = [...document.querySelectorAll('a[href^="http"]')]
.filter(a => !a.href.includes(window.location.host));
const issues = externalLinks.filter(a =>
a.target === '_blank' && (!a.rel?.includes('noopener') || !a.rel?.includes('noreferrer'))
);
if (issues.length) {
console.warn(`${issues.length} external links missing noopener/noreferrer:`);
issues.forEach(a => console.warn(a.href));
} else {
console.log(`All ${externalLinks.length} external links properly attributed`);
}references/qa-report-template.md for full audits.For smoke tests: console output is the report.
For standard and full audits: a markdown report at qa-report-[date].md. Use the template in references/qa-report-template.md.
This skill's output depends on data, measurements, or tool results it cannot generate on its own. When a required input, tool, or data source is unavailable or unverifiable, the sanctioned output is the deliverable with the gap stated: what was needed, what was actually obtained or verified, and which parts of the output are affected. Fabricating, estimating, or interpolating a required number to complete the deliverable is never sanctioned. A stated gap is a complete answer.
references/qa-report-template.md - Markdown report template for standard and full audits.© rampstackco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (references) in skills/qa-testing of rampstackco/claude-skills.
Open the folder on GitHubat commit 482c9bf
QA Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| QA Testing this skillrampstackco/claude-skills | 935 | — | ~3.2k | Automated safety check: Pass | MIT | |
| Agentic Browser Testingpetrkindlmann/qa-skills | 163 | — | ~4.5k | Automated safety check: Pass | MIT | |
| Scoutqa Testgithub/awesome-copilot | 40k | 1 repos | ~3.5k | Automated safety check: Pass | MIT | |
| QA Testingespennilsen/pi | 122 | — | ~2.9k | Automated safety check: Pass | MIT | |
| QA Engineerdralgorhythm/claude-agentic-framework | 124 | — | ~631 | Automated safety check: Pass | None | |
| Prowl UI Verificationonevcat/Prowl | 631 | — | ~3.3k | Automated safety check: Pass | Custom licence |
petrkindlmann/qa-skills
Goal-driven E2E testing where a browser agent (Playwright MCP / computer-use) reads a natural-language goal and explores the app via the accessibility tree to assert outcomes — no pre-written script.
github/awesome-copilot
This skill should be used when the user asks to "test this website", "run exploratory testing", "check for accessibility issues", "verify the login flow works", "find bugs on this page", or requests…
espennilsen/pi
Perform QA testing on running web applications using cmuxbrowser.
dralgorhythm/claude-agentic-framework
Define test strategy and verify quality against WCAG and testing-pyramid criteria — a user-invoked QA Engineer workflow.
onevcat/Prowl
Drives and verifies the native macOS Prowl Debug UI through accessibility automation, proving behavior with before-and-after evidence instead of reasoning from code.
Community-Access/accessibility-agents
Reference data, not a reviewer. An agent skill from Community-Access/accessibility-agents.
rampstackco/claude-skills
Run a structured after-action review (postmortem, retrospective) on a launch, incident, or completed project to capture timeline, root cause analysis, contributing factors, and actionable lessons.
rampstackco/claude-skills
Design measurement frameworks including event taxonomy, KPI hierarchy, dashboard architecture, attribution models, and analytics implementation strategy.
rampstackco/claude-skills
Build or audit a comprehensive brand style guide that documents the full brand system including story, logo system, color, typography, imagery, voice, applications, and dos/don'ts.
rampstackco/claude-skills
Develop or document a complete brand voice and tone system covering voice attributes, tone shifts by context, vocabulary preferences, grammar rules, and copy examples.
rampstackco/claude-skills
Write or edit website copy, blog content, and editorial pieces with attention to voice, structure, and goal.
rampstackco/claude-skills
Develop a content strategy covering editorial positioning, content pillars, formats, calendar, governance, and topical authority planning.
Categories
Run QA testing on a page, feature, or full site at one of three depth tiers (smoke, standard, full). QA Testing is an agent skill from rampstackco/claude-skills. Run QA testing on a page, feature, or full site at one of three depth tiers (smoke, standard, full).
QA Testing fits situations like: the user asks to QA a page; run a smoke test after a deploy; verify a page before launch; run a regression sweep.
Run `npx skills add rampstackco/claude-skills --skill qa-testing -a claude-code`. Or copy the skill folder (skills/qa-testing in rampstackco/claude-skills) into .claude/skills/qa-testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add rampstackco/claude-skills --skill qa-testing -a codex`. Or copy the skill folder (skills/qa-testing in rampstackco/claude-skills) into .agents/skills/qa-testing in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add rampstackco/claude-skills --skill qa-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/qa-testing, .gemini/skills/qa-testing, .github/skills/qa-testing and .opencode/skills/qa-testing in your project.
SKILL.md names no scripts, command-line tools or credentials: QA Testing is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
QA Testing is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.2k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.1k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with QA Testing: Agentic Browser Testing (petrkindlmann/qa-skills, 163 stars), Scoutqa Test (github/awesome-copilot, 40k stars), QA Testing (espennilsen/pi, 122 stars) and QA Engineer (dralgorhythm/claude-agentic-framework, 124 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
rampstackco (a GitHub organization) maintains it in rampstackco/claude-skills, which has 935 GitHub stars. The repository holds 103 skills in this directory. The repository was last updated on October 7, 2026.
Source: rampstackco/claude-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.