-
Notifications
You must be signed in to change notification settings - Fork 2.2k
chore(test): vitest migration #9969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+19,760
−7,285
Merged
Changes from 7 commits
Commits
Show all changes
146 commits
Select commit
Hold shift + click to select a range
9109505
RFC: Migrate from tape to vitest
chrisgervang 659c49f
RFC: Add multi-environment architecture and expanded implementation plan
chrisgervang ee46a47
RFC: Add @deck.gl/test-utils deprecation timeline
chrisgervang 04b8519
chore(test): add vitest infrastructure
chrisgervang 718a052
chore(test): add tape-to-vitest migration script
chrisgervang 4949e46
chore(test): convert test files from tape to vitest
chrisgervang d632932
chore(test): add TODO for typed array equality tester removal
chrisgervang 541f0c1
chore(test): remove obsolete gpu-grid-layer test
chrisgervang 3b187e2
chore(test): convert spy.called to vitest toHaveBeenCalled()
chrisgervang fd05149
chore: ignore yarn engine checks for vitest dependencies
chrisgervang 8c1954a
chore(test): remove unused describe imports from vitest conversions
chrisgervang 47e1d61
chore: ignore vite.config.local.mjs in eslint
chrisgervang 14d3c7c
chore(test): convert t.pass() to console.log() in vitest migration
chrisgervang f14ccae
chore(test): handle test.skip and test.only in vitest migration
chrisgervang 9e75ff6
fix(test): preserve assertion message in assert callback conversion
chrisgervang c2955bb
chore(test): handle expression body arrow functions in migration
chrisgervang 2f77513
fix(ci): install Playwright browsers and use headless project
chrisgervang c8eef73
fix(test): exclude tests that were not in original CI suite
chrisgervang cfffba1
chore(test): restructure test commands with vitest projects
chrisgervang b0280a0
docs(rfc): update vitest migration RFC with implementation details
chrisgervang 84ff56c
fix(test): convert makeSpy to vi.spyOn for browser compatibility
chrisgervang 4a35838
fix(test): convert spy.restore/reset to mockRestore/mockReset
chrisgervang f2402ce
fix(test): convert spy.called to toHaveBeenCalled matcher
chrisgervang e95ae27
fix(test): handle nested t.test() conversion in migration script
chrisgervang d616d74
fix(test): address diff comment issues
chrisgervang cc69f73
chore(test): add manual fix skip list to migration script
chrisgervang 6161023
fix(test): convert spy.callCount to toHaveBeenCalledTimes
chrisgervang fd9930c
fix(test): pass message to expect assertions for better error messages
chrisgervang 8fce5f5
fix(test): convert spy.callCount to toHaveBeenCalledTimes in terrain …
chrisgervang 4766b53
chore(test): exclude tests that were commented out on master
chrisgervang 7054272
feat(test): add browser commands for vitest test runner
chrisgervang a9edc69
feat(test): add interaction and render test specs for vitest
chrisgervang b1e947f
docs: update CONTRIBUTING and RFC with vitest migration progress
chrisgervang a4ffad0
chore(deps): add image comparison dependencies for vitest
chrisgervang facc654
fix(scripts): remove unused fullCall variable in migration script
chrisgervang 354485a
fix(test): add await detection for testLayerAsync and exclude failing…
chrisgervang a14cd26
fix(test): rename jupyter-widget utility file to not have .spec suffix
chrisgervang ed053cc
fix(test-utils): use mockRestore instead of mockClear for spy cleanup
chrisgervang cea4d17
chore(test): reduce verbose logging and use TAP for CI
chrisgervang 8bcb3ee
RFC: Migrate from tape to vitest
chrisgervang d44d9d5
RFC: Add multi-environment architecture and expanded implementation plan
chrisgervang 237a9f6
RFC: Add @deck.gl/test-utils deprecation timeline
chrisgervang 7750fed
RFC: Update CLI commands and finalize Phase 4 discovery outcome
chrisgervang a30500c
fix(test-utils): enable es2022 for top-level await support
chrisgervang 5e4683f
chore: merge chr/tape-to-vitest into chr/vitest-setup
chrisgervang d5a9bbf
feat(test-utils): add backward compatibility for tape/probe.gl users
chrisgervang c711bb8
fix(vitest): pre-bundle dependencies to prevent CI flakiness
chrisgervang 6c04566
ci: split test steps for better visibility
chrisgervang ad34130
ci: use npx for vitest commands
chrisgervang 16b3e9d
fix(test-utils): make spy framework initialization lazy
chrisgervang 305668e
fix(test-utils): enable test-utils import in Node with NullDevice fal…
chrisgervang beb5176
feat(test-utils): add Injectable Spy API for framework-agnostic testing
chrisgervang ae7e43f
RFC: Migrate from tape to vitest
chrisgervang b4d166d
RFC: Add multi-environment architecture and expanded implementation plan
chrisgervang 8c8ed22
RFC: Add @deck.gl/test-utils deprecation timeline
chrisgervang ec43806
RFC: Update CLI commands and finalize Phase 4 discovery outcome
chrisgervang bb7a6a5
RFC: Add injectable spy API, Phase 5 outcome, and Phase 7
chrisgervang 5443914
Merge branch 'origin/chr/tape-to-vitest' into chr/vitest-setup
chrisgervang e8aa70c
chore(test): add createSpy to all testLayer calls (migration script o…
chrisgervang 2ab06f0
chore(test): separate render tests into dedicated vitest project
chrisgervang a6acf0c
chore(test): fix test-render script and add separate entry points
chrisgervang 4f7be42
chore(test-utils): add vi.spyOn default to vitest entry point
chrisgervang 1f8ff88
chore(test): update migration script to use @deck.gl/test-utils/vitest
chrisgervang 5002217
chore(test): migrate unit tests to @deck.gl/test-utils/vitest
chrisgervang 329e6cc
chore(test): update core-layers.node.spec.ts to use vitest entry
chrisgervang 8250c0f
chore(test): remove old tape/probe.gl test entry points
chrisgervang f067e09
chore(test): convert interaction tests to native vitest browser mode
chrisgervang de68ae4
chore(test): include interaction tests in headless project
chrisgervang 875b0c4
chore(test): convert render tests to native vitest with test.each
chrisgervang c406bc3
chore(test): fix render test layer loading and use tap reporter
chrisgervang 0eb3d30
chore(test): add views, effects, and useDevicePixels support to rende…
chrisgervang c84c896
chore(test): fix render test timeouts with absolute URLs and new Deck…
chrisgervang 959390b
chore(test): add skip support for render tests and skip timeout tests
chrisgervang 4b88f59
RFC: Migrate from tape to vitest
chrisgervang 16437f1
RFC: Add multi-environment architecture and expanded implementation plan
chrisgervang 4579dfb
RFC: Add @deck.gl/test-utils deprecation timeline
chrisgervang f860847
RFC: Update CLI commands and finalize Phase 4 discovery outcome
chrisgervang 7119e0f
RFC: Add injectable spy API, Phase 5 outcome, and Phase 7
chrisgervang 0a646af
Merge remote-tracking branch 'origin/chr/tape-to-vitest' into chr/vit…
chrisgervang f8a9a0b
fix(test): fix collision-filter-effect test expectation
chrisgervang d127bda
fix(test-utils): make @probe.gl/test-utils a required peer dependency
chrisgervang ac1293a
fix(test): use mockClear instead of mockReset for spy.reset conversion
chrisgervang 119252b
chore(test): use @deck.gl/test-utils/vitest entry point for all spec …
chrisgervang 0c3fa68
fix(test): correctly convert t.throws regex matchers to toThrow()
chrisgervang 972be68
chore(test): add tap-spec formatter for prettier test output
chrisgervang 2b7bf5e
chore(ci): upload render test failure images as artifacts
chrisgervang 394fe75
chore(test): update golden images for mvt-layer and post-process-effects
chrisgervang 6becbcd
RFC: Migrate from tape to vitest
chrisgervang d2f2f23
RFC: Add multi-environment architecture and expanded implementation plan
chrisgervang 8a60964
RFC: Add @deck.gl/test-utils deprecation timeline
chrisgervang c8e9bd9
RFC: Update CLI commands and finalize Phase 4 discovery outcome
chrisgervang ed2dece
RFC: Add injectable spy API, Phase 5 outcome, and Phase 7
chrisgervang a999c4b
Merge branch 'chr/tape-to-vitest' into chr/vitest-setup
chrisgervang 2763739
chore(test): restore coverage TODO and run migration script
chrisgervang 754737e
fix(test): add dblclick support to browser emulateInput command
chrisgervang 907474f
chore(test): replace tap-spec with vitest default reporter
chrisgervang 6b9de2f
fix(test): improve modifier key handling for dblclick events
chrisgervang 33ec6d6
RFC: Migrate from tape to vitest
chrisgervang 7437439
RFC: Add multi-environment architecture and expanded implementation plan
chrisgervang 1121bc5
RFC: Add @deck.gl/test-utils deprecation timeline
chrisgervang 1bcda33
RFC: Update CLI commands and finalize Phase 4 discovery outcome
chrisgervang d2c9f78
RFC: Add injectable spy API, Phase 5 outcome, and Phase 7
chrisgervang b2970ad
refactor(test): split render tests into individual spec files
chrisgervang 3ab80db
fix(test): fix timeline render tests by reusing Deck instance
chrisgervang fe58fe9
fix(test): unskip scatterplot-transition-3 and transition-4 tests
chrisgervang 7f083a7
revert(test): restore original arc-lnglat and gridcell-lnglat golden …
chrisgervang d81014e
Merge branch 'origin/chr/tape-to-vitest' into chr/vitest-setup
chrisgervang 8619d9f
chore: remove --ignore-engines and add playwright postinstall
chrisgervang 39e5275
feat(test): upgrade vitest from 2.x to 4.x
chrisgervang 3cc0944
fix(test): disable isolation and file parallelism for browser tests
chrisgervang 5fdc63a
fix(test): configure viewport via playwright contextOptions for vites…
chrisgervang fb0c44a
fix(test): exclude flaky tests that fail with isolate: false in CI
chrisgervang 411746c
chore(ci): simplify CI workflow and re-enable coverage
chrisgervang df2f530
fix(test-utils): update vitest peer dependency to ^4.0.18
chrisgervang 5a537d4
fix(test-utils): mark @probe.gl/test-utils peer dependency as optional
chrisgervang 66d9959
feat(scripts): add jscodeshift-based tape-to-vitest codemod
chrisgervang ec78fd2
fix(scripts): improve tape-to-vitest codemod transform
chrisgervang a752446
fix(test): correctly pass expected error to toThrow() assertions
chrisgervang 9f43b37
docs(test): add comprehensive TEST-STATUS.md and fix test scripts
chrisgervang 35a33c7
fix(scripts): detect 3-arg t.ok pattern as equality assertion
chrisgervang 03b09b9
fix(test): re-enable mvt-layer tests after await fix
chrisgervang 4bd8dea
docs(test): update TEST-STATUS.md after mvt-layer fix
chrisgervang 02d1726
fix(test-utils): require @probe.gl/test-utils peer dependency
chrisgervang 82f9dcb
fix(test-utils): add @probe.gl/test-utils to root devDependencies
chrisgervang 05614bf
refactor(test): DRY up screenshot logic in deck-test-utils
chrisgervang 51b411d
chore(test-utils): remove completed TODO comment
chrisgervang 701afe0
Merge branch 'master' into chr/vitest-setup
chrisgervang fe8ea26
refactor(test-utils): Add resetSpy callback and extract shared utilities
chrisgervang ce9016e
fix(test-utils): Remove unused imports from setup-gl.ts
chrisgervang 9584d2e
fix(test-utils): Add async cleanup to prevent luma.gl unhandled rejec…
chrisgervang 0eb0a50
fix(test): Re-enable carto-raster-tile tests and document excluded tests
chrisgervang 93bde3e
fix(test): Exclude render tests from browser project and fix vitest d…
chrisgervang 3131d3a
fix(codemod): Use vitest entry point for utility file fixture
chrisgervang e70e2a3
refactor(test): Use import.meta.dirname for modern Node.js
chrisgervang 79bc238
chore: Merge master into chr/vitest-setup
chrisgervang e2add2c
Merge branch 'master' into chr/vitest-setup
ibgreen 01efe7c
rebase-cleanup
ibgreen c6d7b1b
fixes
ibgreen 7eb0a2f
tape-compat
ibgreen b5eb8bd
Enabled skipped test cases and files
ibgreen 6eccf27
partial-test-restore
ibgreen f5fb11f
fixes
ibgreen b03f384
fixes
ibgreen 8535d8d
wip
ibgreen 632f5a7
fix
ibgreen 2625a74
disable
ibgreen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,377 @@ | ||
| # RFC: Migrate from Tape to Vitest | ||
|
|
||
| - **Author**: Chris Gervang | ||
| - **Date**: January 2026 | ||
| - **Status**: Draft | ||
|
|
||
| ## Overview | ||
|
|
||
| This RFC proposes migrating deck.gl's test infrastructure from **tape** (assertion framework) + **ocular-test** (test runner from @vis.gl/dev-tools) to **vitest** (which serves as both runner and assertion library). | ||
|
|
||
| The migration aims to: | ||
| - Modernize the test infrastructure with a widely-adopted, actively maintained framework | ||
| - Improve developer experience with better error messages, watch mode, and IDE integration | ||
| - Reduce complexity by consolidating runner and assertions into a single tool | ||
| - Maintain the same CLI commands for backwards compatibility | ||
|
|
||
| ## Background | ||
|
|
||
| ### Current Architecture | ||
|
|
||
| ``` | ||
| ocular-test (runner from @vis.gl/dev-tools) | ||
| ├── Vite (dev server for browser tests) | ||
| ├── BrowserTestDriver (@probe.gl/test-utils) | ||
| ├── c8 (coverage) | ||
| └── tape (assertions via tape-promise/tape) | ||
| ``` | ||
|
|
||
| **Entry points:** | ||
| - `test/node.ts` - Minimal smoke test (only `imports-spec` + `core-layers.spec`) | ||
| - `test/browser.ts` - **Comprehensive** - runs ALL tests (`./modules` + `./render` + `./interaction`) | ||
|
|
||
| **Important architectural note:** The previous design intentionally ran all tests in the browser (source of truth for a WebGL library), with Node serving only as a smoke test. | ||
|
|
||
| **Current test commands:** | ||
| - `yarn test` - runs `ocular-test` | ||
| - `yarn test-fast` - runs `ocular-lint && ocular-test node` | ||
| - `yarn cover` - runs `ocular-test cover` | ||
|
|
||
| ### Pain Points | ||
|
|
||
| 1. **Fragmented tooling**: Test runner (ocular-test), assertions (tape), coverage (c8) are separate tools | ||
| 2. **Tape is minimalist**: Limited error messages, no built-in mocking, requires wrappers like tape-promise | ||
| 3. **Custom infrastructure**: BrowserTestDriver requires custom hooks (`window.browserTestDriver_finish`) | ||
| 4. **Developer experience**: No watch mode, no IDE integration for running individual tests | ||
|
|
||
| ## Proposal | ||
|
|
||
| Replace ocular-test and tape with vitest: | ||
|
|
||
| ``` | ||
| vitest (runner + assertions) | ||
| ├── Vite (built-in - same foundation as ocular-test) | ||
| ├── Playwright (browser mode - replaces BrowserTestDriver) | ||
| ├── v8 coverage (built-in) | ||
| └── expect() assertions (replaces tape) | ||
| ``` | ||
|
|
||
| ### Why Vitest? | ||
|
|
||
| 1. **Built on Vite**: Same bundler that ocular-test uses, ensuring compatibility | ||
| 2. **All-in-one**: Runner, assertions, mocking, coverage in a single package | ||
| 3. **Modern DX**: Watch mode, parallel execution, better error messages | ||
| 4. **Industry standard**: Widely adopted, well-documented, actively maintained | ||
| 5. **TypeScript-first**: Native TypeScript support without additional configuration | ||
|
|
||
| ### Multi-Environment Architecture | ||
|
|
||
| We adopt a **hybrid approach** using vitest workspaces: | ||
| - **Browser runs ALL tests** (source of truth for correctness) | ||
| - **Node runs pure unit tests** (fast feedback during development) | ||
|
|
||
| This preserves the previous design philosophy where browser tests are comprehensive, while adding fast local iteration via Node. | ||
|
|
||
| **File naming convention:** | ||
| | Pattern | Description | | ||
| |---------|-------------| | ||
| | `*.spec.ts` | Default - runs in both environments | | ||
| | `*.browser.spec.ts` | Browser-only (WebGL, real DOM, etc.) | | ||
|
|
||
| **Vitest workspace configuration:** | ||
| ```typescript | ||
| // vitest.config.ts | ||
| export default defineConfig({ | ||
| test: { | ||
| projects: [ | ||
| { | ||
| test: { | ||
| name: 'node', | ||
| environment: 'node', | ||
| include: ['test/modules/**/*.spec.ts'], | ||
| exclude: ['test/modules/**/*.browser.spec.ts'], | ||
| setupFiles: ['./test/setup/vitest-node-setup.ts'] | ||
| } | ||
| }, | ||
| { | ||
| test: { | ||
| name: 'browser', | ||
| include: ['test/modules/**/*.spec.ts'], // ALL tests | ||
| browser: { | ||
| enabled: true, | ||
| provider: playwright(), | ||
| instances: [{browser: 'chromium'}] | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| test: { | ||
| name: 'headless', | ||
| include: ['test/modules/**/*.spec.ts'], // ALL tests | ||
| browser: { | ||
| enabled: true, | ||
| headless: true, | ||
| provider: playwright(), | ||
| instances: [{browser: 'chromium'}] | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| **CLI commands:** | ||
| ```json | ||
| { | ||
| "test": "vitest run", | ||
| "test-node": "vitest run --project node", | ||
| "test-browser": "vitest run --project browser", | ||
| "test-headless": "vitest run --project headless" | ||
| } | ||
| ``` | ||
|
|
||
| ### Why Playwright Instead of Puppeteer? | ||
|
|
||
| Vitest browser mode only supports **Playwright** or WebdriverIO as providers - Puppeteer is not an option. This is actually beneficial: | ||
| - Playwright has better parallel execution | ||
| - Native TypeScript support | ||
| - More robust browser automation APIs | ||
| - Better cross-browser testing support | ||
|
|
||
| The existing Puppeteer usage (via `@probe.gl/test-utils` BrowserTestDriver) will be replaced with Playwright's native APIs. | ||
|
|
||
| ### API Changes | ||
|
|
||
| **Test file changes:** | ||
|
|
||
| ```typescript | ||
| // Before (tape) | ||
| import test from 'tape-promise/tape'; | ||
|
|
||
| test('color#parseColor', t => { | ||
| const result = parseColor([127, 128, 129]); | ||
| t.deepEqual(result, [127, 128, 129, 255], 'expected result'); | ||
| t.end(); | ||
| }); | ||
|
|
||
| // After (vitest) | ||
| import {test, expect} from 'vitest'; | ||
|
|
||
| test('color#parseColor', () => { | ||
| const result = parseColor([127, 128, 129]); | ||
| expect(result).toEqual([127, 128, 129, 255]); | ||
| }); | ||
| ``` | ||
|
|
||
| **Assertion mapping:** | ||
|
|
||
| | tape | vitest | | ||
| |------|--------| | ||
| | `t.ok(value)` | `expect(value).toBeTruthy()` | | ||
| | `t.notOk(value)` | `expect(value).toBeFalsy()` | | ||
| | `t.equal(a, b)` / `t.is(a, b)` | `expect(a).toBe(b)` | | ||
| | `t.deepEqual(a, b)` | `expect(a).toEqual(b)` | | ||
| | `t.throws(fn)` | `expect(fn).toThrow()` | | ||
| | `t.end()` | (not needed) | | ||
|
|
||
| ### CLI Compatibility | ||
|
|
||
| Commands remain the same: | ||
|
|
||
| ```json | ||
| { | ||
| "scripts": { | ||
| "test": "vitest run", | ||
| "test-fast": "ocular-lint && vitest run", | ||
| "cover": "vitest run --coverage" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| `yarn test ci` continues to work - vitest auto-detects CI environments. | ||
|
|
||
| ### @deck.gl/test-utils Updates | ||
|
|
||
| The `@deck.gl/test-utils` module uses `makeSpy` from `@probe.gl/test-utils`. This will be replaced with vitest's built-in `vi.spyOn`: | ||
|
|
||
| ```typescript | ||
| // Before | ||
| import {makeSpy} from '@probe.gl/test-utils'; | ||
| const spy = makeSpy(Object.getPrototypeOf(layer), 'updateState'); | ||
|
|
||
| // After | ||
| import {vi} from 'vitest'; | ||
| const spy = vi.spyOn(Object.getPrototypeOf(layer), 'updateState'); | ||
| ``` | ||
|
|
||
| ## Implementation Plan | ||
|
|
||
| ### Phase 1: Infrastructure Setup | ||
|
|
||
| **1.1 Install dependencies:** | ||
| ```bash | ||
| yarn add -D @vitest/browser @vitest/browser-playwright playwright | ||
| ``` | ||
|
|
||
| **Node 18 Compatibility:** Confirmed - Vitest 2.1.9 requires `^18.0.0 || >=20.0.0`, Playwright requires `>=18`. | ||
|
|
||
| **1.2 Update `vitest.config.ts`** with workspace projects (see Multi-Environment Architecture above) | ||
|
|
||
| **1.3 Create setup files:** | ||
| - `test/setup/vitest-node-setup.ts` - JSDOM polyfills (from current `test/node.ts`) | ||
| - `test/setup/vitest-browser-setup.ts` - Minimal (browser provides DOM) | ||
|
|
||
| **1.4 Add npm scripts** for each environment | ||
|
|
||
| ### Phase 2: Update @deck.gl/test-utils | ||
| - Replace `makeSpy` with `vi.spyOn` | ||
| - Add vitest as peer dependency | ||
|
|
||
| ### Phase 3: Migrate Test Files (~185 files) | ||
| - Convert tape imports to vitest | ||
| - Transform assertions | ||
| - Remove `t.end()` calls | ||
| - Update callback patterns (`onError: t.notOk` → `onError: (err) => expect(err).toBeFalsy()`) | ||
|
|
||
| ### Phase 4: Discovery - Run Node Tests and Identify Browser Dependencies | ||
|
|
||
| The hybrid approach serves as a **discovery mechanism**: | ||
|
|
||
| 1. Run `yarn test-node` and observe failures | ||
| 2. Failures reveal browser-only dependencies: | ||
| - WebGL/GPU operations (`@luma.gl/*`) | ||
| - Real DOM APIs not in JSDOM | ||
| - Browser-specific APIs (fetch quirks, Web Workers) | ||
| - Dependencies that check `typeof window` | ||
| - Canvas 2D context beyond JSDOM's mock | ||
|
|
||
| **Decision point after discovery:** | ||
| - **Few failures (~10-20%)** → Keep hybrid, rename failures to `.browser.spec.ts` | ||
| - **Many failures (~50%+)** → Fall back to browser-only approach | ||
|
|
||
| ### Phase 5: Migrate Snapshot & Interaction Tests | ||
|
|
||
| **Current state:** | ||
| - **35 test files** in `test/render/` with **150 golden images** | ||
| - **3 test files** in `test/interaction/` | ||
| - Both use tape + probe.gl's `BrowserTestDriver` (Puppeteer) | ||
| - `SnapshotTestRunner` uses `window.browserTestDriver_captureAndDiffScreen` | ||
| - `InteractionTestRunner` uses `window.browserTestDriver_emulateInput` | ||
|
|
||
| **5.1 Convert to vitest syntax:** | ||
| - Replace `import test from 'tape'` with `import {test, expect} from 'vitest'` | ||
| - Update assertion syntax | ||
|
|
||
| **5.2 Update SnapshotTestRunner for Playwright:** | ||
| - Replace `browserTestDriver_captureAndDiffScreen` with Playwright's `page.screenshot()` | ||
| - Use `@vitest/browser`'s page context | ||
| - Keep golden image comparison logic | ||
|
|
||
| **5.3 Update InteractionTestRunner for Playwright:** | ||
| - Replace `browserTestDriver_emulateInput` with Playwright APIs: | ||
| - `page.mouse.move()`, `page.mouse.click()`, `page.keyboard.press()` | ||
|
|
||
| **5.4 Add to browser project:** | ||
| ```typescript | ||
| { | ||
| name: 'browser', | ||
| include: [ | ||
| 'test/modules/**/*.spec.ts', | ||
| 'test/render/**/*.spec.ts', // Add render tests | ||
| 'test/interaction/**/*.spec.ts' // Add interaction tests | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| **Files to modify:** | ||
| - `modules/test-utils/src/snapshot-test-runner.ts` | ||
| - `modules/test-utils/src/interaction-test-runner.ts` | ||
| - `test/render/index.js` → `test/render/index.spec.ts` | ||
| - `test/interaction/index.js` → `test/interaction/index.spec.ts` | ||
|
|
||
| ### Phase 6: Cleanup | ||
| - Remove `tap-spec`, `tape-catch` dependencies | ||
| - Remove test entry points from `.ocularrc.js` | ||
| - Delete `test/node.ts`, `test/browser.ts`, `.nycrc` | ||
|
|
||
| ## Scope | ||
|
|
||
| - ~185 test files in `test/modules/` | ||
| - ~2800 assertions to convert | ||
| - 1 test utility module (`@deck.gl/test-utils`) | ||
| - 35 render test files with 150 golden images | ||
| - 3 interaction test files | ||
|
|
||
| ## Verification | ||
|
|
||
| 1. `yarn test-node` - runs unit tests in Node (fast feedback) | ||
| 2. `yarn test-browser` - runs ALL tests in Chromium (unit + render + interaction) | ||
| 3. `yarn test-headless` - runs ALL tests headlessly (CI) | ||
| 4. **Render tests**: Golden image comparison passes for all 150 images | ||
| 5. **Interaction tests**: Controller/picking tests pass | ||
|
|
||
| ## Risks and Mitigations | ||
|
|
||
| | Risk | Mitigation | | ||
| |------|------------| | ||
| | Browser tests may behave differently | Vitest browser mode uses Playwright, similar to current Puppeteer-based setup | | ||
| | Coverage format changes | Vitest v8 provider outputs lcov format, same as current setup | | ||
| | Breaking changes for external consumers of test-utils | Add vitest as peer dependency, document migration | | ||
| | Many tests fail in Node environment | Discovery phase allows fallback to browser-only approach (Option A) | | ||
| | Puppeteer → Playwright migration breaks snapshot comparison | Vitest requires Playwright; will need to regenerate golden images if pixel differences occur | | ||
| | CI takes longer (running tests twice) | Node tests are fast; browser failures are the blocking check | | ||
|
|
||
| ## Alternatives Considered | ||
|
|
||
| ### Keep ocular-test, only replace tape assertions | ||
| - **Rejected**: Would require custom integration between ocular-test's BrowserTestDriver and vitest assertions | ||
| - Vitest is designed to be both runner and assertion library | ||
|
|
||
| ### Migrate to Jest | ||
| - **Rejected**: Jest has slower startup, less Vite integration | ||
| - Vitest is faster and shares the same Vite foundation as ocular-test | ||
|
|
||
| ## Open Questions | ||
|
|
||
| 1. Should we convert test file structure to use `describe`/`it` blocks, or keep flat `test()` calls? | ||
| 2. ~~Should browser tests run in CI by default, or remain opt-in?~~ **Resolved:** Browser tests are the source of truth and should run in CI by default. | ||
| 3. ~~Timeline for deprecating tape support in `@deck.gl/test-utils`?~~ **Resolved:** See deprecation timeline below. | ||
| 4. After Phase 4 discovery: What percentage of tests fail in Node? This determines whether to keep hybrid approach or fall back to browser-only. | ||
|
|
||
| ## @deck.gl/test-utils Deprecation Timeline | ||
|
|
||
| **Goal:** Allow external consumers time to migrate while moving the ecosystem forward. | ||
|
|
||
| **Note:** `@deck.gl/test-utils` is published on npm with ~10k monthly downloads (~1% of core). While primarily intended for internal use, external consumers exist and deserve a migration path. | ||
|
|
||
| | Phase | Version | Timeline | Changes | | ||
| |-------|---------|----------|---------| | ||
| | **Compatibility** | 9.3.x | Next minor release | Add vitest as peer dependency alongside `@probe.gl/test-utils`. Both tape and vitest patterns work. | | ||
| | **Deprecation Warning** | 9.4.x | +1 minor release | Console warnings for tape-based patterns (`makeSpy`, `assert: t.ok`). Documentation updated with vitest examples. | | ||
| | **Removal** | 10.0.0 | Next major release | Remove tape/probe.gl support. `vi.spyOn` replaces `makeSpy`. Callbacks use vitest `expect()`. | | ||
|
|
||
| **Migration guide for external consumers:** | ||
|
|
||
| ```typescript | ||
| // Before (tape) | ||
| import {testLayer} from '@deck.gl/test-utils'; | ||
| import test from 'tape'; | ||
|
|
||
| testLayer({assert: test.ok, onError: test.fail}); | ||
|
|
||
| // After (vitest) | ||
| import {testLayer} from '@deck.gl/test-utils'; | ||
| import {expect} from 'vitest'; | ||
|
|
||
| testLayer({ | ||
| assert: (condition, message) => expect(condition, message).toBeTruthy(), | ||
| onError: (error) => { throw error; } | ||
| }); | ||
| ``` | ||
|
|
||
| ## References | ||
|
|
||
| - [Vitest Documentation](https://vitest.dev/) | ||
| - [Vitest Browser Mode](https://vitest.dev/guide/browser/) | ||
| - [ocular-test source](https://github.com/visgl/dev-tools/blob/master/modules/dev-tools/src/test.ts) |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,7 @@ | |
| "@deck.gl/core": "~9.2.0", | ||
| "@luma.gl/core": "~9.2.6", | ||
| "@luma.gl/engine": "~9.2.6", | ||
| "@probe.gl/test-utils": "^4.1.0" | ||
| "vitest": "^2.1.0" | ||
|
||
| }, | ||
| "gitHead": "13ace64fc2cee08c133afc882fc307253489a4e4" | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RFC outlines the goal being to implement a backwards-compatibility layer and deprecation warnings in
@deck.gl/test-utils. I'm not sure what users use it for, but gets a significant number of downloads still so we need to not break anything.I'm thinking we'll need to keep some old test infrastructure around for this module to ensure correctness on both tape and vitest until deck v10
Temporarily, I've removed tape and probe.gl from deck's test utils until I get all tests to pass without the extra complexity.