Restructure FE tests and auth redirects#611
Conversation
Restructure the frontend test layout and test tooling: move many __tests__ into organized fe/src/test/* folders, add test factories, mocks, stubs and utility helpers, and remove the checked-in fe/eslint-report.json. Add a Vitest multi-project entry (fe/vitest.projects.ts) and a test-structure guard script (fe/scripts/check-test-structure.mjs), update vitest and TypeScript configs and Vite settings, and remove the old vitest.no-setup.config.ts. Update fe/README.md with guidance on running Vitest projects and the new frontend verification gate, add npm verify scripts in package.json, and adjust .gitignore entries to ignore eslint-report.json. Miscellaneous edits: VS Code file nesting settings and other small config tweaks to support the new test layout.
Change Cypress baseUrl and centralize API intercepts by adding a support helper. Updated fe/cypress.config.ts to use port 4173. Added fe/cypress/support/api.ts exporting apiPath() (wraps endpoints with /api/v*) and stubAppShellApi() to centralize common stubs. Refactored multiple e2e specs to use apiPath for intercept URLs and to use stubAppShellApi in settings, plus minor test cleanup/formatting and consistent mock response shapes. Affected files: cypress.config.ts, support/api.ts, and several tests under fe/cypress/e2e (file-naming-patterns.cy.ts, hardlink-move-flow.cy.ts, move-flow.cy.ts, settings-root-folders.cy.ts, settings.cy.ts).
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Reorganizes the frontend testing/tooling setup around Vitest projects, colocated test/ folders, shared test utilities, and updated Cypress e2e stubs for versioned API routes.
Changes:
- Added Vitest project-based configuration (node/jsdom/smoke) with coverage configuration and a test structure guard script.
- Introduced shared frontend test utilities (mounting helpers, waits, storage mocks, factories, stubs, API/SignalR mocks).
- Updated Cypress e2e tests to use a version-aware API path helper and aligned baseUrl/verification scripts.
Reviewed changes
Copilot reviewed 89 out of 116 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| scripts/lint-staged.mjs | Runs frontend lint/format via local node bin paths to improve Windows/Git Bash reliability. |
| package.json | Adds a root convenience script for running the frontend verification gate. |
| fe/vitest.projects.ts | Defines Vitest projects and globs for runtime separation. |
| fe/vitest.no-setup.config.ts | Removes the legacy “no setup” Vitest config. |
| fe/vitest.config.ts | Switches to project-based Vitest config and adds unit coverage settings/thresholds. |
| fe/vite.config.ts | Tweaks production-only build minify/esbuild options. |
| fe/tsconfig.vitest.json | Updates test TS includes and library targets for Vitest typechecking. |
| fe/tsconfig.node.json | Updates Node TS includes (adds vitest projects/config patterns; removes stale configs). |
| fe/tsconfig.app.json | Excludes new colocated src/**/test/**/* paths from app TS build. |
| fe/src/test/utils/wait.ts | Adds shared async helpers (delay/flush/waitFor/deferred). |
| fe/src/test/utils/storage.ts | Adds a Vitest storage mock helper. |
| fe/src/test/utils/mount.ts | Adds reusable mount helpers for Pinia/router + stubs merging. |
| fe/src/test/stubs.ts | Adds shared component stubs (modal/base/app). |
| fe/src/test/mocks/signalr.ts | Adds a SignalR service mock factory. |
| fe/src/test/mocks/api.ts | Adds API service/module mock factories. |
| fe/src/test/factories/settings.ts | Adds settings factory helper. |
| fe/src/test/factories/searchResult.ts | Adds SearchResult factory helper. |
| fe/src/test/factories/rootFolder.ts | Adds RootFolder factory helper. |
| fe/src/test/factories/qualityProfile.ts | Adds QualityProfile factory helper. |
| fe/src/test/factories/indexer.ts | Adds Indexer factory helper. |
| fe/src/test/factories/downloadClient.ts | Adds download client configuration factory helper. |
| fe/src/test/factories/download.ts | Adds Download factory helper. |
| fe/src/test/factories/audiobook.ts | Adds Audiobook factory helper. |
| fe/src/test/README.md | Documents the new frontend test layout and rules. |
| fe/src/components/base/BrandLogo.vue | Makes logo source a bound constant (helps tests/static asset handling). |
| fe/src/tests/useScore.spec.ts | Refactors to use shared SearchResult factory. |
| fe/src/tests/useScore.rejection.spec.ts | Refactors to use shared SearchResult factory. |
| fe/src/tests/test-setup.ts | Removes the global Vitest setup file and its centralized mocks/polyfills. |
| fe/src/tests/startupConfigCache.test.ts | Refactors concurrency test to use shared deferred helper. |
| fe/src/tests/sessionTokenStorage.test.ts | Uses explicit storage mock + module reset; switches to async import. |
| fe/src/tests/searchResultHelpers.spec.ts | Adjusts casting to align with new lint rules for tests. |
| fe/src/tests/searchResultFormatting.spec.ts | Adjusts casting to align with new lint rules for tests. |
| fe/src/tests/sanity.spec.js | Removes legacy sanity test (JS). |
| fe/src/tests/sanity.js | Removes legacy sanity test (JS). |
| fe/src/tests/libraryImport.store.spec.ts | Uses shared flush helper and adjusts test casts. |
| fe/src/tests/import-activity.spec.ts | Updates path reference for ActivityView compile check. |
| fe/src/tests/grabsSortable.spec.ts | Uses shared stubs/factories/wait helpers; improves polling logic. |
| fe/src/tests/debug_AddNew.spec.ts | Removes debug placeholder spec. |
| fe/src/tests/customFilterEvaluator.spec.ts | Adjusts casting style for tests. |
| fe/src/tests/audiobook-detailview.signalr.spec.ts | Uses shared delay helper; adjusts SignalR callback injection. |
| fe/src/tests/api.removeFromLibrary.spec.ts | Adjusts fetch call typing/casting. |
| fe/src/tests/api.ensureImageCached.spec.ts | Switches to alias imports + unmock; adjusts casting. |
| fe/src/tests/api.downloadLogs.spec.ts | Switches to alias imports for unmock + dynamic import. |
| fe/src/tests/api.csrf-retry.spec.ts | Tightens apiService shape and normalizes casting. |
| fe/src/tests/api.advancedSearch.spec.ts | Adjusts fetch call typing/casting. |
| fe/src/tests/WantedView.spec.ts | Uses shared delay helper; adjusts store typing casts. |
| fe/src/tests/SettingsView.spec.ts | Refactors to shared mount helpers and introduces mocked auth store. |
| fe/src/tests/SearchResultCard.spec.ts | Adjusts casting style for tests. |
| fe/src/tests/RootFoldersSettings.spec.ts | Uses deferred + flush helpers; normalizes API spy typing. |
| fe/src/tests/RenamePreviewModal.spec.ts | Adds modal stubs and local API mock for test stability. |
| fe/src/tests/QualityProfilesTab.spec.ts | Uses vi.doMock + flush helper; adds base stubs. |
| fe/src/tests/NotificationsTab.spec.ts | Adds modal stubs; normalizes casts. |
| fe/src/tests/ManualSearchModal.spec.ts | Centralizes modal stubs; swaps ad-hoc waits for shared delay helper. |
| fe/src/tests/LibraryImportSearchModal.spec.ts | Adds modal stubs and uses shared flush helper. |
| fe/src/tests/LibraryImportFooter.spec.ts | Uses shared flush helper and normalizes casts. |
| fe/src/tests/IndexersTab.spec.ts | Adds modal stubs + flush helper; normalizes vi.doMock typing. |
| fe/src/tests/IndexerFormModal.spec.ts | Adjusts casting style for tests. |
| fe/src/tests/EditAudiobookModal.relativePath.spec.ts | Uses shared delay helper; simplifies casts. |
| fe/src/tests/EditAudiobookModal.moveOptions.spec.ts | Adds modal stubs and replaces sleeps with shared delay helper. |
| fe/src/tests/DownloadsView.spec.ts | Uses shared delay helper. |
| fe/src/tests/DownloadClientsTab.spec.ts | Uses factory helper; normalizes vi.doMock typing/casts. |
| fe/src/tests/DownloadClientFormModal.spec.ts | Switches to hoisted API mock and adds modal stubs. |
| fe/src/tests/CollectionView.spec.ts | Uses shared flush helper; normalizes global stubs and casts. |
| fe/src/tests/AudiobooksView.spec.ts | Adds explicit browser/storage mocks; improves cleanup across tests. |
| fe/src/tests/AudiobookDetailView.spec.ts | Uses shared delay/flush helpers; normalizes casts. |
| fe/src/tests/AppActivityBadge.spec.ts | Uses shared delay helper; normalizes casts. |
| fe/src/tests/ApiKeyControl.spec.ts | Uses shared flush helper; normalizes navigator clipboard mocking. |
| fe/src/tests/AddNewView.spec.ts | Adds explicit API/SignalR mocks; uses storage + delay helpers. |
| fe/src/tests/AddLibraryModal.relativePath.spec.ts | Adds modal stubs and uses shared delay helper. |
| fe/src/tests/AddLibraryModal.editableMetadata.spec.ts | Adds modal stubs for consistent modal rendering. |
| fe/src/tests/AddLibraryModal.accessibility.spec.ts | Adds modal stubs and uses shared flush helper. |
| fe/src/tests/ActivityView.spec.ts | Uses shared flush helper; normalizes interval mock typing. |
| fe/src/tests/ActivityView.mobile.spec.ts | Uses shared delay helper; normalizes interval mock typing. |
| fe/scripts/check-test-structure.mjs | Adds a guard script enforcing colocated tests and config rules. |
| fe/package.json | Adds frontend verify gate, coverage script, structure lint, and Vitest project runs. |
| fe/eslint.config.ts | Updates Vitest lint file globs and relaxes no-explicit-any for tests. |
| fe/cypress/support/api.ts | Adds apiPath + shared app shell API stubs for e2e tests. |
| fe/cypress/e2e/settings.cy.ts | Updates Settings e2e stubs to version-aware API paths and current UI fields. |
| fe/cypress/e2e/settings-root-folders.cy.ts | Updates Root Folders e2e to version-aware API paths. |
| fe/cypress/e2e/move-flow.cy.ts | Updates move flow e2e to version-aware API paths. |
| fe/cypress/e2e/hardlink-move-flow.cy.ts | Updates hardlink/copy move flow e2e to version-aware API paths. |
| fe/cypress/e2e/file-naming-patterns.cy.ts | Updates file naming e2e coverage to version-aware API paths. |
| fe/cypress.config.ts | Aligns Cypress baseUrl to port 4173 (matches e2e scripts). |
| fe/README.md | Updates documentation for Vitest projects and the frontend verify script. |
| fe/.vscode/settings.json | Removes Playwright nesting references and updates config nesting. |
| fe/.gitignore | Updates ignored tooling outputs (eslint report) in frontend. |
| CONTRIBUTING.md | Updates contributor instructions to run the new frontend verification gate. |
| .husky/pre-push | Runs version sync + backend format + FE typecheck + FE tests with Node PATH workaround. |
| .husky/pre-commit | Replaces npm wrapper invocation with node script + adds enforcement checks. |
| .gitignore | Updates ignored tooling outputs (eslint report) at repo root. |
Files not reviewed (1)
- fe/package-lock.json: Language not supported
Comments suppressed due to low confidence (2)
fe/src/test/utils/storage.ts:1
installStorageMock()referenceswindowunconditionally, which will throw aReferenceErrorif this helper is ever imported/used from a node-environment Vitest project (unit-node). Guard theseObject.defineProperty(window, ...)calls behind atypeof window !== 'undefined'check (and rely onvi.stubGlobalfor non-DOM environments), so the helper is safe in both runtimes.
fe/src/test/utils/mount.ts:1- Swallowing
router.isReady()failures makes test failures harder to debug and can mask navigation/setup problems (tests may proceed with a router that isn’t actually ready). Prefer letting the rejection propagate, or rethrow with additional context so failures are actionable.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 93c7c1bd64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Add esbuild@0.28.0 to fe/package.json as a dev dependency.
Remove esbuild from front-end dependencies and update Vite config to use the 'oxc' minifier. Add production minification options (drop console/debugger, mangle and codegen) via Rollup output config and keep sourcemaps enabled for bundle analysis. Also tidy the visualizer plugin cast/comment to avoid TypeScript signature mismatches.
Introduce a reusable SignalR test mock and an opt-in Vitest setup file for SignalR. Adds src/test/mocks/signalr.ts with a callback registry, emit/reset helpers and a signalRServiceMock, and a setup file src/test/setup/signalr.ts that auto-mocks the real service and resets the mock after each test. Update a spec to use the new mock (remove manual spy/callback plumbing), add the setup file to vitest.config.ts, and extend the test README to document the allowed global mock and guidelines. Also tighten check-test-structure.mjs to only permit the specific setup file and to allow only that setupFiles config, and add a few asset/font entries to .gitignore.
- Move auth redirect decisions into router, login, and app shell - Add colocated auth store, router guard, login, and app-shell tests - Document auth test boundaries and stabilize Vitest config
- Resolved #611 conflicts against latest canary - Preserved auth redirect cleanup and colocated frontend tests - Regenerated frontend lockfile after dependency merge
- Fail pre-push when version sync leaves package metadata changed - Keep pushed commits aligned with the files validated by the hook
Summary
Reorganizes the frontend test architecture around colocated
test/folders and Vitest projects, then folds in the #678 auth/router cleanup so frontend auth behavior has clearer ownership boundaries. Also merges the latestcanaryintofeature/fe-test-architectureso PR #611 is conflict-free against its base.Closes #678
Changes
Added
/api/v*/...e2e route stubs.Changed
src/__tests__layout into colocatedtest/folders.*.node.spec.tsconvention.settings.cy.tsto test the current General Settings UI instead of removed proxy/output-path controls.baseUrlwith the e2e script port4173.canaryinto the branch and resolved PR Restructure FE tests and auth redirects #611 conflicts.Fixed
/api/v1/...app requests.fe/node_modulesto matchfe/package-lock.json.Removed
fe/src/__tests__structure.auth.redirectToas cross-component redirect state.Testing
cd fe && npm run test:unit:jsdomcd fe && npm run type-check:testcd fe && npm run verifycd fe && npm run lint:eslintcd fe && node node_modules/typescript/bin/tsc -p cypress/tsconfig.json --noEmitcd fe && node node_modules/cypress/bin/cypress verifycypress/e2e/settings.cy.ts./.husky/pre-commithttp://127.0.0.1:5173/returned 200Notes