> qa-regression
Automate QA regression testing with reusable test skills. Create login flows, dashboard checks, user creation, and other common test scenarios that run consistently.
curl "https://skillshub.wtf/MoizIbnYousaf/Ai-Agent-Skills/qa-regression?format=md"QA Regression Testing
Build and run automated regression tests using Playwright. Each test is a reusable skill that can be composed into full test suites.
Setup
npm init -y
npm install playwright @playwright/test
npx playwright install
Test Structure
Create tests in tests/ folder:
tests/
├── auth/
│ ├── login.spec.ts
│ └── logout.spec.ts
├── dashboard/
│ └── load.spec.ts
├── users/
│ ├── create.spec.ts
│ └── delete.spec.ts
└── regression.spec.ts # Full suite
Common Test Skills
Login Test
// tests/auth/login.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Login Flow', () => {
test('should login with valid credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email"]', process.env.TEST_EMAIL!);
await page.fill('[data-testid="password"]', process.env.TEST_PASSWORD!);
await page.click('[data-testid="submit"]');
// Verify redirect to dashboard
await expect(page).toHaveURL(/dashboard/);
await expect(page.locator('[data-testid="user-menu"]')).toBeVisible();
});
test('should show error for invalid credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email"]', 'wrong@example.com');
await page.fill('[data-testid="password"]', 'wrongpassword');
await page.click('[data-testid="submit"]');
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
});
});
Dashboard Load Test
// tests/dashboard/load.spec.ts
import { test, expect } from '@playwright/test';
import { login } from '../helpers/auth';
test.describe('Dashboard', () => {
test.beforeEach(async ({ page }) => {
await login(page);
});
test('should load dashboard within 3 seconds', async ({ page }) => {
const start = Date.now();
await page.goto('/dashboard');
await page.waitForSelector('[data-testid="dashboard-content"]');
const loadTime = Date.now() - start;
expect(loadTime).toBeLessThan(3000);
});
test('should display all widgets', async ({ page }) => {
await page.goto('/dashboard');
await expect(page.locator('[data-testid="stats-widget"]')).toBeVisible();
await expect(page.locator('[data-testid="chart-widget"]')).toBeVisible();
await expect(page.locator('[data-testid="activity-widget"]')).toBeVisible();
});
test('should refresh data on button click', async ({ page }) => {
await page.goto('/dashboard');
const initialValue = await page.locator('[data-testid="last-updated"]').textContent();
await page.click('[data-testid="refresh-button"]');
await page.waitForTimeout(1000);
const newValue = await page.locator('[data-testid="last-updated"]').textContent();
expect(newValue).not.toBe(initialValue);
});
});
Create User Test
// tests/users/create.spec.ts
import { test, expect } from '@playwright/test';
import { login } from '../helpers/auth';
import { generateTestUser, deleteTestUser } from '../helpers/users';
test.describe('User Creation', () => {
let testUser: { email: string; name: string };
test.beforeEach(async ({ page }) => {
await login(page);
testUser = generateTestUser();
});
test.afterEach(async () => {
// Cleanup
await deleteTestUser(testUser.email);
});
test('should create new user successfully', async ({ page }) => {
await page.goto('/users/new');
await page.fill('[data-testid="user-name"]', testUser.name);
await page.fill('[data-testid="user-email"]', testUser.email);
await page.selectOption('[data-testid="user-role"]', 'member');
await page.click('[data-testid="create-user-btn"]');
// Verify success
await expect(page.locator('[data-testid="success-toast"]')).toBeVisible();
await expect(page).toHaveURL(/users/);
// Verify user appears in list
await expect(page.locator(`text=${testUser.email}`)).toBeVisible();
});
test('should validate required fields', async ({ page }) => {
await page.goto('/users/new');
await page.click('[data-testid="create-user-btn"]');
await expect(page.locator('[data-testid="name-error"]')).toBeVisible();
await expect(page.locator('[data-testid="email-error"]')).toBeVisible();
});
});
Shared Helpers
// tests/helpers/auth.ts
import { Page } from '@playwright/test';
export async function login(page: Page) {
await page.goto('/login');
await page.fill('[data-testid="email"]', process.env.TEST_EMAIL!);
await page.fill('[data-testid="password"]', process.env.TEST_PASSWORD!);
await page.click('[data-testid="submit"]');
await page.waitForURL(/dashboard/);
}
export async function logout(page: Page) {
await page.click('[data-testid="user-menu"]');
await page.click('[data-testid="logout"]');
await page.waitForURL(/login/);
}
// tests/helpers/users.ts
export function generateTestUser() {
const id = Date.now();
return {
name: `Test User ${id}`,
email: `test-${id}@example.com`,
};
}
export async function deleteTestUser(email: string) {
// API call to cleanup test user
await fetch(`${process.env.API_URL}/admin/users`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ADMIN_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});
}
Full Regression Suite
// tests/regression.spec.ts
import { test } from '@playwright/test';
// Import all test suites
import './auth/login.spec';
import './auth/logout.spec';
import './dashboard/load.spec';
import './users/create.spec';
import './users/delete.spec';
test.describe('Full Regression Suite', () => {
// Tests run in order defined above
});
Playwright Config
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
['html'],
['json', { outputFile: 'test-results.json' }],
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
Running Tests
# Run all tests
npx playwright test
# Run specific test file
npx playwright test tests/auth/login.spec.ts
# Run tests with UI
npx playwright test --ui
# Run in headed mode (see browser)
npx playwright test --headed
# Generate report
npx playwright show-report
CI Integration
# .github/workflows/regression.yml
name: Regression Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * *' # Daily at 6 AM
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run tests
run: npx playwright test
env:
BASE_URL: ${{ secrets.STAGING_URL }}
TEST_EMAIL: ${{ secrets.TEST_EMAIL }}
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
Best Practices
- Use data-testid attributes - More stable than CSS selectors
- Clean up test data - Always delete what you create
- Avoid hardcoded waits - Use
waitForSelectorinstead ofwaitForTimeout - Run in parallel - Faster feedback on CI
- Screenshot on failure - Easier debugging
- Environment variables - Never commit credentials
Quick Commands
| Task | Command |
|---|---|
| Run all | npx playwright test |
| Run one file | npx playwright test login.spec.ts |
| Debug mode | npx playwright test --debug |
| UI mode | npx playwright test --ui |
| Update snapshots | npx playwright test --update-snapshots |
> related_skills --same-repo
> xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for creating new spreadsheets, reading/analyzing data, modifying existing spreadsheets, or recalculating formulas.
> webapp-testing
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
> video-downloader
Downloads videos from YouTube and other platforms for offline viewing, editing, or archival. Handles various formats and quality options.
> theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.