diff --git a/e2e/tests/sync/supersync-archive-conflict.spec.ts b/e2e/tests/sync/supersync-archive-conflict.spec.ts index 2b738507bb..6d78366117 100644 --- a/e2e/tests/sync/supersync-archive-conflict.spec.ts +++ b/e2e/tests/sync/supersync-archive-conflict.spec.ts @@ -9,6 +9,7 @@ import { renameTask, archiveDoneTasks, expectTaskInWorklog, + hasTaskInWorklog, navigateToWorkView, type SimulatedE2EClient, } from '../../utils/supersync-helpers'; @@ -267,10 +268,30 @@ test.describe('@supersync Archive Conflict Resolution', () => { console.log('[BugB] Client B: task not visible in active list'); // ============ PHASE 7: Verify task IN worklog ============ - await expectTaskInWorklog(clientA, taskName); + // After archive-wins conflict + sync rounds, the archived task may appear under + // either the original title (if archive applied first) or the renamed title (if + // the rename op was also synced). Accept either to avoid brittleness. + const clientAFound = + (await hasTaskInWorklog(clientA, taskName)) || + (await hasTaskInWorklog(clientA, taskRenamed)); + if (!clientAFound) { + throw new Error( + `[BugB] Client A: Expected task to be in worklog under "${taskName}" or "${taskRenamed}"`, + ); + } console.log('[BugB] Client A: task found in worklog'); - await expectTaskInWorklog(clientB, taskName); + // Client B applied the rename locally before archive was received, so the task + // is archived under the renamed title. But also accept the original in case the + // archive was applied before the rename reached Client B. + const clientBFound = + (await hasTaskInWorklog(clientB, taskRenamed)) || + (await hasTaskInWorklog(clientB, taskName)); + if (!clientBFound) { + throw new Error( + `[BugB] Client B: Expected task to be in worklog under "${taskRenamed}" or "${taskName}"`, + ); + } console.log('[BugB] Client B: task found in worklog'); console.log('[BugB] ✓ Test B passed: LWW Update did not resurrect archived task'); diff --git a/e2e/tests/sync/supersync.spec.ts b/e2e/tests/sync/supersync.spec.ts index b078240a3b..63ed7fa2a9 100644 --- a/e2e/tests/sync/supersync.spec.ts +++ b/e2e/tests/sync/supersync.spec.ts @@ -672,8 +672,9 @@ test.describe('@supersync SuperSync E2E', () => { await saveAndGoHomeBtn.click(); console.log('[Archive Test] Client B clicked Save and go home (archiving)'); - // Wait for navigation back to work view - await clientB.page.waitForURL(/tag\/TODAY/, { timeout: 10000 }); + // Wait for navigation back to work view. + // Use negative lookahead to avoid matching /tag/TODAY/daily-summary prematurely. + await clientB.page.waitForURL(/(tag\/TODAY(?!\/daily-summary))/, { timeout: 10000 }); await clientB.page.waitForLoadState('networkidle'); console.log('[Archive Test] Client B back on work view after archiving'); diff --git a/e2e/utils/supersync-helpers.ts b/e2e/utils/supersync-helpers.ts index f824347100..5d7ffd404f 100644 --- a/e2e/utils/supersync-helpers.ts +++ b/e2e/utils/supersync-helpers.ts @@ -501,6 +501,10 @@ export const markTaskDone = async ( const task = getTaskElement(client, taskName); await task.hover(); await task.locator('done-toggle').click(); + // Wait for the 200ms animation delay in toggleDoneWithAnimation to complete. + // During CDK drag animation the task may temporarily resolve to 2 elements; + // use .first() to avoid strict-mode violations. + await expect(task.first()).toHaveClass(/isDone/, { timeout: UI_VISIBLE_TIMEOUT }); }; /** @@ -517,6 +521,8 @@ export const markSubtaskDone = async ( const subtask = getSubtaskElement(client, subtaskName); await subtask.hover(); await subtask.locator('done-toggle').click(); + // Wait for the 200ms animation delay in toggleDoneWithAnimation to complete + await expect(subtask).toHaveClass(/isDone/, { timeout: UI_VISIBLE_TIMEOUT }); }; /**