test: remove obsolete mobile-swipe-delete.test.ts

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) <noreply@anthropic.com>
This commit is contained in:
2026-04-14 01:22:21 +02:00
parent a86b296ecd
commit 3dd4f64cb2

View File

@@ -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 });
});
});