When a SuperSync account is deleted, clients now properly detect
authentication failures and prompt for reconfiguration:
- Add _checkHttpStatus() helper to SuperSyncProvider that throws
AuthFailSPError on 401/403 responses
- Clear cached credentials on auth failure to allow reconfiguration
- Add DELETE /api/test/user/:userId endpoint for E2E testing
- Add deleteTestUser() helper in supersync-helpers.ts
- Add E2E tests for account deletion and reconfiguration scenarios
The existing SyncWrapperService already handles AuthFailSPError by
showing a snackbar with "Configure" action, so no UI changes needed.
- e2e/utils/waits.ts: Add proper retry logic and error handling when
waiting for magic-side-nav to appear. Now throws a clear error if
app doesn't load within 30s instead of silently continuing.
- packages/super-sync-server/src/auth.ts: Use nullish coalescing for
passwordHash to handle passkey-only users (who have no password).
- packages/super-sync-server/src/passkey.ts: Add WebAuthn passkey
authentication support. Fix TypeScript errors by importing types
from @simplewebauthn/types and converting credential IDs to
base64url strings.
Fixes flaky "Multiple fresh clients join and sync correctly after
snapshot" test that was failing when app didn't fully load.
Resolve conflict in webdav-sync-expansion.spec.ts:
- Use simplified sync verification without reload (sync updates NgRx directly)
- Test: B marks task done -> sync -> verify A sees task as done
- Add page.isClosed() checks before waitForTimeout calls to prevent
"Target page, context or browser has been closed" errors when tests
timeout (supersync-helpers.ts, waits.ts, supersync.page.ts)
- Fix context menu selector in LWW tests: use .mat-mdc-menu-item instead
of button[mat-menu-item] which doesn't match Angular Material menu items
- Add retry logic for opening context menus with proper wait/escape handling
- Skip "Subtask edit survives when parent is deleted" test - documents
expected future behavior that is not yet implemented
The closeClient helper was throwing errors when trying to close browser
contexts that were already closed (due to test timeouts or failures).
This caused cascading errors in E2E tests and made debugging harder.
Fix by checking if page is closed before attempting to close the context,
and gracefully catching "already closed" errors.
Previously, flushYoungToOld was dispatched as an action and handled by
an NgRx effect. This caused a race condition during finish day:
1. Action dispatched, effect queued
2. Method returned, sync started, DB locked
3. Effect ran, tried to write, blocked by DB lock
Fix follows the same pattern as moveToArchive:
- Perform the flush synchronously in ArchiveService before dispatching
- Dispatch action for op-log capture only (syncs to other clients)
- Handler skips local operations (only runs for remote)
Also adds comprehensive unit tests and e2e test for this scenario.
Replace UUIDv7 timestamp-based filtering with vector clock comparison
in _filterOpsInvalidatedBySyncImport(). This fixes a bug where client
clock drift could cause pre-import operations to bypass filtering.
Vector clocks track causality ("did this client know about the import?")
rather than wall-clock time, making the filtering immune to clock drift.
Operations are now filtered based on comparison result:
- GREATER_THAN or EQUAL: keep (client had knowledge of import)
- LESS_THAN or CONCURRENT: filter (created without knowledge)
Also fix E2E tests to properly skip when SuperSync server isn't
running in TEST_MODE by checking test endpoint availability.
Fix race condition where sync could start before local operation writes
completed to IndexedDB, causing conflict detection to miss pending ops.
- Add OperationWriteFlushService that uses sp_op_log lock to ensure all
pending writes complete before reading from IndexedDB
- Call flushPendingWrites() before conflict detection in sync service
- Add retry with exponential backoff to createTestUser for rate limiting
- Add unit tests for flush service and sync ordering
The flush mechanism works by acquiring the same lock used by writeOperation().
Since effects use concatMap and Web Locks API guarantees FIFO ordering,
acquiring the lock means all prior writes have completed.
Increased timeouts and added stability improvements for SuperSync E2E tests to address flakiness and resolve 'Sync already in progress' errors.
- Increased default 'waitForTask' timeout from 45s to 60s in 'supersync-helpers.ts'.
- Increased auto-sync detection timeout in 'SuperSyncPage' from 3s to 5s.
- Added a 1s delay in 'SuperSyncPage.triggerSync' to mitigate race conditions.
Also includes other related E2E and SuperSync server fixes:
- Updated 'test-backup.json' with new config properties.
- Improved error handling in 'import.page.ts' for file dispatch events.
- Added reload and app readiness waits in 'supersync.spec.ts' for time tracking tests.
- Enabled WAL journal mode in 'super-sync-server/src/db.ts' for better database performance.
- Implemented data cleanup for existing test users in 'super-sync-server/src/test-routes.ts' to ensure clean test states.
These changes collectively resolve intermittent failures across the E2E test suite.
Improvements to make sync tests more reliable:
- Increase waitForTask default timeout from 15s to 25s
- Add retry loop in waitForTask for DOM update delays
- Add UI settling delay (300ms) after syncAndWait
- Add waitForLoadState('domcontentloaded') after sync operations
- Improve conflict dialog handling with retry for G.APPLY button
- Wait for conflict dialog to close before continuing
- Add explicit timeouts to visibility assertions
These changes address timing issues where the UI hasn't fully
updated after sync operations complete.
- Add waitForStatePersistence utility for sync tests to replace hardcoded delays
- Fix nav-list vs nav-list-tree selector inconsistencies across test files
- Replace waitForTimeout calls with proper element waits and Angular stability checks
- Update selectors.ts constants to use correct nav-list-tree component selector