Skill detail
webapp-uat
Web app UAT and browser QA, a complementary testing specialty.
Inspect before use
Automated review checks relevance, not safety or endorsement. Read the source instructions before using this skill.
SKILL.md
The saved excerpt is a snapshot from review. The external source remains the complete and most current version.
---
name: webapp-uat
description: Full browser UAT for web apps — Playwright testing with console/network error capture, accessibility checks, i18n validation, and bug triage. Use when running screen-by-screen UAT or testing specific features in any web or hybrid app (React, Vue, Angular, Ionic, Next.js, etc).
user-invocable: true
argument-hint: "[screen-name | url | 'full']"
allowed-tools:
- Bash
- Read
- Edit
- Write
- Glob
- Grep
- Agent
---
# Web App UAT Skill
Real browser testing for web applications using Playwright. This skill captures EVERYTHING — console errors, network failures, rendering bugs, broken i18n keys, missing data — and fixes bugs as they're found.
Works with any web stack: React, Vue, Angular, Svelte, Next.js, Nuxt, Ionic/Capacitor, and plain HTML.
## CRITICAL RULES
1. **Console errors are bugs.** Every `console.error`, unhandled rejection, and runtime exception MUST be captured and reported. If a console error blocks functionality, FIX IT before continuing.
2. **Network failures are bugs.** 401s, 500s, CORS errors, timeout responses — capture them ALL. Check if the backend is returning proper data or error payloads.
3. **Visual rendering = truth.** Screenshots show what the user actually sees. If a component renders "---", "undefined", "NaN", "[object Object]", or a raw i18n key, that's a bug.
4. **Backend logs matter.** Check server logs for errors that cause frontend skeleton loaders or empty states.
5. **Fix bugs inline.** Don't just report — fix the code, verify the fix compiles, then re-test.
## Prerequisites
- Playwright installed: `npx playwright --version` (v1.40+)
- Chromium browser: `npx playwright install chromium` if needed
- Frontend running (default `http://localhost:3000` — override with `BASE_URL`)
- Backend running (default `http://localhost:4000` — override with `BACKEND_URL`)
## Getting Started
Before running UAT, the skill needs to understand your app. It will:
1. **Auto-detect your stack** by reading `package.json`, framework configs, and route definitions
2. **Build a screen checklist** from your routes/pages
3. **Identify auth strategy** from your code (JWT, cookies, OAuth, etc.)
If your project has a `uat.config.js` in the root, the skill uses it directly. Otherwise, it auto-discovers screens and asks you to confirm.
## UAT Config (Optional)
Create `uat.config.js` in your project root for repeatable runs:
```javascript
module.exports = {
// Base URLs
baseUrl: process.env.BASE_URL || 'http://localhost:3000',
backendUrl: process.env.BACKEND_URL || 'http://localhost:4000',
// Browser settings
viewport: { width: 1440, height: 900 },
colorScheme: 'dark', // 'dark' | 'light' | 'no-preference'
headless: true,
// Authentication (pick one)
auth: {
// Option A: Reuse saved browser state (cookies, localStorage)
storageState: '/tmp/uat-auth-state.json',
// Option B: Login programmatically
// login: async (page) => {
// await page.goto('/login');
// await page.fill('input[type="email"]', process.env.TEST_EMAIL);
// await page.fill('input[type="password"]', process.env.TEST_PASSWORD);
// await page.click('button[type="submit"]');
// await page.waitForURL('**/dashboard', { timeout: 15000 });
// },
// Option C: Open headed browser for manual login
// interactive: true,
},
// Health check endpoints (verified before UAT starts)
healthChecks: [
'/health',
// '/api/ping',
],
// Screens to test — each screen gets a full pass
screens: [
{
name: 'Home',
path: '/',
checks: [
'page loads without console errors',
'page title is set',
'main content renders (not empty/skeleton)',
],
},
{
name: 'Dashboard',
path: '/dashboard',
checks: [
'data renders with real values (not placeholders)',
'charts/graphs render (canvas/svg has dimensions > 0)',
'no failed API calls',
],
},
Read the full source on GitHub (opens external page)