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:
Stefan Hildebrandt
2026-07-11 21:15:57 +02:00
parent cdb31634a6
commit e1e83c4a83
6 changed files with 73 additions and 54 deletions
+8 -14
View File
@@ -10,8 +10,7 @@ import {
seedUnifiedSettings,
folderRow,
expectFolderUnread,
expectFolderTotal,
forceSync,
expectFolderCountsSynced,
} from './helpers/app';
/**
@@ -49,18 +48,17 @@ test.describe('Multi-account sync', () => {
await expectFolderUnread(page, { role: 'inbox', name: 'Inbox' }, 2);
await addAccount(page, bob);
await forceSync(page);
// Both accounts are now registered in the switcher.
await accountSwitcher(page).click();
await expect(page.locator('[data-testid="account-option"]')).toHaveCount(2);
await page.keyboard.press('Escape');
// Active = bob: his own Inbox shows 1 unread — alice's 2 don't leak in.
await expectFolderUnread(page, { role: 'inbox', name: 'Inbox' }, 1);
await expectFolderCountsSynced(page, { role: 'inbox', name: 'Inbox' }, { unread: 1 });
// Switch back to alice: her count is intact.
await switchAccount(page, alice.email);
await expectFolderUnread(page, { role: 'inbox', name: 'Inbox' }, 2);
await expectFolderCountsSynced(page, { role: 'inbox', name: 'Inbox' }, { unread: 2 });
});
test('the cross-account Unified Inbox aggregates unread across accounts', async ({ page }) => {
@@ -70,30 +68,26 @@ test.describe('Multi-account sync', () => {
await seedUnifiedSettings(page);
await login(page, alice);
await addAccount(page, bob);
await forceSync(page);
// Unified Inbox = alice(1) + bob(1) = 2. The active account's own Inbox
// (bob) still reports just its own 1.
await expect(folderRow(page, { name: 'unified-inbox' }).first()).toBeVisible();
await expectFolderUnread(page, { name: 'unified-inbox' }, 2);
await expectFolderTotal(page, { name: 'unified-inbox' }, 2);
await expectFolderUnread(page, { role: 'inbox', name: 'Inbox' }, 1);
await expectFolderCountsSynced(page, { name: 'unified-inbox' }, { unread: 2, total: 2 });
await expectFolderCountsSynced(page, { role: 'inbox', name: 'Inbox' }, { unread: 1 });
});
test('a delivery to a background account bumps the Unified Inbox counter', async ({ page }) => {
await seedUnifiedSettings(page);
await login(page, alice);
await addAccount(page, bob); // bob is now the active account
await forceSync(page);
await expectFolderUnread(page, { name: 'unified-inbox' }, 0);
await expectFolderCountsSynced(page, { name: 'unified-inbox' }, { unread: 0 });
// Mail lands in alice's inbox while bob is the active account.
await send(alice, subj('bg'));
await forceSync(page);
// The unified counter reflects the background account's new mail.
await expectFolderUnread(page, { name: 'unified-inbox' }, 1);
await expectFolderCountsSynced(page, { name: 'unified-inbox' }, { unread: 1 });
// bob (active) own Inbox is unaffected.
await expectFolderUnread(page, { role: 'inbox', name: 'Inbox' }, 0);
await expectFolderCountsSynced(page, { role: 'inbox', name: 'Inbox' }, { unread: 0 });
});
});