mcpField
W
webapp-testing

webapp-testing

github.com/pixel-process-ugTesting & quality382 installsUpdated 33w ago
Repository

About webapp-testing

webapp-testing is a skill for testing web applications with Playwright. It guides developers through end-to-end flows, visual checks, accessibility audits, network mocking, and mobile viewport tests.

Key features

  1. 01End-to-end tests with Playwright
  2. 02Screenshot and visual regression checks
  3. 03Browser console error analysis
  4. 04Accessibility audits with axe-core
  5. 05Network request mocking
  6. 06Mobile viewport testing

Use cases

  1. 01Verifying critical user flows
  2. 02Checking page layouts across changes
  3. 03Auditing page accessibility
  4. 04Testing responsive behavior on mobile

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/pixel-process-ug/superkit-agents --skill webapp-testing

After installing, type/webapp-testingin Claude Code to confirm it loaded.

Details

From the project README

Web App Testing

Overview

Comprehensive web application testing using Playwright as the primary tool. This skill covers end-to-end testing workflows including screenshot capture for visual verification, browser console log analysis, user interaction simulation, visual regression testing, accessibility auditing with axe-core, network request mocking, and mobile viewport testing.

Announce at start: "I'm using the webapp-testing skill for Playwright-based web application testing."


Phase 1: Test Planning

Goal: Identify what to test and set up the infrastructure.

Actions
  1. Identify critical user flows to test
  2. Define test environments and viewports
  3. Set up test fixtures and data
  4. Configure Playwright project settings
  5. Establish visual baseline screenshots
User Flow Priority Decision Table
Flow TypePriorityTest Depth
Authentication (login/logout/register)CriticalFull happy + error paths
Core business workflow (purchase, submit)CriticalFull happy + error + edge cases
Navigation and routingHighAll major routes
Search and filteringHighCommon queries + empty state
Settings and profileMediumHappy path
Admin/back-officeMediumKey operations only
STOP — Do NOT proceed to Phase 2 until:
  • Critical user flows are identified and prioritized
  • Test environments and viewports are defined
  • Playwright config is ready
  • Test data strategy is defined

Phase 2: Test Implementation

Goal: Write tests using page object models and accessible locators.

Actions
  1. Write page object models for key pages
  2. Implement end-to-end test scenarios
  3. Add visual regression snapshots
  4. Integrate accessibility checks
  5. Configure network mocking for isolated tests
Playwright Configuration
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests/e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ['html', { open: 'never' }],
    ['junit', { outputFile: 'test-results/junit.xml' }],
  ],
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit', use: { ...devices['Desktop Safari'] } },
    { name: 'mobile-chrome', use: { ...devices['Pixel 5'] } },
    { name: 'mobile-safari', use: { ...devices['iPhone 13'] } },
  ],
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});
Page Object Model
class LoginPage {
  constructor(private page: Page) {}

  readonly emailInput = this.page.getByLabel('Email');
  readonly passwordInput = this.page.getByLabel('Password');
  readonly submitButton = this.page.getByRole('button', { name: 'Sign in' });
  readonly errorMessage = this.page.getByRole('alert');

  async login(email: string, password: string) {
    await this.emailInput.fill(email);
    await this.passwordInput.fill(password);
    await this.submitButton.click();
  }

  async expectError(message: string) {
    await expect(this.errorMessage).toContainText(message);
  }
}
Locator Selection Decision Table
Locator TypePriorityWhen to Use
getByRole1st choiceAny element with ARIA role (button, link, heading)
getByLabel2nd choiceForm fields with labels
getByPlaceholder3rd choiceFields without visible labels
getByText4th choiceNon-interactive visible text
getByTestIdLast resortWhen no accessible locator works
CSS selector / XPathNeverBreaks with styling changes
STOP — Do NOT proceed to Phase 3 until:
  • Page object models exist for key pages
  • Tests use accessible locators exclusively
  • Visual baselines are established
  • Accessibility checks are integrated
  • Network mocking is configured for isolated tests

Phase 3: CI Integration

Goal: Configure reliable, fast test execution in CI.

Actions
  1. Configure headless browser execution
  2. Set up screenshot artifact collection
  3. Configure retry and flake detection
  4. Add reporting (HTML report, JUnit XML)
  5. Set up visual diff review process
CI Configuration Checklist
  • Tests run headless in CI
  • Retries enabled (2 retries for CI)
  • Screenshot and video artifacts collected on failure
  • JUnit XML output for CI integration
  • HTML report generated for manual review
  • Visual diff snapshots reviewed before merge
