From 3dd4f64cb27d608fd8d74204e61a5c4126bfd5ca Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Tue, 14 Apr 2026 01:22:21 +0200 Subject: [PATCH] test: remove obsolete mobile-swipe-delete.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The file tested a Fase 2b.5 interaction — full-swipe commits a delete with an undo toast — that Fase 5.10 replaced. Swipes on the list detail view are now a symmetric check/uncheck toggle; delete lives in the double-tap overlay and in selection mode. The two tests were describe.skip'd since Fase 5.10 and the UX they describe doesn't exist anymore. The swipe-toggle gesture that replaced it is still untested at the E2E level because Chromium touch emulation can't drive pointer/touch events into Svelte's component handlers reliably. Adding `playwright install webkit` to CI would unblock a fresh `mobile-swipe-toggle.test.ts` with M-06 swipe-right-check, M-07 swipe-left-uncheck, and M-08 wrong- direction snapback. Noted in plan/fase-5-mobile-ux.md §5.10.b. Verification just test-all → 228 green, 2 skipped (both are the upstream Realtime presence bug in realtime-presence.test.ts; everything else passes). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../web/tests/e2e/mobile-swipe-delete.test.ts | 127 ------------------ 1 file changed, 127 deletions(-) delete mode 100644 apps/web/tests/e2e/mobile-swipe-delete.test.ts diff --git a/apps/web/tests/e2e/mobile-swipe-delete.test.ts b/apps/web/tests/e2e/mobile-swipe-delete.test.ts deleted file mode 100644 index bee4491..0000000 --- a/apps/web/tests/e2e/mobile-swipe-delete.test.ts +++ /dev/null @@ -1,127 +0,0 @@ -/** - * M-series (swipe-delete) — Fase 5.4 + 5.5 - * - * On a touch/mobile viewport, swiping a shopping item left reveals the red - * delete zone. A full swipe commits; an Undo toast appears for 4 seconds and - * restores the row if tapped. - */ -import { test, expect, devices } from '@playwright/test'; -import { USERS } from '../fixtures/users.js'; -import { loginAs } from '../fixtures/login.js'; - -// Use chromium with iPhone 13 viewport + touch emulation (we don't ship webkit -// via Playwright install; chromium-with-touch is enough to exercise pointer+touch). -const IPHONE = devices['iPhone 13']; -const SEED_LIST_PATH = '/lists/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'; - -test.use({ - viewport: IPHONE.viewport, - userAgent: IPHONE.userAgent, - deviceScaleFactor: IPHONE.deviceScaleFactor, - hasTouch: true, - isMobile: true -}); - -/* - * These two tests exercise raw `touchstart`/`touchmove`/`touchend` dispatches - * under Chromium's touch emulation. In practice the emulated events don't - * consistently reach the component's PointerEvent handlers — the real UX works - * (verified in DevTools "Device Mode") but Playwright Chromium touch emulation - * is not expressive enough to drive the full gesture reliably. WebKit (real - * iOS Safari engine) handles this correctly but isn't shipped with the current - * install. Re-enable when we add `playwright install webkit` to CI. - * - * The red-zone swipe-delete logic itself is implemented in - * `/lists/[id]/+page.svelte` (SWIPE_COMMIT_THRESHOLD + scheduleUndoable) and - * covered functionally by the D-04 desktop hover-delete test plus the unit - * tests in `src/lib/sync/undoQueue.test.ts`. - */ -test.describe.skip('Mobile swipe-delete with undo toast', () => { - test.beforeEach(async ({ page }) => { - await loginAs(page, USERS.borja); - }); - - test('M-06: swipe-left reveals the red delete zone', async ({ page }) => { - await page.goto(SEED_LIST_PATH); - // Add a disposable item so we don't depend on seed state. - const name = `swipe-${Date.now()}`; - await page.getByPlaceholder(/add item|añadir producto/i).fill(name); - await page.getByPlaceholder(/add item|añadir producto/i).press('Enter'); - const row = page.locator('[role="listitem"]').filter({ hasText: name }); - await expect(row).toBeVisible({ timeout: 5_000 }); - - // Simulate a touch swipe-left of ~80px - const box = await row.boundingBox(); - if (!box) throw new Error('row has no bounding box'); - const startX = box.x + box.width - 20; - const y = box.y + box.height / 2; - await page.touchscreen.tap(startX, y); - await page.mouse.move(startX, y); - await page.dispatchEvent( - `[role="listitem"]:has-text("${name}")`, - 'touchstart', - { touches: [{ clientX: startX, clientY: y }] } - ); - await page.dispatchEvent( - `[role="listitem"]:has-text("${name}")`, - 'touchmove', - { touches: [{ clientX: startX - 90, clientY: y }] } - ); - - // The row now exposes the red zone with an accessible label - await expect( - row.getByRole('button', { name: /delete item|eliminar producto/i }) - ).toBeVisible({ timeout: 3_000 }); - - // Clean up: release and tap outside - await page.dispatchEvent( - `[role="listitem"]:has-text("${name}")`, - 'touchend', - { touches: [] } - ); - }); - - test('M-07: committing the swipe-delete shows an Undo toast that restores the row', async ({ - page - }) => { - await page.goto(SEED_LIST_PATH); - const name = `undo-${Date.now()}`; - await page.getByPlaceholder(/add item|añadir producto/i).fill(name); - await page.getByPlaceholder(/add item|añadir producto/i).press('Enter'); - const row = page.locator('[role="listitem"]').filter({ hasText: name }); - await expect(row).toBeVisible({ timeout: 5_000 }); - - // Fire the delete action via the exposed red-zone button (test ergonomic - // shortcut; the real gesture is covered by M-06). - const box = await row.boundingBox(); - if (!box) throw new Error('row has no bounding box'); - await page.dispatchEvent( - `[role="listitem"]:has-text("${name}")`, - 'touchstart', - { touches: [{ clientX: box.x + box.width - 20, clientY: box.y + box.height / 2 }] } - ); - await page.dispatchEvent( - `[role="listitem"]:has-text("${name}")`, - 'touchmove', - { touches: [{ clientX: box.x - 200, clientY: box.y + box.height / 2 }] } - ); - await page.dispatchEvent( - `[role="listitem"]:has-text("${name}")`, - 'touchend', - { touches: [] } - ); - - // Row disappears, toast shows up - await expect( - page.locator('[role="listitem"]').filter({ hasText: name }) - ).toHaveCount(0, { timeout: 5_000 }); - const toast = page.getByTestId('undo-toast'); - await expect(toast).toBeVisible({ timeout: 3_000 }); - await toast.getByRole('button', { name: /undo|deshacer/i }).click(); - - // Row comes back - await expect( - page.locator('[role="listitem"]').filter({ hasText: name }) - ).toBeVisible({ timeout: 5_000 }); - }); -});