From unwind
Analyzes end-to-end tests including Playwright/Cypress config, page objects, fixtures, and user flows. Writes structured documentation to docs/unwind/layers/e2e-tests/.
How this skill is triggered — by the user, by Claude, or both
Slash command
/unwind:uw-analyze-e2e-testsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Output:** `docs/unwind/layers/e2e-tests/` (folder with index.md + section files)
Output: docs/unwind/layers/e2e-tests/ (folder with index.md + section files)
Principles: See analysis-principles.md - completeness, machine-readable, link to source, no commentary, incremental writes.
docs/unwind/layers/e2e-tests/
├── index.md # Test summary, browser matrix
├── config.md # Playwright/Cypress config, CI setup
├── page-objects.md # Page object definitions
├── fixtures.md # Test data and fixtures
└── flows.md # User flow tests
For large codebases, split by feature:
docs/unwind/layers/e2e-tests/
├── index.md
├── config.md
├── auth-tests.md
├── checkout-tests.md
└── ...
Step 1: Setup
mkdir -p docs/unwind/layers/e2e-tests/
Write initial index.md:
# E2E Tests
## Sections
- [Configuration](config.md) - _pending_
- [Page Objects](page-objects.md) - _pending_
- [Test Fixtures](fixtures.md) - _pending_
- [User Flows](flows.md) - _pending_
## Summary
_Analysis in progress..._
Step 2: Analyze and write config.md
config.md immediatelyindex.mdStep 3: Analyze and write page-objects.md
page-objects.md immediatelyindex.mdStep 4: Analyze and write fixtures.md
fixtures.md immediatelyindex.mdStep 5: Analyze and write flows.md
flows.md immediatelyindex.mdStep 6: Finalize index.md Add test summary and browser matrix
# E2E Tests
## Configuration
### Playwright Config
[playwright.config.ts](https://github.com/owner/repo/blob/main/playwright.config.ts)
```typescript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './e2e',
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});
| Feature | Tests | Browsers |
|---|---|---|
| Authentication | 5 | Chrome, Firefox, Safari |
| Order Flow | 8 | Chrome, Firefox, Safari |
| Admin Panel | 4 | Chrome |
export class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.page.fill('[data-testid="email"]', email);
await this.page.fill('[data-testid="password"]', password);
await this.page.click('[data-testid="submit"]');
}
async getErrorMessage() {
return this.page.textContent('[data-testid="error"]');
}
}
[Continue for ALL page objects...]
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
test.describe('Authentication', () => {
test('successful login redirects to dashboard', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('[email protected]', 'password123');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('[data-testid="welcome"]')).toBeVisible();
});
test('invalid credentials shows error', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('[email protected]', 'wrongpassword');
await expect(page.locator('[data-testid="error"]')).toHaveText('Invalid credentials');
});
test('logout clears session', async ({ page }) => {
// Login first
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('[email protected]', 'password123');
// Logout
await page.click('[data-testid="logout"]');
await expect(page).toHaveURL('/login');
});
});
test.describe('Order Flow', () => {
test.beforeEach(async ({ page }) => {
// Login before each test
await page.goto('/login');
await page.fill('[data-testid="email"]', '[email protected]');
await page.fill('[data-testid="password"]', 'password123');
await page.click('[data-testid="submit"]');
});
test('complete order flow', async ({ page }) => {
// Add product to cart
await page.goto('/products');
await page.click('[data-testid="product-1"] [data-testid="add-to-cart"]');
// Go to cart
await page.click('[data-testid="cart-icon"]');
await expect(page.locator('[data-testid="cart-item"]')).toHaveCount(1);
// Checkout
await page.click('[data-testid="checkout"]');
await page.fill('[data-testid="card-number"]', '4242424242424242');
await page.fill('[data-testid="expiry"]', '12/25');
await page.fill('[data-testid="cvc"]', '123');
await page.click('[data-testid="place-order"]');
// Confirm
await expect(page).toHaveURL(/\/orders\/\d+/);
await expect(page.locator('[data-testid="order-status"]')).toHaveText('Confirmed');
});
});
[Continue for ALL test files...]
export const testUsers = {
standard: {
email: '[email protected]',
password: 'password123',
},
admin: {
email: '[email protected]',
password: 'admin123',
},
};
export const testProducts = [
{ id: 1, name: 'Test Product', price: 29.99 },
];
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npx playwright install --with-deps
- run: npm run test:e2e
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
## Refresh Mode
If `docs/unwind/layers/e2e-tests/` exists, compare current state and add `## Changes Since Last Review` section to `index.md`.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Applies a firm's KYC/AML rules grid to parsed onboarding records: assigns risk rating, checks required documents, outputs rule outcomes with citations, and routes for escalation.
Generates daily or weekly digests of activity from connected sources (chat, email, docs, tasks, CRM), highlighting action items, decisions, mentions, and project updates.
npx claudepluginhub cliftonc/unwind --plugin unwind