diff --git a/src/admin/e2e/features.e2e.ts b/src/admin/e2e/features.e2e.ts index 493f738..51eb481 100644 --- a/src/admin/e2e/features.e2e.ts +++ b/src/admin/e2e/features.e2e.ts @@ -29,13 +29,17 @@ test('creating a feature adds it to the table and its toggle can be flipped', as const toggle = row.locator('input[type="checkbox"]'); const wasChecked = await toggle.isChecked(); + // Assert on the real PATCH landing, not just the switch's transient DOM state: if the + // feature-state map hasn't loaded for this row yet, the click handler no-ops silently and + // the switch briefly flashes the native checkbox state before Vue snaps it back - which + // reads as "toggled" for an instant even though nothing was ever sent to the API. + const patchResponse = page.waitForResponse( + (res) => res.request().method() === 'PATCH' && res.url().includes('/featurestate/') && res.ok(), + ); await toggle.click({ force: true }); + await patchResponse; await expect(toggle).toBeChecked({ checked: !wasChecked }); - // The click's own toggle-state PUT is async; wait for it to land before reloading, - // otherwise the reload can race it and read back the pre-toggle value. - await page.waitForLoadState('networkidle'); - // Reload to confirm the toggle was persisted to the real API/DB, not just local state. await page.reload(); const reloadedRow = page.getByRole('row', { name: new RegExp(featureName) });