test(web): make test localStorage shim writable#2219
Conversation
The vitest setup shim defined `globalThis.localStorage` via
`Object.defineProperty(..., { configurable: true })` without
`writable: true`. `Object.defineProperty` defaults
`writable` to `false`, which made the property read-only.
Multiple test files reassign the global directly in their own
`beforeEach` (`globalThis.localStorage = makeLS()`):
- `apps/web/src/core/lib/featureFlags.test.ts`
- `apps/web/src/core/lib/insightsEngine.test.ts`
- `apps/web/src/modules/nutrition/lib/nutritionStorage.test.ts`
- `apps/web/src/modules/nutrition/lib/shoppingListStorage.test.ts`
- `apps/web/src/modules/nutrition/lib/waterStorage.test.ts`
- `apps/web/src/modules/nutrition/domain/nutritionBackup.test.ts`
- `apps/web/src/shared/lib/storage/typedStore.test.ts`
Each of those failed in CI with
`TypeError: Cannot assign to read only property 'localStorage'
of object '#<Object>'`, which broke the
`Test coverage (vitest)` and umbrella `check` jobs on PRs
#2217 and #2218 (both shipped despite this — the prior PR
review confirmed the failure was pre-existing on main and
unrelated to those PRs' code changes).
Adding `writable: true` flips the slot to a normal data
property so the existing test pattern keeps working without
having to rewrite every `beforeEach`. `configurable: true`
stays so a later `ensureTestLocalStorage()` call can still
re-define the slot if a test deletes the shim.
Local repro:
- `pnpm --filter @sergeant/web exec vitest run
src/core/lib/featureFlags.test.ts ...` 7/7 files green
(88 tests)
- Full `pnpm --filter @sergeant/web exec vitest run`:
221 files / 2197 tests pass under Node 20.20.2
No production code changes — only the test bootstrap.
Co-Authored-By: dmytro.s.stakhov <dmytro.s.stakhov@gmail.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThe PR adds ChangesTest Infrastructure
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
⏱️ CI Pipeline Duration ReportBased on the last 50 successful runs on the default branch. Overall Pipeline
Trend (last 20 runs): Per-Job Breakdown
|
Summary
Adds
writable: trueto theObject.defineProperty(globalThis, "localStorage", …)descriptor inapps/web/src/test/setup.ts.Object.definePropertydefaultswritabletofalse, which made the shim a read-only data slot and broke any test that does direct global reassignment in its ownbeforeEach(globalThis.localStorage = makeLS()). Seven test files use that pattern and were failing in CI withTypeError: Cannot assign to read only property 'localStorage' of object '#<Object>':apps/web/src/core/lib/featureFlags.test.tsapps/web/src/core/lib/insightsEngine.test.tsapps/web/src/modules/nutrition/lib/nutritionStorage.test.tsapps/web/src/modules/nutrition/lib/shoppingListStorage.test.tsapps/web/src/modules/nutrition/lib/waterStorage.test.tsapps/web/src/modules/nutrition/domain/nutritionBackup.test.tsapps/web/src/shared/lib/storage/typedStore.test.tsThese failures were the "pre-existing on main" breakage flagged on the
Test coverage (vitest)and umbrellacheckjobs of PR #2217 and PR #2218.configurable: truestays so the existing reset path (ensureTestLocalStorage→ re-define on next call) keeps working. Inline comment (Ukrainian, per Hard Rule #15) explains the rationale.No production code changes — test bootstrap only.
Governing Skill
Playbook
Verification
Note: running vitest directly via
pnpm --filter @sergeant/web exec vitestrequires@sergeant/db-schemato be pre-built (pnpm --filter @sergeant/db-schema build) because the umbrellapnpm testgoes through Turborepo (testdepends on^build) but the direct invocation does not. CI uses the Turbo path, so this is only a local-dev nuance.Additional checks:
Docs and Governance
AGENTS.mdneeded an update.Updated docs:
Risk and Rollout
apps/web/src/test/setup.ts); not bundled into web/server/mobile output.writable: true) — return-to-prior-state is identical to the pre-PR descriptor.Hard Rule #15
AGENTS.mdbefore coding.--no-verify.Audit-freeze (until 2026-06-02)
Reviewer Notes
apps/webdeliberately relies onglobalThis.localStoragebeing read-only (e.g., to assert the shim resists overwriting). I grep'd and found none — every reassignment is intentional test-supplied mock seeding — and the full 2197-test sweep passes, but worth a second pair of eyes.configurable: true, so theensureTestLocalStorage()re-define path on the nextafterEach/setup tick keeps functioning identically.Test coverage (vitest)and umbrellacheckjobs that were red on PRs docs(docs): close audit items 5 and 7 with PR 2215/2216 evidence #2217 and perf(web): lazy-load hub views + split markdown/auth/zod vendors (audit #9, #10) #2218 (both shipped despite that, since the failure was confirmed pre-existing — see the comment thread on perf(web): lazy-load hub views + split markdown/auth/zod vendors (audit #9, #10) #2218 for the per-job breakdown).Link to Devin session: https://app.devin.ai/sessions/468732c16b1b4805b00ee2d0d47865f1
Requested by: @Skords-01
Summary by cubic
Make the
localStoragetest shim writable so tests can reassign it without errors. This fixes CI failures in the web vitest suite.writable: trueonglobalThis.localStorageinapps/web/src/test/setup.ts; keptconfigurable: true.globalThis.localStorage = …(7 files) and removes the read-only TypeError in CI.Written for commit 1a2a4e3. Summary will update on new commits.
Summary by CodeRabbit