# Tsh E2e Testing

> E2E testing patterns, verification procedures, and CI readiness checklists using Playwright. Use for writing, debugging, or reviewing end-to-end tests, fixing flaky tests, creating Page Objects, mocking external APIs.

- Skill: `thesoftwarehouse/tsh-e2e-testing` (Agent Skill)
- Install (CLI): `npx skillmds@latest add thesoftwarehouse/tsh-e2e-testing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/thesoftwarehouse/tsh-e2e-testing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: TheSoftwareHouse (https://skillmd.com/u/thesoftwarehouse)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/thesoftwarehouse/tsh-e2e-testing

---


# E2E Testing Patterns & Practices

## Page Object Pattern

```typescript
export class FeaturePage {
  constructor(readonly page: Page) {}
  get submitBtn() {
    return this.page.getByRole('button', { name: 'Submit' });
  }
  async navigate() { await this.page.goto('/feature'); }
}
```

## Test Structure

```typescript
test('should [behavior] when [condition]', async ({ page }) => {
  const id = `test-${Date.now()}-${test.info().parallelIndex}`;
  // Arrange → Act → Assert
});
```

## Mocking (external APIs only)

```typescript
await page.route('**/api/external/**', route => route.fulfill({ status: 200, body: '{}' }));
```

## Verification Loop

```
RUN → FAIL? → DEBUG (browser_snapshot) → FIX → REPEAT
```

| Rule | Limit |
|------|-------|
| Max per test | 5 iterations → `test.fixme()` |
| Max per suite | 15 iterations → stop |
| Flaky detection | 3 pass/fail mix → investigate |
| Stability | 3+ consecutive passes required |
| App bug | Mark `test.fixme('BUG: desc')` |

### Error Recovery

| Error | Action |
|-------|--------|
| Timeout | Increase once → check selector → check if element renders |
| Element not found | Alternative locator → check DOM → verify page loaded |
| Network | Retry → consider mock → verify backend |
| Flaky | Explicit waits → check race conditions → run 5x |
| App bug | Mark `test.fixme('BUG: desc')` - test is skipped; CI usually still passes unless skipped tests fail the build |

## CI Readiness Checklist

- [ ] Passes headless: `npx playwright test --headed=false`
- [ ] Uses `process.env.BASE_URL`
- [ ] No hardcoded credentials
- [ ] Explicit viewport

## Quick Reference

**Always**: accessible locators, unique test data, 3+ passes, mock external APIs
**Never**: `waitForTimeout()`, CSS selectors, test interdependencies, hardcoded creds

