fix(pwa): Recovery-Zähler, Update-Suppression und Timer-Leaks beheben

Stale-Recovery zählt nur aufeinanderfolgende Fehler und wird nach Hard Recovery zurückgesetzt; Update-Checks respektieren „Später“, und PWA-Refresh-State sowie Recovery-Timer werden zuverlässig gesetzt bzw. beim Unmount aufgeräumt.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-31 14:24:25 +02:00
parent bbd4281dcb
commit 7cf04b3357
3 changed files with 95 additions and 13 deletions
+37
View File
@@ -1,11 +1,15 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
forcePwaRecovery,
markReloadAttempt,
recentlyAttemptedReload,
reconcileServiceWorkerOnStartup,
reconcileVersionOnStartup
} from './pwaStartup.js'
const STALE_RECOVERY_COUNT_KEY = 'pwa_stale_recovery_count'
const STALE_RECOVERY_LAST_KEY = 'pwa_stale_recovery_last_ts'
describe('pwaStartup reload guards', () => {
beforeEach(() => {
sessionStorage.clear()
@@ -19,6 +23,39 @@ describe('pwaStartup reload guards', () => {
})
})
describe('forcePwaRecovery stale counter reset', () => {
beforeEach(() => {
sessionStorage.clear()
vi.unstubAllEnvs()
vi.restoreAllMocks()
})
it('clears stale recovery counter before hard recovery reload', async () => {
vi.stubEnv('DEV', false)
sessionStorage.setItem(STALE_RECOVERY_COUNT_KEY, '2')
sessionStorage.setItem(STALE_RECOVERY_LAST_KEY, String(Date.now()))
const reload = vi.fn()
vi.stubGlobal('location', { reload })
vi.stubGlobal('caches', {
keys: vi.fn().mockResolvedValue([]),
delete: vi.fn()
})
Object.defineProperty(navigator, 'serviceWorker', {
configurable: true,
value: {
getRegistrations: vi.fn().mockResolvedValue([])
}
})
await forcePwaRecovery()
expect(sessionStorage.getItem(STALE_RECOVERY_COUNT_KEY)).toBeNull()
expect(sessionStorage.getItem(STALE_RECOVERY_LAST_KEY)).toBeNull()
expect(reload).toHaveBeenCalledOnce()
})
})
describe('reconcileServiceWorkerOnStartup', () => {
beforeEach(() => {
sessionStorage.clear()