AgentSkillsCN

tryramadan-testing

在 TryRamadan 中如何添加并运行测试。采用 Vitest 与 React Testing Library 进行测试。涵盖工具函数与自定义钩子的单元测试、localStorage 持久化、倒计时与祷告时间缓存、新手引导流程,以及无障碍访问(axe)。适用于新增测试用例、修复测试失败,或验证关键路径时使用。

SKILL.md
--- frontmatter
name: tryramadan-testing
description: How to add and run tests in TryRamadan. Uses Vitest and React Testing Library. Covers unit tests for utils and hooks, localStorage persistence, countdown and prayer cache, onboarding flows, and accessibility (axe). Use when adding tests, fixing test failures, or verifying critical paths.

Testing (TryRamadan)

Use this skill when adding tests, fixing failing tests, or verifying critical user paths. Stack: Vitest, @testing-library/react, vitest-axe for a11y.


1. Run commands

bash
npm run test              # Run all tests once
npm run test:watch        # Watch mode
npm run test -- src/test/countdownAndPrayerTimes.test.ts   # Single file

2. Test file locations and scope

FileScope
src/test/countdownAndPrayerTimes.test.tsTime utils, countdown logic, today + Ramadan prayer cache, no-API-when-cached
src/test/localStorage.test.tspersistPreferencesSync, persistQuickActionsSync, useLocalStorage hook, getSuggestedCalories
src/test/loggingAndTracking.test.tsFasting progress, streak, getTodayFastingLog, daily missions, food log helpers
src/test/prayerTimes.test.tsgetRamadanPrayersCacheKey, fetchRamadanPrayerTimes (API failure)
src/test/ramadan.test.tsRamadan date helpers (getRamadanStartForYear, isRamadanDay, etc.)
src/test/ical.test.tsbuildIcalContent, date range, timezone, export modes
src/test/onboardingFlow.test.tsxComplete onboarding → dashboard, persist preferences, no redirect loop
src/test/dashboardFeatures.test.tsxDay selector, fasting status, quick actions, links (with localStorage prefill)
src/test/accessibility.test.tsxaxe-core on HeroSection, OnboardingWelcome, ArabicHover, key flows
src/test/mainFeatures.test.tsxIndex/Dashboard render, links
src/test/routes.test.tsxRoute list and existence

3. Setup and mocks

  • Setup: src/test/setup.ts – jest-dom, vitest-axe matchers, matchMedia and IntersectionObserver mocks.
  • localStorage: Clear in beforeEach when tests depend on fresh state (e.g. localStorage.clear()). Pre-fill when testing cache hit or persisted preferences (e.g. localStorage.setItem("tryramadan-preferences", JSON.stringify({ ... }))).
  • fetch: Use vi.spyOn(global, "fetch") to assert no API call when cache is used or to mock API failure.

4. Testing hooks

  • Use renderHook from @testing-library/react for useLocalStorage, usePrayerTimes, etc.
  • Use act() when updating state (e.g. setter from useLocalStorage).
  • For async: waitFor(() => { expect(...).toBe(...) }).

5. What to test when adding features

  • New utils (time, countdown, cache): Unit tests in the relevant test file; keep pure functions easy to test.
  • New persistence: Test round-trip (write then read from localStorage); test merge/override behavior if applicable.
  • Critical paths: Onboarding completion → dashboard; set location → see prayer times; complete/break fast. Prefer integration-style tests that render the route and fire events.
  • Accessibility: Add or extend accessibility.test.tsx for new pages or components that are critical for a11y (forms, live regions, focus).

6. Common pitfalls

  • useState initial value: If a hook writes to localStorage in useEffect, the key may exist after first render; don’t assert it’s null after mount when the hook persists initial value.
  • todayStr: Tests that depend on "today" use toLocalDateString(new Date()) or cache prefill with that value so cache key matches.
  • React hooks deps: Fix exhaustive-deps where safe; shadcn/ui fast-refresh warnings can remain if documented.