Use when writing Playwright visual regression tests or creating visual test examples for Handsontable - covers the custom tablePage fixture, screenshot workflow, Argos CI integration, and example creation in examples/next/docs/
Visual tests live in visual-tests/ and use Playwright with TypeScript. Screenshots are compared against baselines by Argos CI to detect visual regressions. There are two workflows: (a) add visual tests for existing examples, and (b) create a new example in examples/next/docs/ and write visual tests for it.
tablePageImport the custom test runner instead of the default Playwright test:
import { test } from '../../../src/test-runner';
The tablePage fixture (defined in visual-tests/src/test-runner.ts) automatically:
The fixture provides a standard Playwright Page object, so all Playwright APIs work as expected.
Use __filename as the first argument to test(). The runner auto-generates the test title from the file path. File names should be kebab-case and describe what is being tested (e.g., apply-active-class-name-nested-header.spec.ts).
Every test follows this pattern: perform setup/actions, then capture a screenshot. You can take multiple screenshots per test.
import { test } from '../../../src/test-runner';
import { helpers } from '../../../src/helpers';
import { selectCell } from '../../../src/page-helpers';
test(__filename, async({ tablePage }) => {
const cell = await selectCell(0, 2);
await cell.click();
await tablePage.screenshot({ path: helpers.screenshotPath() });
});
Always use helpers.screenshotPath() for the path argument. It auto-generates unique, deterministic file names based on the test file path, browser, framework, and screenshot index. Using any other naming approach will break Argos CI comparison.
visual-tests/tests/js-only/ -- Tests that run only against the vanilla JS examples.visual-tests/tests/multi-frameworks/ -- Tests that run against JS, React, Angular, and Vue examples.visual-tests/tests/cross-browser/ -- Tests that verify cross-browser rendering consistency.Use test.skip(helpers.hotWrapper !== 'js', '...') to restrict a test to a specific framework.
For tests targeting a specific example (not the default demo), use the goto fixture:
test(__filename, async({ goto, tablePage }) => {
await goto(
helpers.setBaseUrl('/my-custom-demo').getFullUrl()
);
await tablePage.screenshot({ path: helpers.screenshotPath() });
});
visual-tests/src/helpers.ts -- screenshotPath(), selectors (CSS selectors for table parts), findCell(), cssPath().visual-tests/src/page-helpers.ts -- selectCell(), openEditor(), openContextMenu(), createSelection(), openHeaderDropdownMenu(), filterByValue(), filterByCondition(), scrollTableToTheBottom(), takeScreenshot(), and more.Check visual-tests/package.json for available scripts. Configuration files:
visual-tests/playwright.config.ts -- Default config.visual-tests/playwright-cross-browser.config.ts -- Cross-browser config.When creating a new example at examples/next/docs/js/demo/, include:
index.html -- HTML entry point.package.json -- Dependencies (Handsontable, Vite).vite.config.js -- Vite configuration.src/ -- Source files for the example.spec/ -- Spec metadata for the example.helpers.screenshotPath() -- breaks Argos CI screenshot matching.multi-frameworks/ or vice versa.tablePage fixture handles this, but if you use goto to navigate to a different page, animations are still disabled automatically by the fixture.tablePage waits for the table, but dynamic content (menus, dropdowns) may need explicit waits.