- Complete execution patterns for remaining 20 tasks - 6-section prompt templates for each task type - Troubleshooting guide for common issues - Verification checklists and best practices - Session learnings from Wave 2-3 completion
4.7 KiB
Learnings — cts-herd-playwright
Inherited from Phase 1 (cts-presenter-app)
Vue Key Pattern
For repeating groups in arrangements, MUST use ${group.id}-${index} NOT just group.id
PDF Generation
Old-school CSS only (NO Tailwind) with DejaVu Sans font for German umlauts
Auto-Save
500ms debounce for text, immediate for selects/checkboxes via useDebounceFn
Line-Count Translation
Distribute translated text by matching original slide line counts
SQLite date gotcha
Returns YYYY-MM-DD 00:00:00 instead of YYYY-MM-DD — needs substr($date, 0, 10)
Phase 2 Specific
[2026-03-01 23:10] Wave 2-3 Completion Session
Playwright Test Patterns Established
Auth Setup Pattern (auth.setup.ts):
- Navigate to /login to establish session cookies (XSRF-TOKEN)
- Extract XSRF token from cookies:
decodeURIComponent(xsrfCookie.value) - POST to /dev-login with XSRF token in headers
- Navigate to /dashboard to confirm login
- Save storageState to tests/e2e/.auth/user.json
- Pattern works reliably for all authenticated tests
Test Structure Pattern:
test('description', async ({ page }) => {
await page.goto('/url');
await page.waitForLoadState('networkidle'); // CRITICAL for Inertia apps
await expect(page).toHaveURL(/pattern/);
await expect(page.getByTestId('testid')).toBeVisible();
});
CSRF Protection Pattern (for POST requests in tests):
const cookies = await page.context().cookies();
const xsrfCookie = cookies.find((c) => c.name === 'XSRF-TOKEN');
const xsrfToken = xsrfCookie ? decodeURIComponent(xsrfCookie.value) : '';
await page.request.post('/endpoint', {
headers: { 'X-XSRF-TOKEN': xsrfToken }
});
Session Timeout Handling
Issue: Long-running task() calls timeout after 10 minutes (600000ms)
Solution:
- Check if file was created despite timeout:
ls -la tests/e2e/{filename}.spec.ts - If created, verify tests:
npx playwright test {filename}.spec.ts - If tests pass, proceed with verification and commit
- If tests fail, resume session with session_id (saves 70%+ tokens)
Pattern: Timeouts don't mean failure — check actual output before retrying
data-testid Naming Conventions
Established Patterns:
- Navigation:
auth-layout-nav-{page}(e.g.,auth-layout-nav-services) - User controls:
auth-layout-user-dropdown-trigger,auth-layout-logout-link - Sync:
auth-layout-sync-button,auth-layout-sync-timestamp - Lists:
{feature}-list-table,{feature}-list-row-{id},{feature}-list-empty - Actions:
{feature}-list-{action}-button(e.g.,service-list-edit-button) - Blocks:
{block}-block-{element}-{id}(e.g.,information-block-thumbnail-{id})
Rule: Always use kebab-case, always include component context, always be specific
German UI Text Assertions
Common Terms:
- Navigation: "Gottesdienste", "Song-Datenbank"
- Actions: "Bearbeiten", "Finalisieren", "Wieder öffnen", "Herunterladen", "Löschen"
- Auth: "Mit ChurchTools anmelden", "Abmelden", "Test-Anmeldung"
- General: "Willkommen", "Ablaufdatum", "Vorschau", "Zuweisen", "Mit Übersetzung"
Rule: Always use exact German text from Vue components, never English
Inertia.js + Playwright Gotchas
Issue: Inertia apps render client-side, so page.goto() returns before Vue renders
Solution: ALWAYS use await page.waitForLoadState('networkidle') after navigation
Issue: data-testid attributes don't appear in raw HTML (curl output)
Solution: Check compiled JS bundles: grep -r 'data-testid' public/build/assets/*.js
Parallel Task Execution
Wave 3 Pattern: All 6 tasks (T8-T13) can run in parallel
- Each creates independent spec file
- No shared state between tests
- All use same storageState (auth.setup.ts)
- workers:1 in playwright.config.ts prevents SQLite conflicts
Optimization: Dispatch all 6 tasks in ONE message for maximum parallelism
Verification Best Practices
4-Phase Verification (MANDATORY):
- Read Code: Read EVERY changed file line-by-line
- Automated Checks: Run tests, build, lsp_diagnostics
- Hands-On QA: Actually run the tests and see them pass
- Gate Decision: Can explain every line? Saw it work? Confident nothing broken?
Evidence Files: Save test output to .sisyphus/evidence/task-{number}-{name}.txt
Commit Messages: Use conventional commits format:
test(e2e): add {feature} E2E tests
- X tests: {list}
- German UI text assertions
- All tests passing
Token Budget Management
Session Stats:
- Started: 200K tokens
- Used: ~124K tokens (62%)
- Remaining: ~76K tokens (38%)
- Tasks completed: 7/24 (29.2%)
Optimization: Use session_id for retries (saves 70%+ tokens vs new task)
Strategy: Focus on completing Wave 3 (6 tasks) before token exhaustion