Files
scrabble-game/ui/e2e/smoke.spec.ts
T
Ilia Denisov 6268b9d2a2
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 43s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m1s
UI: pin the SPA document so iOS/WKWebView cannot rubber-band the page
On iOS (notably the Telegram Mini App) the document elastic-overscrolls on a
vertical drag even with overscroll-behavior:none — the whole page stretches and
bounces, and it fought the board's swipe-to-open-history. Telegram's own
swipe-to-minimise is already disabled at launch; this removes the remaining
WebKit document bounce by pinning the document (position:fixed + overflow:hidden)
for the game SPA only. Every screen already fits the visual viewport (--vvh) and
scrolls its own inner areas, so the document never needed to scroll.

Scoped to the app via an `app-shell` class set in main.ts; the standalone
landing page (landing.ts) keeps its normal scrolling document. e2e locks the
contract on both entries.
2026-06-11 20:43:12 +02:00

48 lines
2.2 KiB
TypeScript

import { expect, test } from './fixtures';
// The playable-slice smoke against the mock transport: guest login -> lobby shows the
// seeded active game -> open it -> the board renders committed tiles -> place a rack
// tile (tap) and see the score preview.
test('guest reaches a board and previews a placement', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: /guest/i }).click();
await expect(page.getByText('Your turn')).toBeVisible();
const activeRow = page.getByRole('button', { name: /Ann/ });
await expect(activeRow).toBeVisible();
await activeRow.click();
// Board renders, including a committed tile from the seeded HELLO play.
await expect(page.locator('[data-cell]').first()).toBeVisible();
await expect(page.locator('[data-cell] .letter', { hasText: 'H' }).first()).toBeVisible();
// Tap a rack tile, then an empty board cell -> a pending tile + score preview.
const rackTile = page.locator('.rack .tile').first();
await rackTile.click();
await page.locator('[data-cell]:not(.filled)').nth(30).click();
await expect(page.locator('[data-cell].pending')).toHaveCount(1);
// The score preview appears where the hints count used to be.
await expect(page.locator('.scores')).toContainText(/\d/);
// The contextual MakeMove control (✅) appears once a tile is pending.
await expect(page.locator('.make')).toBeVisible();
});
// The SPA pins the document so iOS/WKWebView cannot rubber-band the whole page on a vertical
// drag (the elastic bounce that fought the board's swipe-to-open-history). The native bounce
// itself is not reproducible in Playwright, so we assert the CSS contract that suppresses it.
test('the app pins the document so the page cannot rubber-band', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: /guest/i })).toBeVisible();
const lock = await page.evaluate(() => ({
shell: document.documentElement.classList.contains('app-shell'),
htmlOverflow: getComputedStyle(document.documentElement).overflowY,
bodyPosition: getComputedStyle(document.body).position,
}));
expect(lock.shell).toBe(true);
expect(lock.htmlOverflow).toBe('hidden');
expect(lock.bodyPosition).toBe('fixed');
});