Stage 17 (#3,#5,#10): hover-hold drag zoom, always-editable profile, drag-back + double-tap recall
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 27s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 56s

- Board drag now auto-zooms toward a cell after holding the tile over it ~1s (#3).
- Profile is inline-editable: drop the Edit/Cancel toggle, form is always shown
  for durable accounts; hint balance stays read-only; re-populate after link/merge (#5).
- A pending tile recalls by double-tap (same cell) or by dragging it back onto the
  rack (unzoomed board); a single tap no longer recalls (#10).
- e2e: lock double-tap recall + single-tap no-op; drop the removed Edit-profile click.
This commit is contained in:
Ilia Denisov
2026-06-06 14:42:09 +02:00
parent 4fd82335db
commit 1bbf0bc654
6 changed files with 171 additions and 90 deletions
+19
View File
@@ -29,6 +29,25 @@ test('placing a tile and confirming via ✅ commits the move', async ({ page })
await expect(page.locator('.make')).toBeHidden();
});
test('a pending tile recalls on double-tap, not on a single tap', async ({ page }) => {
await openGame(page);
await page.locator('.rack .tile').first().click();
await page.locator('[data-cell]:not(.filled)').nth(30).click();
await expect(page.locator('[data-cell].pending')).toHaveCount(1);
// A single tap must NOT recall it (changed in Stage 17 — recall was too easy to trigger).
await page.waitForTimeout(350); // clear the double-tap window from the placing tap
await page.locator('[data-cell].pending').first().click();
await expect(page.locator('[data-cell].pending')).toHaveCount(1);
// A double-tap (two synchronous clicks on the same cell) recalls it to the rack.
await page.locator('[data-cell].pending').first().evaluate((el: HTMLElement) => {
el.click();
el.click();
});
await expect(page.locator('[data-cell].pending')).toHaveCount(0);
});
test('history slides the board down and closes on a board tap', async ({ page }) => {
await openGame(page);
await page.locator('.burger').click();
-2
View File
@@ -54,7 +54,6 @@ test('profile edit saves a new display name', async ({ page }) => {
await loginLobby(page);
await page.locator('.burger').first().click();
await page.getByRole('button', { name: /Profile/ }).click();
await page.getByRole('button', { name: /Edit profile/ }).click();
await page.locator('.edit input').first().fill('Kaya Test');
await page.getByRole('button', { name: /^Save$/ }).click();
await expect(page.locator('.name')).toHaveText('Kaya Test');
@@ -127,7 +126,6 @@ test('profile edit disables Save and flags an invalid display name', async ({ pa
await loginLobby(page);
await page.locator('.burger').first().click();
await page.getByRole('button', { name: /Profile/ }).click();
await page.getByRole('button', { name: /Edit profile/ }).click();
const name = page.locator('.edit input').first();
const save = page.getByRole('button', { name: /^Save$/ });