Repository navigation
feat: add cheetah-grid-playwright package - #474
Merged
Merged
Conversation
🦋 Changeset detectedLatest commit: 4928b7b The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
New workspace package providing Playwright helpers for driving the grid: cells addressed by field/record index, operated with real mouse and keyboard events at coordinates computed via the grid API. Absorbs two timing pitfalls: makeVisibleCell only updates the DOM scroll position (grid state follows on the async scroll event), and cell editors ignore Enter for one macrotask after opening. The FAQ editing example gains the same wait. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the locally declared structural types with a type-only import of the cheetah-grid namespace, and add a build phase to the lint CI job so type checking can resolve the built type definitions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ota-meshi
force-pushed
the
feat/playwright-helper-package
branch
from
August 19, 2026 03:25
78bb167 to
838423d
Compare
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
No concrete use case: the namespace is looked up as window.cheetahGrid, which the UMD bundle defines and ESM apps expose under that name anyway. An option can be reintroduced without breakage if a need appears. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ota-meshi
force-pushed
the
feat/playwright-helper-package
branch
3 times, most recently
from
August 19, 2026 04:26
de4b3e8 to
94df503
Compare
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ota-meshi
force-pushed
the
feat/playwright-helper-package
branch
from
August 19, 2026 04:27
94df503 to
22c4b2d
Compare
The functions passed to evaluate() are serialized per call site, so the namespace lookup, instance resolution, and cell spec resolution were duplicated between rect() and value(). Consolidate them into a single page function dispatching on an op parameter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both the scroll listener and the rAF fallback called grid.unlisten(id), and the core unlisten is not idempotent, so every scroll-inducing operation raised an uncaught TypeError in the page. Tests now assert that no page errors occur during any operation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rect() coordinates were relative to the grid's own frame while page.mouse operates in the top-level viewport, so every click on a grid inside an iframe landed offset. Add the ancestor frame elements' offsets (throwing clearly for cross-origin frames), run fill()'s macrotask wait in the grid's frame, and scope the editor lookup to the grid root. The iframe test is served over HTTP because file: documents are opaque origins in Chrome. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… editor fill() silently reported success when the editor did not open (e.g. a record still loading): the value went into the grid's hidden focus control. Load the record first via the cell value, exclude the focus control from the editor lookup, and throw a clear error when no editor opened. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An out-of-range record index or col/row produced fabricated coordinates: value() returned undefined and click() silently hit unrelated points. Throw a clear error instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The grid's own mouse hit-testing does not compensate for visual scaling, so under an ancestor transform/zoom near cells only worked by error cancellation while farther cells silently missed. Detect the scale mismatch and throw a clear error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CJS TypeScript consumers under node16 resolution could not compile against the package because only .d.mts types were emitted while the require condition pointed at them. Ship a single ESM build instead; the supported Node versions (engines) all handle require(esm). Also update tsdown to ^0.22.14 and export ./package.json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rect() returned only the anchor cell slice for colSpan/rowSpan cells. Resolve the cell range and return the union of the start and end cell rectangles. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On menu editor columns the initial click opens the menu, leaving it open (with focus trapped on a menu item) after the clear error. Press Escape before throwing, and mention non-text editors in the message. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Enter does not guarantee a commit: the built-in SmallDialogInputEditor keeps the dialog open when a validator (possibly asynchronous) rejects the value, while fill() reported success. Poll the outcome after Enter and throw the validation message, cancelling the editing so the dialog does not stay open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The grid only scrolls its own internal viewport, so on pages where the grid sits below the fold (or is taller than the window) every click silently missed: mouse events outside the viewport hit nothing. Scroll the grid into view, scroll the window further to the cell when needed, and fail clearly when the point still cannot be brought into view. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Under scroll-behavior: smooth the programmatic scroll of makeVisibleCell animates: right after the call the scroll position is still the old one, so the scroll-state wait was skipped entirely and coordinates were computed at the old position. Temporarily force scroll-behavior: auto on the grid's scrollable while adjusting. Also group the scroll adjustment into scrollCellIntoView (named apart from the core makeVisibleCell), ordered with the other page helpers by call order. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The descendant search silently picked the first grid in document order, so tests targeting another grid failed confusingly downstream. Throw a clear error instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The center of the whole cell rectangle falls outside the canvas when the cell is larger than the grid viewport (e.g. a column wider than the grid), so clicks silently missed. Compute the click point from the intersection of the cell and the canvas instead; rect() still returns the whole cell rectangle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The shipped artifact depends on cellOperation surviving the build self-contained (it is serialized into the page at runtime), but only the sources were tested. Drive the grid through dist/index.js in the suite, failing fast when the package has not been built. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A missing file: subresource does not fail navigation, so on a fresh clone every test silently burned the 60s hook timeout waiting for a grid that could never appear (9+ minutes with no hint). Check for the cheetahGrid global right after navigation in a shared gotoFixture helper and fail with a message pointing at the build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The eslint files globs omitted .mts, so tsdown.config.mts was silently skipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Aligning the end edge of a cell larger than the grid viewport shoved its start edge off screen on every click. The resulting scroll also closed cell editors right after opening (always in WebKit, where the scroll event arrives after the editor opens; in Chrome when the grid was horizontally scrolled), making such cells impossible to edit in place. Clamp the scroll so the start edge stays in view. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The row-direction clamp for ranges starting in frozen rows used column widths (_getColsWidth with row indices), returning a wrong height for such ranges on vertically scrolled grids. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The click point was only checked against the window viewport, so overflow ancestors, iframe boxes, scaled iframes, and overlaying elements produced silent misclicks, and viewport:null contexts or scroll-behavior:smooth broke the window-scroll retry. Resolve the point page-side instead: walk from the grid's frame to the top window, instantly scrolling every clipping scroll container, frame, and window as needed, rejecting transform-scaled frame elements, and hit-testing the final point so a covering element fails clearly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- cell()/cellAt() now reject non-integer or negative indices synchronously: a negative record index resolved onto header rows, where click() could trigger header actions such as sorting. - The merged-cell rectangle is now taken from getCellRangeRect, which handles ranges spanning the frozen-column boundary; the previous per-cell union mixed coordinate spaces and inverted under scroll, falsely rejecting visible cells. - fill()'s commit-timeout path now closes the editor like the other failure paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fixture server bound to all interfaces and followed .. path traversal, exposing repository files to the local network while the suite runs. Bind to 127.0.0.1 and reject paths escaping the repository root. Also replace the bare TypeError on pages running cheetah-grid < 2.2 with a message naming the required version. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #472. Introduces
cheetah-grid-playwright, a new ESM-only workspace package providing official Playwright helpers for driving the grid. Cells are addressed by field name and record index (or raw col/row indices) and operated with real mouse and keyboard events at coordinates computed through the grid API, so interactions go through the same code path as actual user input.The helpers absorb the pitfalls that make hand-written recipes wrong or flaky, found through adversarial review and verified by reproduction:
makeVisibleCell()(which only moves the DOM scroll position), forcing instant scrolling underscroll-behavior: smooth.fill()loads lazy records first, opens the editor with F2, waits out the editors' Enter guard, and verifies the commit — failing with the validation message when aninputValidatorrejects the value instead of reporting a false success.Tests (23) run against local fixture pages with vitest + Playwright (
channel: "chrome"), including a smoke test of the built artifact (the page function is serialized at runtime, so the shipped file must be exercised). The lint CI job gains a build phase so type checking can resolve the builtcheetah-gridtype definitions.Known limitation, documented in code: the page must expose
window.cheetahGrid(the same module instance that created the grid).This PR also carries two core fixes found through the helper's tests:
makeVisibleCellscrolled the start edge of cells larger than the grid viewport out of view on every click, and the resulting scroll closed cell editors right after opening (always in WebKit, in Chrome when horizontally scrolled), making such cells impossible to edit in place; andgetCellsRectclamped the row direction of ranges starting in frozen rows by column widths instead of row heights.Possible follow-ups (not in this PR): menu editors via a
selectOption-like API, selection ranges, and event waiting helpers.🤖 Generated with Claude Code