From e0230cbe526b5d022741d3f548842baa7dbb33b7 Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:05:23 -0500 Subject: [PATCH 1/7] test: configure Vitest browser mode and add basic bindings --- .gitignore | 2 + __tests__/Example.test.res | 18 + package.json | 7 +- rescript.json | 5 + src/bindings/Vitest.res | 25 ++ vitest.config.js | 16 + yarn.lock | 731 ++++++++++++++++++++++++++++++++++++- 7 files changed, 802 insertions(+), 2 deletions(-) create mode 100644 __tests__/Example.test.res create mode 100644 src/bindings/Vitest.res create mode 100644 vitest.config.js diff --git a/.gitignore b/.gitignore index 522b8342c..59dc8d7ad 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,8 @@ app/**/*.mjs app/**/*.jsx functions/**/*.mjs functions/**/*.jsx +__tests__/**/*.mjs +__tests__/**/*.jsx !_shims.mjs !_shims.jsx diff --git a/__tests__/Example.test.res b/__tests__/Example.test.res new file mode 100644 index 000000000..acdf95e76 --- /dev/null +++ b/__tests__/Example.test.res @@ -0,0 +1,18 @@ +open Vitest + +module Example = { + @react.component + let make = () =>
{React.string("testing")}
+} + +test("basic assertions", async () => { + expect("foo")->toBe("foo") + + expect(true)->toBe(true) +}) + +test("component rendering", async () => { + let screen = await render() + + await element(screen->getByText("testing"))->toBeVisible +}) diff --git a/package.json b/package.json index 732a8f3a5..615556608 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "prepare": "yarn build:res && yarn build:scripts && yarn build:update-index", "preview": "yarn build && static-server build/client", "reanalyze": "rescript-tools reanalyze -all-cmt .", - "test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs" + "test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs", + "test:browser": "vitest --config=vitest.browser.config.js" }, "dependencies": { "@babel/generator": "^7.24.7", @@ -84,12 +85,14 @@ "@tailwindcss/vite": "^4.1.13", "@types/react": "^19.2.2", "@vitejs/plugin-react": "^4.7.0", + "@vitest/browser-playwright": "^4.0.18", "auto-image-converter": "^2.1.2", "chokidar": "^4.0.3", "dotenv": "^16.4.7", "jsdom": "^26.1.0", "lefthook": "^2.0.4", "lightningcss": "^1.30.1", + "playwright": "^1.58.2", "prettier": "^3.6.2", "remark-cli": "^12.0.1", "search-insights": "^2.17.3", @@ -100,6 +103,8 @@ "vite-plugin-devtools-json": "^1.0.0", "vite-plugin-env-compatible": "^2.0.1", "vite-plugin-page-reload": "^0.2.2", + "vitest": "^4.0.18", + "vitest-browser-react": "^2.0.5", "wrangler": "^4.63.0" } } diff --git a/rescript.json b/rescript.json index 2e776585b..9214ceafd 100644 --- a/rescript.json +++ b/rescript.json @@ -8,6 +8,11 @@ "dependencies": ["@rescript/react", "@rescript/webapi"], "compiler-flags": ["-open WebAPI.Global"], "sources": [ + { + "dir": "__tests__", + "subdirs": true, + "type": "dev" + }, { "dir": "app", "subdirs": true diff --git a/src/bindings/Vitest.res b/src/bindings/Vitest.res new file mode 100644 index 000000000..45074826b --- /dev/null +++ b/src/bindings/Vitest.res @@ -0,0 +1,25 @@ +type page +type expect +type screen +type assertion + +@module("vitest") +external test: (string, unit => promise) => unit = "test" + +@module("vitest") +external expect: 'a => expect = "expect" + +@send +external toBe: (expect, 'a) => unit = "toBe" + +@send +external toBeVisible: expect => promise = "toBeVisible" + +@module("vitest-browser-react") +external render: Jsx.element => promise = "render" + +@send +external getByText: (screen, string) => expect = "getByText" + +@module("vitest") @scope("expect") +external element: 'a => expect = "element" diff --git a/vitest.config.js b/vitest.config.js new file mode 100644 index 000000000..18eb0da85 --- /dev/null +++ b/vitest.config.js @@ -0,0 +1,16 @@ +import { defineConfig } from "vitest/config"; +import { playwright } from "@vitest/browser-playwright"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + test: { + include: ["__tests__/*.jsx"], + browser: { + enabled: true, + provider: playwright(), + // https://vitest.dev/config/browser/playwright + instances: [{ browser: "chromium" }], + }, + }, +}); diff --git a/yarn.lock b/yarn.lock index af266062f..3e1dab845 100644 --- a/yarn.lock +++ b/yarn.lock @@ -909,6 +909,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/aix-ppc64@npm:0.27.3" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/android-arm64@npm:0.25.12" @@ -923,6 +930,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/android-arm64@npm:0.27.3" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/android-arm@npm:0.25.12" @@ -937,6 +951,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/android-arm@npm:0.27.3" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/android-x64@npm:0.25.12" @@ -951,6 +972,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/android-x64@npm:0.27.3" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/darwin-arm64@npm:0.25.12" @@ -965,6 +993,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/darwin-arm64@npm:0.27.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/darwin-x64@npm:0.25.12" @@ -979,6 +1014,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/darwin-x64@npm:0.27.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/freebsd-arm64@npm:0.25.12" @@ -993,6 +1035,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/freebsd-arm64@npm:0.27.3" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/freebsd-x64@npm:0.25.12" @@ -1007,6 +1056,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/freebsd-x64@npm:0.27.3" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-arm64@npm:0.25.12" @@ -1021,6 +1077,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-arm64@npm:0.27.3" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-arm@npm:0.25.12" @@ -1035,6 +1098,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-arm@npm:0.27.3" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-ia32@npm:0.25.12" @@ -1049,6 +1119,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-ia32@npm:0.27.3" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-loong64@npm:0.25.12" @@ -1063,6 +1140,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-loong64@npm:0.27.3" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-mips64el@npm:0.25.12" @@ -1077,6 +1161,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-mips64el@npm:0.27.3" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-ppc64@npm:0.25.12" @@ -1091,6 +1182,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-ppc64@npm:0.27.3" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-riscv64@npm:0.25.12" @@ -1105,6 +1203,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-riscv64@npm:0.27.3" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-s390x@npm:0.25.12" @@ -1119,6 +1224,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-s390x@npm:0.27.3" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/linux-x64@npm:0.25.12" @@ -1133,6 +1245,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-x64@npm:0.27.3" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/netbsd-arm64@npm:0.25.12" @@ -1147,6 +1266,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/netbsd-arm64@npm:0.27.3" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/netbsd-x64@npm:0.25.12" @@ -1161,6 +1287,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/netbsd-x64@npm:0.27.3" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/openbsd-arm64@npm:0.25.12" @@ -1175,6 +1308,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/openbsd-arm64@npm:0.27.3" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/openbsd-x64@npm:0.25.12" @@ -1189,6 +1329,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/openbsd-x64@npm:0.27.3" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openharmony-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/openharmony-arm64@npm:0.25.12" @@ -1203,6 +1350,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/openharmony-arm64@npm:0.27.3" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/sunos-x64@npm:0.25.12" @@ -1217,6 +1371,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/sunos-x64@npm:0.27.3" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/win32-arm64@npm:0.25.12" @@ -1231,6 +1392,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/win32-arm64@npm:0.27.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/win32-ia32@npm:0.25.12" @@ -1245,6 +1413,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/win32-ia32@npm:0.27.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.25.12": version: 0.25.12 resolution: "@esbuild/win32-x64@npm:0.25.12" @@ -1259,6 +1434,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/win32-x64@npm:0.27.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@fastify/accept-negotiator@npm:^2.0.0": version: 2.0.1 resolution: "@fastify/accept-negotiator@npm:2.0.1" @@ -2251,6 +2433,13 @@ __metadata: languageName: node linkType: hard +"@polka/url@npm:^1.0.0-next.24": + version: 1.0.0-next.29 + resolution: "@polka/url@npm:1.0.0-next.29" + checksum: 10c0/0d58e081844095cb029d3c19a659bfefd09d5d51a2f791bc61eba7ea826f13d6ee204a8a448c2f5a855c17df07b37517373ff916dd05801063c0568ae9937684 + languageName: node + linkType: hard + "@poppinss/colors@npm:^4.1.5": version: 4.1.5 resolution: "@poppinss/colors@npm:4.1.5" @@ -2961,6 +3150,16 @@ __metadata: languageName: node linkType: hard +"@types/chai@npm:^5.2.2": + version: 5.2.3 + resolution: "@types/chai@npm:5.2.3" + dependencies: + "@types/deep-eql": "npm:*" + assertion-error: "npm:^2.0.1" + checksum: 10c0/e0ef1de3b6f8045a5e473e867c8565788c444271409d155588504840ad1a53611011f85072188c2833941189400228c1745d78323dac13fcede9c2b28bacfb2f + languageName: node + linkType: hard + "@types/concat-stream@npm:^2.0.0": version: 2.0.3 resolution: "@types/concat-stream@npm:2.0.3" @@ -2979,6 +3178,13 @@ __metadata: languageName: node linkType: hard +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + "@types/estree-jsx@npm:^1.0.0": version: 1.0.5 resolution: "@types/estree-jsx@npm:1.0.5" @@ -3133,6 +3339,121 @@ __metadata: languageName: node linkType: hard +"@vitest/browser-playwright@npm:^4.0.18": + version: 4.0.18 + resolution: "@vitest/browser-playwright@npm:4.0.18" + dependencies: + "@vitest/browser": "npm:4.0.18" + "@vitest/mocker": "npm:4.0.18" + tinyrainbow: "npm:^3.0.3" + peerDependencies: + playwright: "*" + vitest: 4.0.18 + peerDependenciesMeta: + playwright: + optional: false + checksum: 10c0/505fafe6f957d020b74914ed328de57cba0be65ff82810da85297523776a0d7389669660e58734a416fc09ce262632b4d2cf257a9e8ab1115b695d133bba7bb5 + languageName: node + linkType: hard + +"@vitest/browser@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/browser@npm:4.0.18" + dependencies: + "@vitest/mocker": "npm:4.0.18" + "@vitest/utils": "npm:4.0.18" + magic-string: "npm:^0.30.21" + pixelmatch: "npm:7.1.0" + pngjs: "npm:^7.0.0" + sirv: "npm:^3.0.2" + tinyrainbow: "npm:^3.0.3" + ws: "npm:^8.18.3" + peerDependencies: + vitest: 4.0.18 + checksum: 10c0/6b7bda92fa2e8c68de3e51c97322161484c3f1dd7a7417cdeabb4f1d98eab7dba96c156ac4282ea537c58d55cc0e5959abb4b9d90d3823b3cc3071c3f7460633 + languageName: node + linkType: hard + +"@vitest/expect@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/expect@npm:4.0.18" + dependencies: + "@standard-schema/spec": "npm:^1.0.0" + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:4.0.18" + "@vitest/utils": "npm:4.0.18" + chai: "npm:^6.2.1" + tinyrainbow: "npm:^3.0.3" + checksum: 10c0/123b0aa111682e82ec5289186df18037b1a1768700e468ee0f9879709aaa320cf790463c15c0d8ee10df92b402f4394baf5d27797e604d78e674766d87bcaadc + languageName: node + linkType: hard + +"@vitest/mocker@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/mocker@npm:4.0.18" + dependencies: + "@vitest/spy": "npm:4.0.18" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.21" + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/fb0a257e7e167759d4ad228d53fa7bad2267586459c4a62188f2043dd7163b4b02e1e496dc3c227837f776e7d73d6c4343613e89e7da379d9d30de8260f1ee4b + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/pretty-format@npm:4.0.18" + dependencies: + tinyrainbow: "npm:^3.0.3" + checksum: 10c0/0086b8c88eeca896d8e4b98fcdef452c8041a1b63eb9e85d3e0bcc96c8aa76d8e9e0b6990ebb0bb0a697c4ebab347e7735888b24f507dbff2742ddce7723fd94 + languageName: node + linkType: hard + +"@vitest/runner@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/runner@npm:4.0.18" + dependencies: + "@vitest/utils": "npm:4.0.18" + pathe: "npm:^2.0.3" + checksum: 10c0/fdb4afa411475133c05ba266c8092eaf1e56cbd5fb601f92ec6ccb9bab7ca52e06733ee8626599355cba4ee71cb3a8f28c84d3b69dc972e41047edc50229bc01 + languageName: node + linkType: hard + +"@vitest/snapshot@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/snapshot@npm:4.0.18" + dependencies: + "@vitest/pretty-format": "npm:4.0.18" + magic-string: "npm:^0.30.21" + pathe: "npm:^2.0.3" + checksum: 10c0/d3bfefa558db9a69a66886ace6575eb96903a5ba59f4d9a5d0fecb4acc2bb8dbb443ef409f5ac1475f2e1add30bd1d71280f98912da35e89c75829df9e84ea43 + languageName: node + linkType: hard + +"@vitest/spy@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/spy@npm:4.0.18" + checksum: 10c0/6de537890b3994fcadb8e8d8ac05942320ae184f071ec395d978a5fba7fa928cbb0c5de85af86a1c165706c466e840de8779eaff8c93450c511c7abaeb9b8a4e + languageName: node + linkType: hard + +"@vitest/utils@npm:4.0.18": + version: 4.0.18 + resolution: "@vitest/utils@npm:4.0.18" + dependencies: + "@vitest/pretty-format": "npm:4.0.18" + tinyrainbow: "npm:^3.0.3" + checksum: 10c0/4a3c43c1421eb90f38576926496f6c80056167ba111e63f77cf118983902673737a1a38880b890d7c06ec0a12475024587344ee502b3c43093781533022f2aeb + languageName: node + linkType: hard + "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" @@ -3368,6 +3689,13 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + "astring@npm:^1.8.0": version: 1.9.0 resolution: "astring@npm:1.9.0" @@ -3693,6 +4021,13 @@ __metadata: languageName: node linkType: hard +"chai@npm:^6.2.1": + version: 6.2.2 + resolution: "chai@npm:6.2.2" + checksum: 10c0/e6c69e5f0c11dffe6ea13d0290936ebb68fcc1ad688b8e952e131df6a6d5797d5e860bc55cef1aca2e950c3e1f96daf79e9d5a70fb7dbaab4e46355e2635ed53 + languageName: node + linkType: hard + "chalk@npm:^5.0.0, chalk@npm:^5.3.0": version: 5.6.2 resolution: "chalk@npm:5.6.2" @@ -4697,6 +5032,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.27.0": + version: 0.27.3 + resolution: "esbuild@npm:0.27.3" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.3" + "@esbuild/android-arm": "npm:0.27.3" + "@esbuild/android-arm64": "npm:0.27.3" + "@esbuild/android-x64": "npm:0.27.3" + "@esbuild/darwin-arm64": "npm:0.27.3" + "@esbuild/darwin-x64": "npm:0.27.3" + "@esbuild/freebsd-arm64": "npm:0.27.3" + "@esbuild/freebsd-x64": "npm:0.27.3" + "@esbuild/linux-arm": "npm:0.27.3" + "@esbuild/linux-arm64": "npm:0.27.3" + "@esbuild/linux-ia32": "npm:0.27.3" + "@esbuild/linux-loong64": "npm:0.27.3" + "@esbuild/linux-mips64el": "npm:0.27.3" + "@esbuild/linux-ppc64": "npm:0.27.3" + "@esbuild/linux-riscv64": "npm:0.27.3" + "@esbuild/linux-s390x": "npm:0.27.3" + "@esbuild/linux-x64": "npm:0.27.3" + "@esbuild/netbsd-arm64": "npm:0.27.3" + "@esbuild/netbsd-x64": "npm:0.27.3" + "@esbuild/openbsd-arm64": "npm:0.27.3" + "@esbuild/openbsd-x64": "npm:0.27.3" + "@esbuild/openharmony-arm64": "npm:0.27.3" + "@esbuild/sunos-x64": "npm:0.27.3" + "@esbuild/win32-arm64": "npm:0.27.3" + "@esbuild/win32-ia32": "npm:0.27.3" + "@esbuild/win32-x64": "npm:0.27.3" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/fdc3f87a3f08b3ef98362f37377136c389a0d180fda4b8d073b26ba930cf245521db0a368f119cc7624bc619248fff1439f5811f062d853576f8ffa3df8ee5f1 + languageName: node + linkType: hard + "escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -4787,7 +5211,7 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^3.0.0": +"estree-walker@npm:^3.0.0, estree-walker@npm:^3.0.3": version: 3.0.3 resolution: "estree-walker@npm:3.0.3" dependencies: @@ -4831,6 +5255,13 @@ __metadata: languageName: node linkType: hard +"expect-type@npm:^1.2.2": + version: 1.3.0 + resolution: "expect-type@npm:1.3.0" + checksum: 10c0/8412b3fe4f392c420ab41dae220b09700e4e47c639a29ba7ba2e83cc6cffd2b4926f7ac9e47d7e277e8f4f02acda76fd6931cb81fd2b382fa9477ef9ada953fd + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.3 resolution: "exponential-backoff@npm:3.1.3" @@ -5133,6 +5564,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -5143,6 +5584,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -7740,6 +8190,13 @@ __metadata: languageName: node linkType: hard +"mrmime@npm:^2.0.0": + version: 2.0.1 + resolution: "mrmime@npm:2.0.1" + checksum: 10c0/af05afd95af202fdd620422f976ad67dc18e6ee29beb03dd1ce950ea6ef664de378e44197246df4c7cdd73d47f2e7143a6e26e473084b9e4aa2095c0ad1e1761 + languageName: node + linkType: hard + "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -7962,6 +8419,13 @@ __metadata: languageName: node linkType: hard +"obug@npm:^2.1.1": + version: 2.1.1 + resolution: "obug@npm:2.1.1" + checksum: 10c0/59dccd7de72a047e08f8649e94c1015ec72f94eefb6ddb57fb4812c4b425a813bc7e7cd30c9aca20db3c59abc3c85cc7a62bb656a968741d770f4e8e02bc2e78 + languageName: node + linkType: hard + "on-exit-leak-free@npm:^2.1.0": version: 2.1.2 resolution: "on-exit-leak-free@npm:2.1.2" @@ -8303,6 +8767,48 @@ __metadata: languageName: node linkType: hard +"pixelmatch@npm:7.1.0": + version: 7.1.0 + resolution: "pixelmatch@npm:7.1.0" + dependencies: + pngjs: "npm:^7.0.0" + bin: + pixelmatch: bin/pixelmatch + checksum: 10c0/ff069f92edaa841ac9b58b0ab74e1afa1f3b5e770eea0218c96bac1da4e752f5f6b79a0f9c4ba6b02afb955d39b8c78bcc3cc884f8122b67a1f2efbbccbe1a73 + languageName: node + linkType: hard + +"playwright-core@npm:1.58.2": + version: 1.58.2 + resolution: "playwright-core@npm:1.58.2" + bin: + playwright-core: cli.js + checksum: 10c0/5aa15b2b764e6ffe738293a09081a6f7023847a0dbf4cd05fe10eed2e25450d321baf7482f938f2d2eb330291e197fa23e57b29a5b552b89927ceb791266225b + languageName: node + linkType: hard + +"playwright@npm:^1.58.2": + version: 1.58.2 + resolution: "playwright@npm:1.58.2" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.58.2" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/d060d9b7cc124bd8b5dffebaab5e84f6b34654a553758fe7b19cc598dfbee93f6ecfbdc1832b40a6380ae04eade86ef3285ba03aa0b136799e83402246dc0727 + languageName: node + linkType: hard + +"pngjs@npm:^7.0.0": + version: 7.0.0 + resolution: "pngjs@npm:7.0.0" + checksum: 10c0/0d4c7a0fd476a9c33df7d0a2a73e1d56537628a668841f6995c2bca070cf30819f9254a64363266bc14ef2fee47659dd3b4f2b18eec7ab65143015139f497b38 + languageName: node + linkType: hard + "portfinder@npm:1.0.37": version: 1.0.37 resolution: "portfinder@npm:1.0.37" @@ -8994,6 +9500,7 @@ __metadata: "@tsnobip/rescript-lezer": "npm:^0.7.0" "@types/react": "npm:^19.2.2" "@vitejs/plugin-react": "npm:^4.7.0" + "@vitest/browser-playwright": "npm:^4.0.18" auto-image-converter: "npm:^2.1.2" chokidar: "npm:^4.0.3" docson: "npm:^2.1.0" @@ -9010,6 +9517,7 @@ __metadata: mdast-util-from-markdown: "npm:^2.0.2" mdast-util-to-string: "npm:^4.0.0" mdast-util-toc: "npm:^7.1.0" + playwright: "npm:^1.58.2" prettier: "npm:^3.6.2" react: "npm:^19.1.0" react-dom: "npm:^19.1.0" @@ -9036,6 +9544,8 @@ __metadata: vite-plugin-devtools-json: "npm:^1.0.0" vite-plugin-env-compatible: "npm:^2.0.1" vite-plugin-page-reload: "npm:^0.2.2" + vitest: "npm:^4.0.18" + vitest-browser-react: "npm:^2.0.5" wrangler: "npm:^4.63.0" languageName: unknown linkType: soft @@ -9596,6 +10106,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + "signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" @@ -9603,6 +10120,17 @@ __metadata: languageName: node linkType: hard +"sirv@npm:^3.0.2": + version: 3.0.2 + resolution: "sirv@npm:3.0.2" + dependencies: + "@polka/url": "npm:^1.0.0-next.24" + mrmime: "npm:^2.0.0" + totalist: "npm:^3.0.0" + checksum: 10c0/5930e4397afdb14fbae13751c3be983af4bda5c9aadec832607dc2af15a7162f7d518c71b30e83ae3644b9a24cea041543cc969e5fe2b80af6ce8ea3174b2d04 + languageName: node + linkType: hard + "slash@npm:^5.1.0": version: 5.1.0 resolution: "slash@npm:5.1.0" @@ -9732,6 +10260,13 @@ __metadata: languageName: node linkType: hard +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -9753,6 +10288,13 @@ __metadata: languageName: node linkType: hard +"std-env@npm:^3.10.0": + version: 3.10.0 + resolution: "std-env@npm:3.10.0" + checksum: 10c0/1814927a45004d36dde6707eaf17552a546769bc79a6421be2c16ce77d238158dfe5de30910b78ec30d95135cc1c59ea73ee22d2ca170f8b9753f84da34c427f + languageName: node + linkType: hard + "stdin-discarder@npm:^0.2.2": version: 0.2.2 resolution: "stdin-discarder@npm:0.2.2" @@ -10044,6 +10586,20 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c + languageName: node + linkType: hard + +"tinyexec@npm:^1.0.2": + version: 1.0.2 + resolution: "tinyexec@npm:1.0.2" + checksum: 10c0/1261a8e34c9b539a9aae3b7f0bb5372045ff28ee1eba035a2a059e532198fe1a182ec61ac60fa0b4a4129f0c4c4b1d2d57355b5cb9aa2d17ac9454ecace502ee + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" @@ -10054,6 +10610,13 @@ __metadata: languageName: node linkType: hard +"tinyrainbow@npm:^3.0.3": + version: 3.0.3 + resolution: "tinyrainbow@npm:3.0.3" + checksum: 10c0/1e799d35cd23cabe02e22550985a3051dc88814a979be02dc632a159c393a998628eacfc558e4c746b3006606d54b00bcdea0c39301133956d10a27aa27e988c + languageName: node + linkType: hard + "tldts-core@npm:^6.1.86": version: 6.1.86 resolution: "tldts-core@npm:6.1.86" @@ -10104,6 +10667,13 @@ __metadata: languageName: node linkType: hard +"totalist@npm:^3.0.0": + version: 3.0.1 + resolution: "totalist@npm:3.0.1" + checksum: 10c0/4bb1fadb69c3edbef91c73ebef9d25b33bbf69afe1e37ce544d5f7d13854cda15e47132f3e0dc4cafe300ddb8578c77c50a65004d8b6e97e77934a69aa924863 + languageName: node + linkType: hard + "tough-cookie@npm:^5.1.1": version: 5.1.2 resolution: "tough-cookie@npm:5.1.2" @@ -10731,6 +11301,138 @@ __metadata: languageName: node linkType: hard +"vite@npm:^6.0.0 || ^7.0.0": + version: 7.3.1 + resolution: "vite@npm:7.3.1" + dependencies: + esbuild: "npm:^0.27.0" + fdir: "npm:^6.5.0" + fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.3" + postcss: "npm:^8.5.6" + rollup: "npm:^4.43.0" + tinyglobby: "npm:^0.2.15" + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/5c7548f5f43a23533e53324304db4ad85f1896b1bfd3ee32ae9b866bac2933782c77b350eb2b52a02c625c8ad1ddd4c000df077419410650c982cd97fde8d014 + languageName: node + linkType: hard + +"vitest-browser-react@npm:^2.0.5": + version: 2.0.5 + resolution: "vitest-browser-react@npm:2.0.5" + peerDependencies: + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + vitest: ^4.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/ae972fa20895c73622c2e724a2e2a716cc2a2e5148da19a60d1185323aeb5f5bd0653cfe3048d081bb086ee0efa68c0c360d28cdf42ddd8df6a5f2d17ffd0c9e + languageName: node + linkType: hard + +"vitest@npm:^4.0.18": + version: 4.0.18 + resolution: "vitest@npm:4.0.18" + dependencies: + "@vitest/expect": "npm:4.0.18" + "@vitest/mocker": "npm:4.0.18" + "@vitest/pretty-format": "npm:4.0.18" + "@vitest/runner": "npm:4.0.18" + "@vitest/snapshot": "npm:4.0.18" + "@vitest/spy": "npm:4.0.18" + "@vitest/utils": "npm:4.0.18" + es-module-lexer: "npm:^1.7.0" + expect-type: "npm:^1.2.2" + magic-string: "npm:^0.30.21" + obug: "npm:^2.1.1" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.3" + std-env: "npm:^3.10.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^1.0.2" + tinyglobby: "npm:^0.2.15" + tinyrainbow: "npm:^3.0.3" + vite: "npm:^6.0.0 || ^7.0.0" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@opentelemetry/api": ^1.9.0 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.0.18 + "@vitest/browser-preview": 4.0.18 + "@vitest/browser-webdriverio": 4.0.18 + "@vitest/ui": 4.0.18 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@opentelemetry/api": + optional: true + "@types/node": + optional: true + "@vitest/browser-playwright": + optional: true + "@vitest/browser-preview": + optional: true + "@vitest/browser-webdriverio": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10c0/b913cd32032c95f29ff08c931f4b4c6fd6d2da498908d6770952c561a1b8d75c62499a1f04cadf82fb89cc0f9a33f29fb5dfdb899f6dbb27686a9d91571be5fa + languageName: node + linkType: hard + "w3c-keyname@npm:^2.2.4": version: 2.2.8 resolution: "w3c-keyname@npm:2.2.8" @@ -10892,6 +11594,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + "widest-line@npm:^5.0.0": version: 5.0.0 resolution: "widest-line@npm:5.0.0" @@ -11032,6 +11746,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.18.3": + version: 8.19.0 + resolution: "ws@npm:8.19.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/4741d9b9bc3f9c791880882414f96e36b8b254e34d4b503279d6400d9a4b87a033834856dbdd94ee4b637944df17ea8afc4bce0ff4a1560d2166be8855da5b04 + languageName: node + linkType: hard + "wsl-utils@npm:^0.1.0": version: 0.1.0 resolution: "wsl-utils@npm:0.1.0" From 9699d4f5542faa14889e6ec8389963e23a55fe10 Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:07:46 -0500 Subject: [PATCH 2/7] add to CI --- .github/workflows/pull-request.yml | 1 + package.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index bc85eeee8..6812e76c4 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -13,3 +13,4 @@ jobs: - run: yarn build:res --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110 - run: yarn test - run: yarn ci:format + - run: yarn test:ci diff --git a/package.json b/package.json index 615556608..e0a0cc097 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "build:vite": "react-router build", "build": "yarn build:res && yarn build:scripts && yarn build:update-index && yarn build:vite", "ci:format": "prettier . --check --experimental-cli", + "ci:test": "yarn vitest --run --browser.headless", "clean:res": "rescript clean", "convert-images": "auto-convert-images", "dev:res": "rescript watch", @@ -29,7 +30,7 @@ "preview": "yarn build && static-server build/client", "reanalyze": "rescript-tools reanalyze -all-cmt .", "test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs", - "test:browser": "vitest --config=vitest.browser.config.js" + "vitest": "vitest" }, "dependencies": { "@babel/generator": "^7.24.7", From 771bcb3f7ee116e6e0d3d9414f54499aae6b7494 Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:23:55 -0500 Subject: [PATCH 3/7] add interaction to test --- __tests__/Example.test.res | 14 ++++++++++-- src/bindings/Vitest.res | 47 +++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/__tests__/Example.test.res b/__tests__/Example.test.res index acdf95e76..df140a2db 100644 --- a/__tests__/Example.test.res +++ b/__tests__/Example.test.res @@ -2,7 +2,10 @@ open Vitest module Example = { @react.component - let make = () =>
{React.string("testing")}
+ let make = (~handleClick) => +
+ +
} test("basic assertions", async () => { @@ -12,7 +15,14 @@ test("basic assertions", async () => { }) test("component rendering", async () => { - let screen = await render() + let callback = fn() + let screen = await render() await element(screen->getByText("testing"))->toBeVisible + + let button = await screen->getByRole(#button) + + await button->click + + expect(callback)->toHaveBeenCalled }) diff --git a/src/bindings/Vitest.res b/src/bindings/Vitest.res index 45074826b..0c151148e 100644 --- a/src/bindings/Vitest.res +++ b/src/bindings/Vitest.res @@ -1,25 +1,56 @@ type page type expect type screen -type assertion +type element +type mock +/** + * Vitest + */ @module("vitest") external test: (string, unit => promise) => unit = "test" +@module("vitest") @scope("vi") +external fn: unit => 'a => 'b = "fn" + @module("vitest") external expect: 'a => expect = "expect" +/** + * vitest-browser-react + */ +@module("vitest-browser-react") +external render: Jsx.element => promise = "render" + +@module("vitest") @scope("expect") +external element: 'a => element = "element" + +/* + * Locators + */ @send -external toBe: (expect, 'a) => unit = "toBe" +external getByText: (screen, string) => element = "getByText" @send -external toBeVisible: expect => promise = "toBeVisible" +external getByRole: (screen, [#button]) => promise = "getByRole" -@module("vitest-browser-react") -external render: Jsx.element => promise = "render" +/** + * Actions + */ +@send +external click: element => promise = "click" +/** + * Vitest assertions + */ @send -external getByText: (screen, string) => expect = "getByText" +external toBe: (expect, 'a) => unit = "toBe" -@module("vitest") @scope("expect") -external element: 'a => expect = "element" +@send +external toHaveBeenCalled: expect => unit = "toHaveBeenCalled" + +/** + * Browser assertions + */ +@send +external toBeVisible: element => promise = "toBeVisible" From 8c2b2f650ad8fa5d93f7f0e37866a66d93f2c4c7 Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:24:49 -0500 Subject: [PATCH 4/7] fix test command --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 6812e76c4..8190eb080 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -13,4 +13,4 @@ jobs: - run: yarn build:res --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110 - run: yarn test - run: yarn ci:format - - run: yarn test:ci + - run: yarn ci:test From 9e18478bef784079caf702e5a0d10a97de91ed08 Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:32:17 -0500 Subject: [PATCH 5/7] clean up CI names --- .github/workflows/pull-request.yml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 8190eb080..bea4aa702 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -1,16 +1,25 @@ name: Test on: [pull_request] jobs: - build: + CI: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: Checkout + uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 with: node-version-file: ".node-version" cache: yarn - - run: yarn - - run: yarn build:res --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110 - - run: yarn test - - run: yarn ci:format - - run: yarn ci:test + - name: Install dependencies + run: yarn + - name: Format check + run: yarn ci:format + - name: Build ReScript + run: yarn build:res --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110 + - name: Test examples and hrefs + run: yarn test + - name: Install Playwright + run: yarn playwright install --with-deps + - name: Vitest + run: yarn ci:test From 0b11e76e01c798a7d70ef000125f672670b2f2c4 Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:48:36 -0500 Subject: [PATCH 6/7] split up CI jobs --- .github/workflows/pull-request.yml | 28 ++++++++++++++++++++++++---- package.json | 2 +- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index bea4aa702..58a86c57a 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -1,7 +1,7 @@ -name: Test +name: Pull Request on: [pull_request] jobs: - CI: + Format: runs-on: ubuntu-latest steps: - name: Checkout @@ -15,10 +15,30 @@ jobs: run: yarn - name: Format check run: yarn ci:format - - name: Build ReScript - run: yarn build:res --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110 + Site_Checks: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version-file: ".node-version" + cache: yarn - name: Test examples and hrefs run: yarn test + Vitest: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version-file: ".node-version" + cache: yarn + - name: Build ReScript + run: yarn build:res - name: Install Playwright run: yarn playwright install --with-deps - name: Vitest diff --git a/package.json b/package.json index e0a0cc097..39407f269 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "build:scripts": "yarn dlx tsdown@0.20.0 scripts/*.jsx -d _scripts --no-clean --ext .mjs", "build:generate-llms": "node _scripts/generate_llms.mjs", - "build:res": "rescript build", + "build:res": "rescript build --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110", "build:sync-bundles": "node scripts/sync-playground-bundles.mjs", "build:update-index": "yarn build:generate-llms && node _scripts/generate_feed.mjs > public/blog/feed.xml", "build:vite": "react-router build", From ec82f6befc808660e88f4c5c5c4962586736d2ff Mon Sep 17 00:00:00 2001 From: jderochervlk Date: Sat, 7 Feb 2026 14:49:48 -0500 Subject: [PATCH 7/7] install deps --- .github/workflows/pull-request.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 58a86c57a..e6a8c4a08 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -25,6 +25,8 @@ jobs: with: node-version-file: ".node-version" cache: yarn + - name: Install dependencies + run: yarn - name: Test examples and hrefs run: yarn test Vitest: @@ -37,6 +39,8 @@ jobs: with: node-version-file: ".node-version" cache: yarn + - name: Install dependencies + run: yarn - name: Build ReScript run: yarn build:res - name: Install Playwright