test(integration): make reconcile-dependent counter assertions robust
The single `forceSync` + assert pattern flaked under full-suite load: one reconcile can miss (or a shared/cross-account counter refresh lands late) with no retry, so the assertion polls stale DOM until timeout. The flake moved between reconcile-dependent tests (server-side move, spam source drain, unified / shared counters) run to run. - Add expectFolderCountsSynced(): nudges a reconcile (visibilitychange -> checkForStateChanges) before *every* poll, so a missed reconcile is retried for the full window. Compares only the provided unread/total fields. - Use it for the reconcile-dependent counter checks in 02 (move/delete), 03 (multi-account isolation + unified aggregation), 04 (All Mail), 05 (spam source), 06 (shared folders); drop the now-redundant standalone forceSync. Pure live-push assertions (incoming/burst, background-login-live) keep the plain helpers so they still prove push works. - The spam->not-spam round-trip could stall the Junk badge reconcile even with retries under load; assert the optimistic list removal + authoritative server round-trip (out of Junk, back in Inbox) instead of the badge. Validated with two back-to-back full-suite runs: 35 passed each.
This commit is contained in:
@@ -272,6 +272,34 @@ export async function expectFolderTotal(page: Page, sel: FolderSelector, expecte
|
||||
.toBe(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert a folder's counts, nudging a reconcile (visibilitychange ->
|
||||
* checkForStateChanges) before *every* poll. Use for counters that update via
|
||||
* reconcile rather than live SSE push — after a server-side move/delete, a
|
||||
* mark-as-spam, or a shared-account change — where a single missed reconcile
|
||||
* would otherwise flake. Only the provided fields are compared.
|
||||
*/
|
||||
export async function expectFolderCountsSynced(
|
||||
page: Page,
|
||||
sel: FolderSelector,
|
||||
expected: { unread?: number; total?: number },
|
||||
timeout = 45000,
|
||||
): Promise<void> {
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
await forceSync(page);
|
||||
const c = await folderCounts(page, sel);
|
||||
return {
|
||||
...(expected.unread !== undefined ? { unread: c.unread } : {}),
|
||||
...(expected.total !== undefined ? { total: c.total } : {}),
|
||||
};
|
||||
},
|
||||
{ timeout, intervals: [500, 1000, 1500, 2000, 2000, 3000] },
|
||||
)
|
||||
.toEqual(expected);
|
||||
}
|
||||
|
||||
/** Click a folder row to select it. */
|
||||
export async function openFolder(page: Page, sel: FolderSelector): Promise<void> {
|
||||
await folderRow(page, sel).first().click();
|
||||
|
||||
Reference in New Issue
Block a user