test(e2e): robustness — stable locators, exact assertions, no fixed sleep
- ContextSheet: add data-testid="context-sheet". longpress tests targeted the open sheet via the `.translate-y-0` animation class (breaks on any animation refactor) — now target `[data-testid="context-sheet"][aria-modal="true"]`, which is stable and unambiguous vs. the centered LightboxModal (also aria-modal). - toast-on-failure: the like button was `button.filter(hasText:/\d+/).first()`, which could match any digit-bearing button (e.g. the comment count) → use the stable aria-label "Gefällt mir". - config stats: assert the exact user_count (4 = 3 seeded guests + admin) instead of `>= 3` — deterministic after the per-test truncate, catches under/overcount. - offline-network 429 test: replace the fixed 3s waitForTimeout with a poll-until-the-retry-count-stabilizes (faster, and a real storm never stabilizes → the poll fails, which is the intended outcome). Note: reviewed the "config restore not in try/finally" finding — it's a non-issue. The truncate auto-fixture wipes+reseeds the whole config table (and clears the rate limiter) before every test, so config state cannot leak between tests. All affected specs verified green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,13 +45,11 @@ test.describe('Mobile — long-press gesture', () => {
|
||||
|
||||
await longPress(page, card, 600);
|
||||
|
||||
// The ContextSheet renders a dialog with role="dialog" + aria-modal="true".
|
||||
// Multiple sheets (UploadSheet, ContextSheet) may be in the DOM — match the
|
||||
// one that actually has aria-modal=true (i.e. the open one).
|
||||
// ContextSheet is always mounted (it just translates off-screen when closed).
|
||||
// Match the OPEN state by the `translate-y-0` class the component applies
|
||||
// when `open === true`.
|
||||
const sheet = page.locator('[role="dialog"][aria-modal="true"].translate-y-0');
|
||||
// The ContextSheet is always mounted (it translates off-screen when closed).
|
||||
// Target it by its stable data-testid, gated on aria-modal="true" which the
|
||||
// component sets only while open — unambiguous vs. the centered LightboxModal
|
||||
// (which also has aria-modal) and independent of the animation classes.
|
||||
const sheet = page.locator('[data-testid="context-sheet"][aria-modal="true"]');
|
||||
await expect(sheet).toBeVisible({ timeout: 2_000 });
|
||||
await expect(sheet.getByRole('button', { name: /abbrechen/i })).toBeVisible();
|
||||
});
|
||||
@@ -68,10 +66,9 @@ test.describe('Mobile — long-press gesture', () => {
|
||||
// Simulate a short press (200 ms — well under the 500 ms threshold).
|
||||
await longPress(page, card, 200);
|
||||
|
||||
// Within 1 s, no aria-modal=true dialog should be open (the ContextSheet
|
||||
// is "open" only when its aria-modal flag is true).
|
||||
// The ContextSheet stays mounted but `translate-y-0` is only set when open.
|
||||
await expect(page.locator('[role="dialog"][aria-modal="true"].translate-y-0')).toHaveCount(0, { timeout: 1_000 });
|
||||
// Within 1 s, the ContextSheet must not be open (aria-modal is set only when
|
||||
// open). A quick tap opens the lightbox instead, which is a different element.
|
||||
await expect(page.locator('[data-testid="context-sheet"][aria-modal="true"]')).toHaveCount(0, { timeout: 1_000 });
|
||||
});
|
||||
|
||||
test('long-press suppresses the click that lands at pointerup (no double-open of lightbox)', async ({ page, guest, signIn }) => {
|
||||
|
||||
Reference in New Issue
Block a user