|
1 | 1 | import { test, expect } from './fixtures/server' |
2 | 2 | import { groupCard, noteCard } from './fixtures/atlasCards' |
3 | 3 | import { clickCorner, zoomAllTheWayOut } from './fixtures/atlasBoard' |
| 4 | +import { contextMenu } from './fixtures/contextMenu' |
4 | 5 |
|
5 | 6 | // The click model (goal 0102's gesture table) + surface-scoped |
6 | 7 | // shortcuts (goal 0071 slice): plain click selects/replaces, a second |
@@ -42,6 +43,47 @@ test('plain click selects (replacing any prior selection); a second click on the |
42 | 43 | await expect(overlay).not.toBeVisible() |
43 | 44 | }) |
44 | 45 |
|
| 46 | +test('a plain click leaves the selection ring visibly showing on the clicked card while it still holds DOM focus, for a note card and a sticky', async ({ page }) => { |
| 47 | + await page.goto('/') |
| 48 | + await page.getByRole('link', { name: 'Atlas' }).click() |
| 49 | + await expect(page.getByTestId('atlas-board')).toBeVisible() |
| 50 | + |
| 51 | + // Regression: Primer's own [role="button"]:focus:not(:focus-visible) |
| 52 | + // reset zeroes any box-shadow scoped to that inner role="button" |
| 53 | + // element -- exactly the state a plain mouse click leaves the |
| 54 | + // clicked card in (focused, but never :focus-visible from a pointer |
| 55 | + // gesture), which made a single-card selection invisible. The ring |
| 56 | + // must show on the wrapper, immune to that reset, while the card is |
| 57 | + // still focused -- not just once focus moves elsewhere. |
| 58 | + const getting = noteCard(page, 'Getting started') |
| 59 | + await getting.click() |
| 60 | + expect(await page.evaluate(() => document.activeElement?.getAttribute('data-testid'))).toBe('atlas-note-card') |
| 61 | + const cardWrapper = selectedWrapper(page, getting) |
| 62 | + await expect(cardWrapper).toHaveCount(1) |
| 63 | + await expect.poll(() => cardWrapper.evaluate((el) => getComputedStyle(el).boxShadow)).not.toBe('none') |
| 64 | + |
| 65 | + // A sticky note's own, separately-declared (heavier) ring rule. |
| 66 | + const board = page.getByTestId('atlas-board') |
| 67 | + await zoomAllTheWayOut(page) |
| 68 | + await page.keyboard.press('n') |
| 69 | + await clickCorner(board, 'top-right') |
| 70 | + const noteTA = page.getByTestId('atlas-sticky-textarea') |
| 71 | + await noteTA.fill('ZzE2eStickyRing') |
| 72 | + await noteTA.blur() |
| 73 | + const sticky = page.locator('[data-testid="atlas-sticky-note"]') |
| 74 | + await sticky.click() |
| 75 | + expect(await page.evaluate(() => document.activeElement?.getAttribute('data-testid'))).toBe('atlas-sticky-note') |
| 76 | + const stickyWrapper = page.locator('.react-flow__node.selected').filter({ has: sticky }) |
| 77 | + await expect(stickyWrapper).toHaveCount(1) |
| 78 | + await expect.poll(() => stickyWrapper.evaluate((el) => getComputedStyle(el).boxShadow)).not.toBe('none') |
| 79 | + |
| 80 | + // Cleanup (testing.md's within-file discipline). |
| 81 | + const menu = contextMenu(page) |
| 82 | + await sticky.click({ button: 'right' }) |
| 83 | + await menu.getByText('Delete note', { exact: true }).click() |
| 84 | + await expect(sticky).toHaveCount(0) |
| 85 | +}) |
| 86 | + |
45 | 87 | test('a real double-click reproduces the same select-then-commit outcome as two plain clicks, for both a leaf and a frame body', async ({ page }) => { |
46 | 88 | await page.goto('/') |
47 | 89 | await page.getByRole('link', { name: 'Atlas' }).click() |
|
0 commit comments