Skip to content
cccskills
FreePublished on GitHub

handsontable-playwright-e2e

Create and update Playwright tests that check Handsontable interactions in real browsers. The skill guides test organization, reliable waits, element selection, and coverage across themes and bundles, while helping distinguish browser tests from unit tests.

OriginalShow the original description

Use when writing or modifying real-browser Playwright E2E / functional tests for Handsontable (specs in tests/e2e/, core, wrappers, or walkontable). Covers the Page Object Model, hooking in by data-testid, deterministic web-first waits, wrapper-specific gotchas, recording via the CLI, and the new-vs-modify / E2E-vs-unit decision. NOT for screenshot/visual tests (use visual-testing) or the legacy Jasmine suite (use handsontable-e2e-testing).

Works withPlaywright
See how to install

Good for

  • Test keyboard navigation and cell editing
  • Add regression coverage for a bug fix
  • Check behavior across themes and bundles
  • Migrate legacy Jasmine tests to Playwright

Files included (5)

  • SKILL.md7.8 KB
  • references/codegen.md784 B
  • references/determinism.md4.3 KB
  • references/page-objects.md2.4 KB
  • references/wrappers.md2.0 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Handsontable Playwright E2E authoring

New E2E is Playwright in tests/e2e/ (*.spec.ts). The legacy Jasmine *.spec.js suite is frozen: add new specs only in Playwright. Reference: tests/e2e/grid.spec.ts + tests/fixtures/pages/GridPage.ts.

Where tests run

Locally, run only the specs you created or changed, under the default theme: cd tests && npx playwright test --project=e2e-main e2e/<your-spec>.spec.ts. The Stop hook and pre-push do this automatically. The matrix is theme (main/horizon/classic) × bundle (umd = handsontable.js, full-min = handsontable.full.min.js), six projects, one CI job each (E2E / Playwright <bundle> (theme: …)), but a spec runs on e2e-main only unless every top-level block declares the axes it is sensitive to: { tag: THEMES_TAG } (computed styles, tokens, a theme branch, hit tests, pixel assertions), { tag: BUNDLES_TAG } (HyperFormula, the Formulas plugin, a bundle branch, the load surface), or { tag: [THEMES_TAG, BUNDLES_TAG] }, all from fixtures/test.ts, never as bare strings. A static sweep (tests/lib/__tests__/leg-declarations.test.mjs) refuses a spec that touches such a surface without the tag, and the E2E nightly runs the full matrix on develop. Rules and the ignore grammar: tests/AGENTS.md → "Declaring the legs". Local gates run e2e-main (plain UMD) only. To run all six legs for one spec: HOT_E2E_FULL_MATRIX=1 npx playwright test e2e/<your-spec>.spec.ts (without the variable, npx playwright test e2e/<your-spec>.spec.ts runs the legs the spec declares). Tests tagged @cross-browser ({ tag: CROSS_BROWSER_TAG } from fixtures/test.ts) also run on Firefox and WebKit through playwright-engines.config.ts (one CI job); tag a test whose behavior an engine could get wrong on its own – real keys, pointer gestures, focus, DOM-read layout. tests/AGENTS.md → "The engine legs" has the local command.

Check port 8123 before you believe a local result

webServer uses reuseExistingServer, so Playwright attaches to whatever already listens on 8123 (a worktree beside the main clone, a leftover support/static-server.mjs) and your specs exercise a build you did not make, with no signal in the output.

lsof -nP -i :8123 | grep LISTEN     # empty = free, safe to run

If it is taken and not yours, leave it running (another session may be mid-run) and use your own port:

cd tests && HOT_TEST_PORT=8131 npx playwright test --project=e2e-main e2e/<your-spec>.spec.ts

HOT_TEST_PORT is read by tests/playwright.config.ts and throws on a malformed or empty value. It applies to the functional suite only; the visual suite's port is owned by visual-tests/src/config.mjs plus two hardcoded app.listen(8082) demo servers.

Rebuild both bundles before an all-legs run

build:umd writes dist/handsontable.js only; the -min legs load handsontable.full.min.js from build:umd.min. Run the full task and check both files moved:

npm --prefix handsontable run build
ls -l handsontable/dist/handsontable.js handsontable/dist/handsontable.full.min.js

Read a mixed result per leg: a split along the bundle axis is about the bundles, not timing (stale bundle vs genuine full.min difference: tests/AGENTS.md).

Five rules

  1. Page Object Model. A spec expresses intent; selectors and multi-step flows live in a page object under tests/fixtures/pages/.
  2. Hook by data-testid, not structural CSS. Stamp ids in the fixture (or add them to the component when it removes ambiguity). Fall back to role/text locators before grid internals.
  3. Web-first waits only. await expect(locator).toBeVisible(); await every assertion. Inside a page object the same rule has six shapes lint cannot see (setTimeout in page.evaluate(), a waitForFunction without { polling }, a scroll method that ends on scrollTop, .at(-1) on a separately read log, a fixture build that fails silently, a negative settle with no positive control), spelled out in references/determinism.md.
  4. Isolation. One instance per test; page.route() / page.clock() for network/time. failOnFlakyTests is on in CI: pass-on-retry is a hard failure.
  5. Thread the bundle axis, and declare the legs. Import test from tests/fixtures/test.ts, destructure { page, theme, bundle }, and pass both to the page object. A new fixture copies the fail-loud ?theme=/?bundle= allowlist block from demo/grid.html (no hardcoded bundle <script src=…>). Formulas specs load HyperFormula as an external script in the fixture, and declare BUNDLES_TAG; a spec that reads a computed style, a token or a pixel declares THEMES_TAG, on every top-level block (tests/AGENTS.md → "Declaring the legs"). Never-get-wrong list: tests/AGENTS.md.

