
qa-testing
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 matters. Covers accessibility, performance, and SEO at the surface-signal level only: deep audits belong to accessibility-audit, performance-optimization, and seo-technical, and code-level debugging to code-review-web.
- Installs
- 281
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/rampstackco/claude-skills --skill qa-testing- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads qa-testing automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
QA Testing
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.
When to use
- After every deploy (smoke test)
- After launching a new page or feature (standard audit)
- Before a major release (full release matrix)
- Investigating a "something looks off" report
- Pre-launch verification of a site or section
When NOT to use
- Deep accessibility compliance work (use
accessibility-audit) - Deep performance investigation (use
performance-optimization) - Code review or debugging (use
code-review-web) - Initial site setup or technical SEO baseline (use
seo-technical)
Required inputs
- The page URL or site under test
- The tier of QA needed (smoke, standard, or full)
- Browser dev tools access
- Any specific concerns to check beyond the standard tier
The framework: 3 tiers
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 |
Tier 1: Smoke test
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:
- Title exists and is 30 to 60 characters
- Canonical points at the production domain (never staging or preview URLs)
- Exactly one H1
- Zero images missing the
altattribute. An emptyalt=""on a decorative image is correct markup and passes; only an absent attribute fails. - Zero broken images
- Every schema block parses (no
invalidentries 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.
Tier 2: Standard page audit
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):
- Meta description: 120 to 160 characters
- og:image, og:title, twitter:card present
- H2s present and descriptive
- All external links with
target="_blank"haverel="noopener" - Page language declared (
langattribute on<html>) - Favicon present
Tier 3: Full release matrix
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.
Specific QA snippets
Image audit
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,
});
Heading hierarchy check
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');
Contrast spot-check
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
Form audit (per form)
[...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);
});
External link audit
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`);
}
Workflow
- Pick the tier. Smoke for routine deploys. Standard for new work. Full for releases.
- Run the snippet. Paste the appropriate console snippet, review output.
- Note failures. Each failure either gets fixed before ship or filed as a known issue.
- For Standard tier, add: visual review at 375px, 768px, and 1440px. Standard deliberately skips 1024px; the Full tier picks it up with the rest of the template's responsiveness checklist. Test the primary user flow.
- For Full tier, add: cross-browser testing, Lighthouse audit, schema validation, security headers, 404 handling.
- Document. Use the template in
references/qa-report-template.mdfor full audits.
Failure patterns
- Skipping smoke tests on "small" deploys. Half of broken-production incidents start with a deploy that "looked safe."
- Running snippets but not reading the output. The console snippet is a tool. The judgment is reading what it returns.
- Visual-only QA. Eyeballing a page misses missing alt text, broken schema, missing canonical. Always run the snippet.
- Single-browser testing. Mobile Safari and Chrome differ enough to surprise you. Test at least Chrome and Safari.
- No mobile QA. The 375px viewport is where most users live. Test there or get burned later.
- Pass-fail with no remediation. A failed QA must produce a fix or a known-issue ticket. Failed QA that ships unfixed is process theater.
Output format
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.
If required data is unavailable
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.
Reference files
references/qa-report-template.md- Markdown report template for standard and full audits.
FAQ
What does the qa-testing skill do?
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 matters. Covers accessibility, performance, and SEO at the surface-signal level only: deep audits belong to accessibility-audit, performance-optimization, and seo-technical, and code-level debugging to code-review-web.
How do I install qa-testing?
Run npx skills add https://github.com/rampstackco/claude-skills --skill qa-testing in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/qa-testing/ (personal) or .claude/skills/qa-testing/ (project).
Which AI agents can use qa-testing?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is qa-testing safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains qa-testing?
It is published by rampstackco in rampstackco/claude-skills. It has 281 recorded installs.
More from rampstackco/claude-skills
art-direction
rampstackco/claude-skills
Direct visual and creative work for campaigns, photography, illustration, video, and branded experiences. Use this skill whenever the user wants to brief a photographer, direct illustrators, plan a creative campaign, develop visual concepts, or evaluate creative work for fit. Triggers on art direction, photo brief, photography brief, illustration brief, campaign concept, creative concept, visual direction, mood board, look and feel, visual treatment, video direction. Also triggers when the user has approved brand identity but needs to extend it into specific creative deliverables. Use creative-direction instead when the ask is the project-wide aesthetic brief that this skill consumes as input.
brand-identity
rampstackco/claude-skills
Design or evaluate a brand visual identity system covering logo, color, typography, imagery direction, iconography, and motion principles. Use this skill whenever the user wants to design a logo, build a visual identity, define brand colors, choose brand typography, develop iconography, plan brand imagery, or evaluate an existing identity for cohesion. Triggers on logo design, brand identity, visual identity, brand mark, wordmark, monogram, color palette, brand colors, brand typography, type system, iconography, brand imagery, motion design, brand system, identity system. Also triggers when the user has a brand direction approved and now needs the visual artifacts that express it.
creative-direction
rampstackco/claude-skills
Walk the user through four directional axes (tone register, aesthetic philosophy, audience relationship, sensory ambition) and produce a structured aesthetic brief that downstream content, copy, design, and art-direction skills consume as required input. The aesthetic depth layer, distinct from creative-brief (operational kickoff: scope, audience, deliverables, constraints). Use when a project needs aesthetic coherence across many small decisions and the user has only a vague feeling, or when multiple downstream aesthetic-producing skills need a shared brief. Triggers on creative direction, aesthetic direction, set the aesthetic, define the visual direction, what's the vibe, what's the tone, the four axes. Does NOT fire for a general kickoff brief (use creative-brief), tactical single-piece work, already-documented direction, purely functional output, or locked production-stage work.
brand-style-guide
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. Use this skill whenever the user wants to create brand guidelines, document an existing brand, build a brand book, audit an existing style guide for completeness, or produce the artifact that other teams will reference for years. Triggers on style guide, brand guidelines, brand book, brand standards, brand manual, style sheet, brand documentation, brand reference. Also triggers when the brand identity is finished and needs to be documented for handoff to designers, developers, vendors, or future team members.
landing-page-copy
rampstackco/claude-skills
Write landing page copy with attention to the hero, value proposition, social proof, objection handling, and conversion-focused CTAs. Use this skill whenever the user wants to write a landing page, sales page, hero section, or any conversion-focused web copy. Triggers on landing page, sales page, hero copy, value proposition, headline, subheadline, hero section, CTA copy, conversion copy, opt-in page, squeeze page. Also triggers when the user has a marketing campaign or product launch needing dedicated conversion copy. Use cro-optimization instead when the page already exists and the ask is to lift its conversion rate through testing rather than to write the copy.
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work