STOP — CI integration complete when:
  • Tests run reliably in CI pipeline
  • Artifacts are collected on failure
  • Flaky tests are identified and fixed (not skipped)

Screenshot Capture Patterns

Full Page
test('homepage renders correctly', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('homepage.png', {
    fullPage: true,
    maxDiffPixelRatio: 0.01,
  });
});
Element-Level
test('navigation bar matches design', async ({ page }) => {
  await page.goto('/');
  const nav = page.getByRole('navigation');
  await expect(nav).toHaveScreenshot('navbar.png');
});
Dynamic Content Masking
test('dashboard layout', async ({ page }) => {
  await page.goto('/dashboard');
  await expect(page).toHaveScreenshot('dashboard.png', {
    mask: [
      page.locator('[data-testid="timestamp"]'),
      page.locator('[data-testid="user-avatar"]'),
      page.locator('.chart-container'),
    ],
    animations: 'disabled',
  });
});

Browser Log Analysis

test('no console errors on page load', async ({ page }) => {
  const consoleErrors: string[] = [];

  page.on('console', msg => {
    if (msg.type() === 'error') consoleErrors.push(msg.text());
  });
  page.on('pageerror', error => {
    consoleErrors.push(error.message);
  });

  await page.goto('/');
  await page.waitForLoadState('networkidle');
  expect(consoleErrors).toEqual([]);
});

Accessibility Testing with axe-core

import AxeBuilder from '@axe-core/playwright';

test('page has no accessibility violations', async ({ page }) => {
  await page.goto('/');
  const results = await new AxeBuilder({ page })
    .withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
    .exclude('.third-party-widget')
    .analyze();
  expect(results.violations).toEqual([]);
});

Network Request Mocking

test('displays users from API', async ({ page }) => {
  await page.route('**/api/users', async route => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]),
    });
  });
  await page.goto('/users');
  await expect(page.getByText('Alice')).toBeVisible();
});

test('handles API errors gracefully', async ({ page }) => {
  await page.route('**/api/users', route =>
    route.fulfill({ status: 500, body: 'Internal Server Error' })
  );
  await page.goto('/users');
  await expect(page.getByText('Something went wrong')).toBeVisible();
});

Mobile Viewport Testing

test.describe('mobile responsive', () => {
  test.use({ viewport: { width: 375, height: 667 } });

  test('hamburger menu works', async ({ page }) => {
    await page.goto('/');
    await expect(page.getByRole('navigation')).not.toBeVisible();
    await page.getByRole('button', { name: 'Menu' }).click();
    await expect(page.getByRole('navigation')).toBeVisible();
  });
});

Test Organization

tests/
  e2e/
    auth/
      login.spec.ts
      register.spec.ts
    checkout/
      cart.spec.ts
      payment.spec.ts
    fixtures/
      test-data.ts
      auth.setup.ts
    pages/
      login.page.ts
      dashboard.page.ts
    utils/
      helpers.ts

Anti-Patterns / Common Mistakes

Anti-PatternWhy It Is WrongCorrect Approach
CSS selectors or XPathBreak with styling changesUse accessible locators (role, label, text)
page.waitForTimeout()Arbitrary delays, flakyUse expect().toBeVisible() or similar
Testing third-party components in detailNot your code to testTest your integration, not their internals
Hardcoded test dataBreaks across environmentsUse fixtures and factories
Tests depending on execution orderFragile, hard to debugEach test must be independent
Ignoring flaky testsErodes trust in test suiteFix root cause or quarantine
Screenshots without masking dynamic contentAlways different, always failingMask timestamps, avatars, charts
No accessibility checksMissing critical quality gateaxe-core on every page

Integration Points

SkillRelationship
senior-frontendFrontend components are tested by E2E tests
testing-strategyE2E tests are the top of the testing pyramid
acceptance-testingUser flow tests serve as acceptance tests
performance-optimizationPerformance budgets can be verified in E2E
code-reviewReview checks that tests use accessible locators
security-reviewSecurity headers and auth flows tested in E2E

Quality Checklist

  • All critical user flows covered
  • Tests use accessible locators (role, label, text)
  • Network mocking for isolated tests
  • Visual regression baselines reviewed and approved
  • Accessibility scans on all pages
  • Mobile viewport tests for responsive features
  • No waitForTimeout (use proper assertions)
  • CI pipeline configured with retries
  • Screenshot artifacts collected on failure
  • Flaky tests identified and fixed (not skipped)

Skill Type

FLEXIBLE — Adapt test depth to the project's critical paths. The page object model pattern and accessible locators are strongly recommended. Accessibility checks are mandatory on every page. Visual regression baselines must be reviewed before merge.

Comments

Markdown supported