Which test

  • User-visible (rendering, interaction, keyboard, menus, overlays) → E2E here.
  • Invisible to users (data, indexing, algorithms) → Jest *.unit.js, still mandatory.
  • Public type surface → a *.types.ts type test in the package whose types changed.
  • Pure refactor / internal non-runtime → no new test; declare Refactor-only: <reason> in the commit.
  • New API / plugin / editor → new spec. Bug fix → a failing case in the closest existing spec.
  • Broken or flaky legacy Jasmine → migrate to Playwright.

Full decision rules: handsontable/.ai/TESTING.md.

Test granular user actions

Handsontable implements the low-level interactions, so target fine-grained actions, not app-level happy paths:

  • Scrolling: wheel, scrollbar drag, keyboard, momentum/inertial; frozen rows/cols and overlays aligned during and after.
  • Pointer: hover (highlights, handles, tooltips), click/dblclick, context menu, drag-to-select, fill-handle drag, column/row resize and move.
  • Keyboard: navigation, range selection, editing, shortcuts, enter/escape commit; IME composition for CJK.
  • Touch: tap, long-press, touch scroll/drag on mobile viewports.
  • Layout: RTL, container resize / ResizeObserver, viewport edges, large-dataset virtualization boundaries.

Overlay-clone gotcha: headers and frozen rows/cols render in several overlay layers (.ht_clone_top, .ht_clone_inline_start, the corner, plus the master), so a data-testid stamped in a renderer or header hook appears more than once. Scope the locator to the overlay (page.locator('.ht_clone_top').getByTestId(...)) or strict mode fails. Unfrozen cells live only in .ht_master.

Perform the action, then assert the exact cell / overlay / selection state. Judge a test by whether it would catch a real bug: test-writing-discipline skill.

Recording

Record with the Playwright CLI (npx playwright codegen), the version-pinned tool installed here, not a Playwright MCP (an unpinned second automation surface, even when one is loaded in the session). Refactor the output into a page object with data-testid selectors before committing.

References

TypeScript style: handsontable/.ai/CONVENTIONS.md.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Develop and modify the Handsontable Angular wrapper with guidance on component lifecycle, settings updates, and NgZone, which controls change detection. It also covers standalone examples, global configuration, and the build and test workflow.

  • Fix settings updates in the Angular wrapper
  • Review change detection around grid operations
  • Update examples to standalone components
handsontable/handsontable22.1KUpdated Oct 19, 2026

Open local or public web pages in BrowserStack Live for checks on real mobile devices or desktop browsers. The skill prepares temporary access to a local server, launches the requested session, and shares its dashboard link.

  • Check a local page on an Android device
  • Open a page in Safari on an iPhone or iPad
  • Inspect behavior in a specific desktop browser
handsontable/handsontable22.1KUpdated Oct 19, 2026

Prepare user-facing changelog entries for source code changes. The skill determines whether an entry is needed, classifies the change, writes a clear title, and uses the project CLI to create a JSON file tied to the pull request.

  • Add a changelog entry for a bug fix
  • Classify a new feature or behavior change
  • Explain a breaking change and its replacement
handsontable/handsontable22.1KUpdated Oct 19, 2026

code-graph

FreeSummary

Explore relationships between functions and files using a prebuilt code graph, a map of code dependencies. Trace bugs, inspect callers and execution paths, and assess the impact of refactoring or proposed changes.

  • Explore callers and dependencies in unfamiliar code
  • Trace a bug across multiple files
  • Assess the impact of renaming or removing code
handsontable/handsontable22.1KUpdated Oct 19, 2026

Work with Handsontable row and column positions by distinguishing source data, displayed order, and rendered cells. It guides index conversion and helps investigate misplaced data when sorting, filtering, hiding, or moving rows and columns.

  • Investigating misplaced rows or columns
  • Converting between source and displayed indexes
  • Combining filters with manual column movement
handsontable/handsontable22.1KUpdated Oct 19, 2026

Create Handsontable documentation examples for JavaScript, TypeScript, React, Angular, and Vue. The skill explains source files, generated JavaScript, required imports and license settings, embedding examples in guides, and checking that each framework version displays correctly.

  • Adding a code example to a feature guide
  • Preparing examples for multiple frameworks
  • Generating JavaScript examples from TypeScript
handsontable/handsontable22.1KUpdated Oct 19, 2026

See all skills by handsontable

Report a problem with this skill