feat(test): add Playwright E2E test suite#367
Open
dnplkndll wants to merge 22 commits intoChurchApps:mainfrom
Open
feat(test): add Playwright E2E test suite#367dnplkndll wants to merge 22 commits intoChurchApps:mainfrom
dnplkndll wants to merge 22 commits intoChurchApps:mainfrom
Conversation
1077a59 to
f231a18
Compare
- Add global-setup.ts for single login + storageState reuse across workers - Add playwright.config.ts with project dependencies (settings runs first) - Fix settings.spec.ts: use dispatchEvent for toolbar-intercepted clicks, update SVG selectors for mobile edit buttons, fix form edit selectors - Skip delete-form-questions test (upstream API 500 bug on sort column) - Split serving.spec.ts into 3 focused files (lessons, plans, songs-tasks) - Update all spec files to use shared auth helper with storageState - Add .auth-state.json to .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- global-setup.ts: replace networkidle wait with emailInput visibility
check; fixes WebSocket preventing networkidle from settling
- auth.ts: use Promise.race(navButton, emailInput) instead of sequential
isLoginPage check; prevents false-positive re-login when React briefly
flashes login form before reading stored JWT
- settings.spec.ts:
- Replace all networkidle waits with specific element visibility checks
- Add pre-cleanup loop targeting form rows by name (tr filter) so
leftover Octav forms are deleted regardless of list order
- Add explicit visibility waits for Add Question button and Form Members
tab; both depend on async memberPermission query completing after
navigation to the form detail page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Navigation refactored to use SiteHeader from @churchapps/apphelper. #primaryNavButton no longer exists in the DOM.
Replaced #site-header/#primaryNavButton selectors with login form visibility checks. Auth is confirmed by the login form disappearing after submit, not by detecting a specific nav element. This is resilient to nav refactors upstream.
After a successful login, the SelectChurchModal always appears on a fresh session (no lastChurchId cookie). The login form stays mounted while the dialog is open, so waiting for emailInput to be hidden always times out. Fix: use Promise.race to wait for either the church dialog or navigation, then handle the dialog by clicking the church and waiting for URL change. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously login() waited 8s for emailInput timeout when already authenticated (storageState), leaving only 5s (actionTimeout) for #primaryNavButton to render. Race navButton vs emailInput instead: return immediately when authenticated and nav is provably ready. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…test overhead from 20s to 5s
Add console.log debugging to Mobile Settings and Form Questions tests to capture browser state during CI: secondary menu content, API failures, and console errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mobile Settings tests were failing because they looked for "Mobile Apps" in the settings secondary menu, but "Mobile" is actually a primary nav item (gated by ContentApi permissions). Fixed to navigate via the primary nav dropdown instead. Also removed debug instrumentation from form questions test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NavItem renders <a href="about:blank"> with programmatic onClick navigation, so a[href="/mobile"] never matches. Use the NavItem's auto-generated data-testid="nav-item-mobile" instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Intercept login API response and log nav items to diagnose why ContentApi permissions aren't reflected in the primary nav in CI. Only runs when CI=true env var is set. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All settings tests (Mobile, Forms, General) now pass in CI. The diagnostic logging was only needed to debug the failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
actionTimeout 5s → 15s fixes 132 test failures where MUI components need extra render cycles. Dashboard beforeEach now navigates directly to /dashboard instead of clicking nav-item which routes to / (onboarding). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ision The edit form and cancel edit tests were clicking the first Edit button on the page, which could be a seed data form (contentType=person) instead of the test-created form (contentType=form). This caused the Form Members tab to never appear since it requires contentType=form. Now targets the specific form row by name instead of using .first(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Same .first() ambiguity as the edit/cancel tests — now targets the specific "Octavius Test Form" row. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
c55ccb6 to
a887a89
Compare
- edit form questions: fix race condition — wait for edit form to load question data before filling title (prevents API fetch from overwriting the fill). Use waitForResponse to confirm POST /questions completes. - create/edit/delete form: handle duplicate test forms from previous runs using .first() selectors, improved pre-cleanup loop, and loop-based deletion. Relax assertions to toBeVisible() instead of toHaveCount(1). - cancel editing form questions: add .first() for duplicate question text. - form restriction: use 'Restricted' (actual dropdown option, not 'Public' which was the original incorrect value). - delete form: loop to delete all matching test forms, not just one. - playwright.config: increase timeout/navigationTimeout for remote envs. Skip 3 tests blocked by upstream issues: - add person to role: /users/loadOrCreate returns 400 because person search results have undefined name.first/name.last fields. - add/remove form members: Form Members tab requires forms.admin permission that the test user doesn't have (unrelated to restricted flag). Verified: 17 pass, 4 skip on both MySQL and PostgreSQL environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Un-skip "add person to role" (API double-conversion bug fixed in PersonRepo) - Un-skip "delete form questions" (sort column bug fixed in Drizzle QuestionRepo) - Un-skip "add/remove form members" (demo user has forms.admin permission) - Add /mobile and /site/pages to Header.tsx test ID mappings (mobile tests were failing because nav-item-mobile data-testid was never assigned) - Use waitForResponse and proper timeouts instead of fixed delays Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace waitForTimeout(200) with proper data-load assertions: - Wait for form name field to have expected value before editing - Wait for role name field to load before editing - Wait for mobile tab name to load before editing - Wait for question title to load before cancelling - Fix "add person to role" to search for "Jennifer Williams" (exists in demo data) - Fix form edit test: wait for API data to prevent contentType reset from "form" to "person" The contentType bug caused Form Members tab to not appear — the edit form's default state has contentType:"person", and saving before API data loads overwrites the original "form" contentType. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prior runs can leave up to 10+ Octav* forms. Increase cleanup loop from 5 to 10 iterations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Playwright waits
- Replace ~120 waitForTimeout() calls with element visibility/assertion waits
- Replace all SVG d="..." path selectors with partial-match or text-based selectors
- Remove .catch(() => {}) from waitForResponse calls (let failures propagate)
- Fix missing await on waitForTimeout (serving-plans, website)
- Fix invalid locators (page.locator('text') → page.getByText())
- Replace hardcoded .nth(N) with .last() for dynamic lists (donations chart, website blocks)
- Fix expect(primitive).toBe() → expect(locator).toHaveCount() (people)
- Scope edit buttons to specific rows to avoid ambiguous .first() selectors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tests/global-setup.ts) — single login, savesstorageStatefor reuse across all specsplaywright.config.tsto supportBASE_URLenv var override (defaults todemo.b1.church)serving.spec.tsinto focused files:serving-lessons,serving-plans,serving-songs-taskswaitForTimeoutvalues across all specs (5000ms → 200-1000ms).auth-state.jsonto.gitignoreTest plan
npx playwright testagainstdemo.b1.church(default)BASE_URL=http://localhost:3101 npx playwright testagainst local dev🤖 Generated with Claude Code