super-productivity/e2e/utils
Johannes Millan dc0378edd6
[codex] Fix sync import conflict from startup example tasks (#7976)
* fix(sync): ignore startup example tasks during import

* fix(sync): defer startup example tasks until initial sync completes

Switch ExampleTasksService to afterInitialSyncDoneStrict$ so example tasks
are not created before the first remote import lands. On a fresh synced
client the imported tasks are then already in the store and the length===0
guard skips creation entirely — closing the same conflict for file-based
providers (Dropbox/WebDAV), which the op-log marker gate does not cover.

The isExampleTask marker + gate exclusion stay as a safety net for the
narrow case where example tasks are created on a still-empty server and an
import arrives before they are uploaded.

Also dedupe the two markRejected call sites into _discardExampleTaskOps and
document the local-only read (a remote isExampleTask flag can never bypass
the conflict dialog) and the intentional mixed-case behavior.

* test(sync): cover mixed-pending and empty-discard import gate cases

Add a SyncImportConflictGateService test for the mixed case (real pending
work + startup example tasks): the conflict dialog is still shown, but the
example-task id is reported in discardablePendingOpIds and intentionally
left for the caller to keep on USE_LOCAL — locking the documented invariant.

Also assert markRejected is not called on the config-only silent-accept path,
pinning the empty-array guard in _discardExampleTaskOps.

* test(sync): integration coverage for example-task import gate

Run the real OperationLogStoreService + SyncImportConflictGateService against
IndexedDB (no mocks) to cover the seam the unit specs stub:
- example-task creates persisted with their real multi-entity payload are
  recognized as non-meaningful and reported as discardable
- after markRejected they are actually excluded from getUnsynced() (never
  uploaded), while a pending config op is preserved
- real user work alongside example tasks still triggers the dialog
- a remote-sourced example-task op is never discardable (gate reads local
  pending only)

Verified load-bearing: removing the gate exclusion turns the first case red.

* fix(sync): mark onboarding done when example tasks are skipped

EXAMPLE_TASKS_CREATED was only written after creating example tasks, so a
synced client that skipped creation because real tasks already existed never
set the flag — and could recreate onboarding tasks on a later startup when
the task list happened to be empty.

Set the flag whenever tasks already exist at the initial-sync gate, so
onboarding runs at most once per client.

* docs(sync): note known limits of the example-task import gate

Document two accepted, narrow residuals of syncing onboarding example tasks:
- upload→piggyback path: example ops accepted in the same upload round are
  already synced and not in the discard list; state stays correct because the
  SYNC_IMPORT filter drops them as CONCURRENT on receivers.
- file-based snapshot path: hasMeaningfulStoreData() counts example tasks (no
  in-state marker), so a fresh Dropbox/WebDAV client that made example tasks
  while sync was disabled can still see the conflict dialog.

* test(sync): cover fresh-client example-task import gate (e2e)

Add a SuperSync e2e proving a fresh client with first-run example tasks accepts
an incoming SYNC_IMPORT without a conflict dialog, plus a backward-compatible
{ allowExampleTasks } opt-in to createSimulatedClient (the harness otherwise
pre-sets SUP_EXAMPLE_TASKS_CREATED).

Uses waitForInitialSync:false + a race between the conflict dialog and sync
completion so the test actually fails when the dialog appears (pre-fix), and
asserts all four onboarding titles are absent. Guards the op-log isExampleTask
marker/gate path (not the afterInitialSyncDoneStrict$ timing, which a fresh
e2e client cannot exercise since sync is disabled at boot).

* docs(sync): link example-task import-gate limitations to #7985
2026-06-03 15:57:53 +02:00
..
assertions.ts refactor(e2e): simplify improvements per KISS/YAGNI review 2026-01-06 12:46:20 +01:00
check-webdav.ts test(e2e): harden failure signals and provider gates (#7753) 2026-05-23 20:33:04 +02:00
config-helpers.ts fix(sync): harden vector clock sanitization and improve E2E test robustness 2026-02-12 16:27:56 +01:00
e2e-constants.ts perf(e2e): optimize polling intervals in helpers 2026-01-18 15:58:46 +01:00
element-helpers.ts refactor(e2e): extract ensureGlobalAddTaskBarOpen helper to reduce code duplication 2026-01-16 13:35:59 +01:00
index.ts feat(shepherd): remove all tours except keyboard navigation 2026-03-22 17:00:42 +01:00
legacy-migration-helpers.ts test(e2e): dismiss devError native dialogs so sync tests don't hang 2026-05-23 23:13:09 +02:00
runtime-errors.ts test(e2e): dismiss devError native dialogs so sync tests don't hang 2026-05-23 23:13:09 +02:00
schedule-task-helper.ts fix(e2e): fix schedule dialog submit button selector 2026-01-21 14:30:24 +01:00
supersync-assertions.ts test(e2e): fix failing WebDAV and SuperSync E2E tests 2026-03-23 11:07:25 +01:00
supersync-helpers.ts [codex] Fix sync import conflict from startup example tasks (#7976) 2026-06-03 15:57:53 +02:00
sync-helpers.ts test(e2e): dismiss devError native dialogs so sync tests don't hang 2026-05-23 23:13:09 +02:00
time-input-helper.ts refactor(e2e): replace waitForTimeout with condition-based waits 2026-01-03 15:29:38 +01:00
waits.ts test(e2e): harden failure signals and provider gates (#7753) 2026-05-23 20:33:04 +02:00