diff --git a/package.json b/package.json
index de41994f..9f213149 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"build": "tsc -b tsconfig.build.json",
"build:clean": "tsc -b tsconfig.build.json --clean",
"test": "npm test -w @interactive-os/json-document",
+ "test:projects": "vitest run --config vitest.config.ts",
"test:collaboration:soak": "npm run test:soak -w @interactive-os/json-document-collaboration",
"typecheck": "npm run typecheck -w @interactive-os/json-document",
"smoke:package": "npm run smoke:package -w @interactive-os/json-document",
diff --git a/packages/contenteditable-collaboration/tsconfig.test.json b/packages/contenteditable-collaboration/tsconfig.test.json
index 0ccde6c2..7fee621e 100644
--- a/packages/contenteditable-collaboration/tsconfig.test.json
+++ b/packages/contenteditable-collaboration/tsconfig.test.json
@@ -6,7 +6,7 @@
"node"
],
"noEmit": true,
- "rootDir": ".",
+ "rootDir": "../..",
"skipLibCheck": true
},
"include": [
diff --git a/packages/contenteditable-collaboration/vitest.config.ts b/packages/contenteditable-collaboration/vitest.config.ts
index bd252e16..cd4a26d1 100644
--- a/packages/contenteditable-collaboration/vitest.config.ts
+++ b/packages/contenteditable-collaboration/vitest.config.ts
@@ -1,6 +1,6 @@
-import { defineConfig } from "vitest/config";
+import { defineDOMProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineDOMProject("contenteditable-collaboration", {
resolve: {
alias: [
{
@@ -26,8 +26,4 @@ export default defineConfig({
},
],
},
- test: {
- environment: "jsdom",
- include: ["tests/**/*.test.ts"],
- },
});
diff --git a/packages/json-document-ajv/tests/ajv-connector.test.ts b/packages/json-document-ajv/tests/ajv-connector.test.ts
index 8c84c09b..41cce37a 100644
--- a/packages/json-document-ajv/tests/ajv-connector.test.ts
+++ b/packages/json-document-ajv/tests/ajv-connector.test.ts
@@ -4,7 +4,7 @@ import { describe, expect, test } from "vitest";
import { createAjvValidator } from "../src/index.js";
-describe("Ajv connector", () => {
+describe("Ajv Connector", () => {
test("translates the first nested error instancePath into a JSON Pointer", () => {
const ajv = new Ajv();
const validate = createAjvValidator(ajv.compile({
diff --git a/packages/json-document-ajv/tsconfig.test.json b/packages/json-document-ajv/tsconfig.test.json
index 1ce8a8e2..adf237ce 100644
--- a/packages/json-document-ajv/tsconfig.test.json
+++ b/packages/json-document-ajv/tsconfig.test.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"composite": false,
"noEmit": true,
- "rootDir": ".",
+ "rootDir": "../..",
"types": ["node", "vitest/globals"]
},
"include": ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"]
diff --git a/packages/json-document-ajv/vitest.config.ts b/packages/json-document-ajv/vitest.config.ts
index 4955cf77..630217eb 100644
--- a/packages/json-document-ajv/vitest.config.ts
+++ b/packages/json-document-ajv/vitest.config.ts
@@ -1,13 +1,9 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document-ajv", {
resolve: {
alias: {
"@interactive-os/json-document": new URL("../json-document/src/application/document/index.ts", import.meta.url).pathname,
},
},
- test: {
- environment: "node",
- include: ["tests/**/*.test.ts"],
- },
});
diff --git a/packages/json-document-collaboration/vitest.config.ts b/packages/json-document-collaboration/vitest.config.ts
index 8b78f010..a447c48a 100644
--- a/packages/json-document-collaboration/vitest.config.ts
+++ b/packages/json-document-collaboration/vitest.config.ts
@@ -1,6 +1,6 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document-collaboration", {
resolve: {
alias: {
"@interactive-os/json-document": new URL(
@@ -13,7 +13,4 @@ export default defineConfig({
).pathname,
},
},
- test: {
- include: ["tests/**/*.test.ts"],
- },
});
diff --git a/packages/json-document-contenteditable/tsconfig.test.json b/packages/json-document-contenteditable/tsconfig.test.json
index 56dcd4a1..7d1d888c 100644
--- a/packages/json-document-contenteditable/tsconfig.test.json
+++ b/packages/json-document-contenteditable/tsconfig.test.json
@@ -1,7 +1,7 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
"compilerOptions": {
- "rootDir": "."
+ "rootDir": "../.."
},
"include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx", "vitest.config.ts"]
}
diff --git a/packages/json-document-contenteditable/vitest.config.ts b/packages/json-document-contenteditable/vitest.config.ts
index 7c0e710d..46998de9 100644
--- a/packages/json-document-contenteditable/vitest.config.ts
+++ b/packages/json-document-contenteditable/vitest.config.ts
@@ -1,7 +1,7 @@
import react from "@vitejs/plugin-react";
-import { defineConfig } from "vitest/config";
+import { defineDOMReactProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineDOMReactProject("json-document-contenteditable", {
plugins: [react()],
resolve: {
alias: {
@@ -9,8 +9,4 @@ export default defineConfig({
},
dedupe: ["react", "react-dom"],
},
- test: {
- environment: "jsdom",
- include: ["tests/**/*.test.ts", "tests/**/*.test.tsx"],
- },
});
diff --git a/packages/json-document-editing/tsconfig.test.json b/packages/json-document-editing/tsconfig.test.json
index 1ce8a8e2..adf237ce 100644
--- a/packages/json-document-editing/tsconfig.test.json
+++ b/packages/json-document-editing/tsconfig.test.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"composite": false,
"noEmit": true,
- "rootDir": ".",
+ "rootDir": "../..",
"types": ["node", "vitest/globals"]
},
"include": ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"]
diff --git a/packages/json-document-editing/vitest.config.ts b/packages/json-document-editing/vitest.config.ts
index 2d753760..38478cb0 100644
--- a/packages/json-document-editing/vitest.config.ts
+++ b/packages/json-document-editing/vitest.config.ts
@@ -1,11 +1,10 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document-editing", {
resolve: {
alias: {
"@interactive-os/json-document": new URL("../json-document/src/application/document/index.ts", import.meta.url).pathname,
"@interactive-os/json-document-selection": new URL("../json-document-selection/src/index.ts", import.meta.url).pathname,
},
},
- test: { include: ["tests/**/*.test.ts"] },
});
diff --git a/packages/json-document-react-hook-form/tests/react-hook-form-connector.test.tsx b/packages/json-document-react-hook-form/tests/react-hook-form-connector.test.tsx
index bf3ce3e0..c8366495 100644
--- a/packages/json-document-react-hook-form/tests/react-hook-form-connector.test.tsx
+++ b/packages/json-document-react-hook-form/tests/react-hook-form-connector.test.tsx
@@ -16,7 +16,7 @@ interface ProfileForm {
afterEach(cleanup);
-describe("React Hook Form connector", () => {
+describe("React Hook Form Connector", () => {
test("keeps drafts local, then commits all submitted fields as one history entry", async () => {
const document = createProfileDocument();
render();
diff --git a/packages/json-document-react-hook-form/tsconfig.test.json b/packages/json-document-react-hook-form/tsconfig.test.json
index da1d0636..5662a9a6 100644
--- a/packages/json-document-react-hook-form/tsconfig.test.json
+++ b/packages/json-document-react-hook-form/tsconfig.test.json
@@ -1,7 +1,7 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
"compilerOptions": {
- "rootDir": "."
+ "rootDir": "../.."
},
"include": ["src/**/*.ts", "tests/**/*.ts", "tests/**/*.tsx", "vitest.config.ts"]
}
diff --git a/packages/json-document-react-hook-form/vitest.config.ts b/packages/json-document-react-hook-form/vitest.config.ts
index a3713c67..5a2b77f4 100644
--- a/packages/json-document-react-hook-form/vitest.config.ts
+++ b/packages/json-document-react-hook-form/vitest.config.ts
@@ -1,7 +1,7 @@
import react from "@vitejs/plugin-react";
-import { defineConfig } from "vitest/config";
+import { defineDOMReactProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineDOMReactProject("json-document-react-hook-form", {
plugins: [react()],
resolve: {
alias: {
@@ -12,8 +12,4 @@ export default defineConfig({
},
dedupe: ["react", "react-dom", "react-hook-form"],
},
- test: {
- environment: "jsdom",
- include: ["tests/**/*.test.ts", "tests/**/*.test.tsx"],
- },
});
diff --git a/packages/json-document-react/tests/react-connector.test.tsx b/packages/json-document-react/tests/react-connector.test.tsx
index 869253c0..14a27ff3 100644
--- a/packages/json-document-react/tests/react-connector.test.tsx
+++ b/packages/json-document-react/tests/react-connector.test.tsx
@@ -11,7 +11,7 @@ import {
afterEach(cleanup);
-describe("React connector", () => {
+describe("React Connector", () => {
test("exposes the shared document through the official Connector entry point", () => {
const document = createJSONDocument({ title: "Draft" });
function View() {
diff --git a/packages/json-document-react/tsconfig.test.json b/packages/json-document-react/tsconfig.test.json
index da1d0636..5662a9a6 100644
--- a/packages/json-document-react/tsconfig.test.json
+++ b/packages/json-document-react/tsconfig.test.json
@@ -1,7 +1,7 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
"compilerOptions": {
- "rootDir": "."
+ "rootDir": "../.."
},
"include": ["src/**/*.ts", "tests/**/*.ts", "tests/**/*.tsx", "vitest.config.ts"]
}
diff --git a/packages/json-document-react/vitest.config.ts b/packages/json-document-react/vitest.config.ts
index 5c32b171..dbd2e552 100644
--- a/packages/json-document-react/vitest.config.ts
+++ b/packages/json-document-react/vitest.config.ts
@@ -1,7 +1,7 @@
import react from "@vitejs/plugin-react";
-import { defineConfig } from "vitest/config";
+import { defineDOMReactProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineDOMReactProject("json-document-react", {
plugins: [react()],
resolve: {
alias: {
@@ -10,8 +10,4 @@ export default defineConfig({
},
dedupe: ["react", "react-dom"],
},
- test: {
- environment: "jsdom",
- include: ["tests/**/*.test.ts", "tests/**/*.test.tsx"],
- },
});
diff --git a/packages/json-document-rich-text-react/tsconfig.test.json b/packages/json-document-rich-text-react/tsconfig.test.json
index 519b66da..ac66d93a 100644
--- a/packages/json-document-rich-text-react/tsconfig.test.json
+++ b/packages/json-document-rich-text-react/tsconfig.test.json
@@ -1,5 +1,5 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
- "compilerOptions": { "rootDir": "." },
+ "compilerOptions": { "rootDir": "../.." },
"include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx"]
}
diff --git a/packages/json-document-rich-text-react/vitest.config.ts b/packages/json-document-rich-text-react/vitest.config.ts
index 7a90a3c7..e15e1a68 100644
--- a/packages/json-document-rich-text-react/vitest.config.ts
+++ b/packages/json-document-rich-text-react/vitest.config.ts
@@ -1,8 +1,7 @@
-import { defineConfig } from "vitest/config";
-export default defineConfig({
+import { defineNodeReactProject } from "../../test/vitest.shared.js";
+
+export default defineNodeReactProject("json-document-rich-text-react", {
test: {
- environment: "node",
- include: ["tests/**/*.test.ts", "tests/**/*.test.tsx"],
environmentMatchGlobs: [["tests/render-locality.test.tsx", "jsdom"]],
},
});
diff --git a/packages/json-document-rich-text-web/tsconfig.test.json b/packages/json-document-rich-text-web/tsconfig.test.json
index ac3a5704..cff6edf9 100644
--- a/packages/json-document-rich-text-web/tsconfig.test.json
+++ b/packages/json-document-rich-text-web/tsconfig.test.json
@@ -1,5 +1,5 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
- "compilerOptions": { "rootDir": "." },
+ "compilerOptions": { "rootDir": "../.." },
"include": ["src/**/*.ts", "tests/**/*.ts"]
}
diff --git a/packages/json-document-rich-text-web/vitest.config.ts b/packages/json-document-rich-text-web/vitest.config.ts
index 48de14cd..52e1d207 100644
--- a/packages/json-document-rich-text-web/vitest.config.ts
+++ b/packages/json-document-rich-text-web/vitest.config.ts
@@ -1,2 +1,3 @@
-import { defineConfig } from "vitest/config";
-export default defineConfig({ test: { environment: "jsdom", include: ["tests/**/*.test.ts"] } });
+import { defineDOMProject } from "../../test/vitest.shared.js";
+
+export default defineDOMProject("json-document-rich-text-web");
diff --git a/packages/json-document-rich-text/tsconfig.test.json b/packages/json-document-rich-text/tsconfig.test.json
index 1ce8a8e2..adf237ce 100644
--- a/packages/json-document-rich-text/tsconfig.test.json
+++ b/packages/json-document-rich-text/tsconfig.test.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"composite": false,
"noEmit": true,
- "rootDir": ".",
+ "rootDir": "../..",
"types": ["node", "vitest/globals"]
},
"include": ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"]
diff --git a/packages/json-document-rich-text/vitest.config.ts b/packages/json-document-rich-text/vitest.config.ts
index 00988cf0..237f2e7c 100644
--- a/packages/json-document-rich-text/vitest.config.ts
+++ b/packages/json-document-rich-text/vitest.config.ts
@@ -1,5 +1,3 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
- test: { include: ["tests/**/*.test.ts"] },
-});
+export default defineNodeProject("json-document-rich-text");
diff --git a/packages/json-document-selection/tsconfig.test.json b/packages/json-document-selection/tsconfig.test.json
index 1ce8a8e2..adf237ce 100644
--- a/packages/json-document-selection/tsconfig.test.json
+++ b/packages/json-document-selection/tsconfig.test.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"composite": false,
"noEmit": true,
- "rootDir": ".",
+ "rootDir": "../..",
"types": ["node", "vitest/globals"]
},
"include": ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"]
diff --git a/packages/json-document-selection/vitest.config.ts b/packages/json-document-selection/vitest.config.ts
index 00988cf0..8a1991b8 100644
--- a/packages/json-document-selection/vitest.config.ts
+++ b/packages/json-document-selection/vitest.config.ts
@@ -1,5 +1,3 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
- test: { include: ["tests/**/*.test.ts"] },
-});
+export default defineNodeProject("json-document-selection");
diff --git a/packages/json-document-tanstack-table/tsconfig.test.json b/packages/json-document-tanstack-table/tsconfig.test.json
index 9e4e9510..97f83bfd 100644
--- a/packages/json-document-tanstack-table/tsconfig.test.json
+++ b/packages/json-document-tanstack-table/tsconfig.test.json
@@ -1,7 +1,7 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
"compilerOptions": {
- "rootDir": "."
+ "rootDir": "../.."
},
"include": ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"]
}
diff --git a/packages/json-document-tanstack-table/vitest.config.ts b/packages/json-document-tanstack-table/vitest.config.ts
index 93d174ee..3af9fdbc 100644
--- a/packages/json-document-tanstack-table/vitest.config.ts
+++ b/packages/json-document-tanstack-table/vitest.config.ts
@@ -1,14 +1,10 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document-tanstack-table", {
resolve: {
alias: {
"@interactive-os/json-document": new URL("../json-document/src/application/document/index.ts", import.meta.url).pathname,
"@interactive-os/json-document-editing": new URL("../json-document-editing/src/index.ts", import.meta.url).pathname,
},
},
- test: {
- environment: "node",
- include: ["tests/**/*.test.ts"],
- },
});
diff --git a/packages/json-document-web/tests/web-connector.test.ts b/packages/json-document-web/tests/web-adapters.test.ts
similarity index 99%
rename from packages/json-document-web/tests/web-connector.test.ts
rename to packages/json-document-web/tests/web-adapters.test.ts
index 273dc6ed..5546ffa2 100644
--- a/packages/json-document-web/tests/web-connector.test.ts
+++ b/packages/json-document-web/tests/web-adapters.test.ts
@@ -27,7 +27,7 @@ import {
type WebClipboardEvent,
} from "../src/index.js";
-describe("Web clipboard Connector", () => {
+describe("Web clipboard Adapter", () => {
test("copies and pastes a structured Document payload through ClipboardEvent contracts", () => {
const editor = createDocumentEditor({
blocks: [
@@ -270,7 +270,7 @@ describe("Web input modifiers", () => {
});
});
-describe("Web keyboard adapter", () => {
+describe("Web keyboard Adapter", () => {
const adapter = createWebKeyboardAdapter();
const grid = {
rowIds: ["r1", "r2", "r3"],
diff --git a/packages/json-document-web/tsconfig.test.json b/packages/json-document-web/tsconfig.test.json
index 47dc82d1..bd90e2d9 100644
--- a/packages/json-document-web/tsconfig.test.json
+++ b/packages/json-document-web/tsconfig.test.json
@@ -1,7 +1,7 @@
{
"extends": ["./tsconfig.json", "../../tsconfig/test-dom.json"],
"compilerOptions": {
- "rootDir": "."
+ "rootDir": "../.."
},
"include": ["src/**/*.ts", "tests/**/*.ts"]
}
diff --git a/packages/json-document-web/vitest.config.ts b/packages/json-document-web/vitest.config.ts
index 1069a2be..ba49e669 100644
--- a/packages/json-document-web/vitest.config.ts
+++ b/packages/json-document-web/vitest.config.ts
@@ -1,6 +1,6 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document-web", {
resolve: {
alias: {
"@interactive-os/json-document": new URL("../json-document/src/application/document/index.ts", import.meta.url).pathname,
@@ -8,8 +8,4 @@ export default defineConfig({
"@interactive-os/json-document-editing": new URL("../json-document-editing/src/index.ts", import.meta.url).pathname,
},
},
- test: {
- environment: "node",
- include: ["tests/**/*.test.ts"],
- },
});
diff --git a/packages/json-document-zod/tests/zod-connector.test.ts b/packages/json-document-zod/tests/zod-connector.test.ts
index 829360e6..d263055d 100644
--- a/packages/json-document-zod/tests/zod-connector.test.ts
+++ b/packages/json-document-zod/tests/zod-connector.test.ts
@@ -4,7 +4,7 @@ import * as z from "zod/v4";
import { createZodValidator } from "../src/index.js";
-describe("Zod connector", () => {
+describe("Zod Connector", () => {
test("translates the first nested issue path into an escaped JSON Pointer", () => {
const validate = createZodValidator(z.object({
profile: z.object({
diff --git a/packages/json-document-zod/tsconfig.test.json b/packages/json-document-zod/tsconfig.test.json
index 1ce8a8e2..adf237ce 100644
--- a/packages/json-document-zod/tsconfig.test.json
+++ b/packages/json-document-zod/tsconfig.test.json
@@ -3,7 +3,7 @@
"compilerOptions": {
"composite": false,
"noEmit": true,
- "rootDir": ".",
+ "rootDir": "../..",
"types": ["node", "vitest/globals"]
},
"include": ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"]
diff --git a/packages/json-document-zod/vitest.config.ts b/packages/json-document-zod/vitest.config.ts
index 4955cf77..80d3d8f1 100644
--- a/packages/json-document-zod/vitest.config.ts
+++ b/packages/json-document-zod/vitest.config.ts
@@ -1,13 +1,9 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document-zod", {
resolve: {
alias: {
"@interactive-os/json-document": new URL("../json-document/src/application/document/index.ts", import.meta.url).pathname,
},
},
- test: {
- environment: "node",
- include: ["tests/**/*.test.ts"],
- },
});
diff --git a/packages/json-document/vitest.config.ts b/packages/json-document/vitest.config.ts
index 7cae7533..0544468f 100644
--- a/packages/json-document/vitest.config.ts
+++ b/packages/json-document/vitest.config.ts
@@ -1,6 +1,6 @@
-import { defineConfig } from "vitest/config";
+import { defineNodeProject } from "../../test/vitest.shared.js";
-export default defineConfig({
+export default defineNodeProject("json-document", {
resolve: {
alias: {
"@interactive-os/json-document": new URL("./src/application/document/index.ts", import.meta.url).pathname,
diff --git a/site/playwright.config.ts b/site/playwright.config.ts
index d5965f1e..3034c3f3 100644
--- a/site/playwright.config.ts
+++ b/site/playwright.config.ts
@@ -29,8 +29,14 @@ export default defineConfig({
url: baseURL,
},
projects: [
+ {
+ name: "setup",
+ testMatch: /.*\.setup\.ts/,
+ },
{
name: "chrome",
+ dependencies: ["setup"],
+ testIgnore: /.*\.setup\.ts/,
use: {
...devices["Desktop Chrome"],
...(browserChannel ? { channel: browserChannel } : {}),
diff --git a/site/tests/browser/connectors/contenteditable.spec.ts b/site/tests/browser/adapters/contenteditable.spec.ts
similarity index 91%
rename from site/tests/browser/connectors/contenteditable.spec.ts
rename to site/tests/browser/adapters/contenteditable.spec.ts
index b2ce5ea9..cfa3fa01 100644
--- a/site/tests/browser/connectors/contenteditable.spec.ts
+++ b/site/tests/browser/adapters/contenteditable.spec.ts
@@ -1,6 +1,6 @@
import { expect, test } from "@playwright/test";
-test("Contenteditable Connector commits a local string through the mounted React component", async ({ page }) => {
+test("Contenteditable Adapter commits a local string through the mounted React component", async ({ page }) => {
const errors: string[] = [];
page.on("console", (message) => {
if (message.type() === "error" || message.type() === "warning") errors.push(message.text());
diff --git a/site/tests/browser/site.setup.ts b/site/tests/browser/site.setup.ts
new file mode 100644
index 00000000..f85d52bf
--- /dev/null
+++ b/site/tests/browser/site.setup.ts
@@ -0,0 +1,6 @@
+import { expect, test } from "@playwright/test";
+
+test("browser acceptance server is ready", async ({ request }) => {
+ const response = await request.get("/");
+ expect(response.ok()).toBe(true);
+});
diff --git a/site/vitest.config.ts b/site/vitest.config.ts
index 6feb1bcd..e57ae45b 100644
--- a/site/vitest.config.ts
+++ b/site/vitest.config.ts
@@ -1,9 +1,9 @@
import react from "@vitejs/plugin-react";
import { tanstackRouter } from "@tanstack/router-plugin/vite";
-import { defineConfig } from "vitest/config";
+import { defineDOMReactProject } from "../test/vitest.shared.js";
import { jsonDocumentSourceAliases } from "./config/json-document-source-aliases.ts";
-export default defineConfig({
+export default defineDOMReactProject("site", {
plugins: [
tanstackRouter({
target: "react",
@@ -19,8 +19,4 @@ export default defineConfig({
alias: jsonDocumentSourceAliases(),
dedupe: ["react", "react-dom"],
},
- test: {
- environment: "jsdom",
- include: ["tests/**/*.test.ts", "tests/**/*.test.tsx"],
- },
});
diff --git a/test/README.md b/test/README.md
new file mode 100644
index 00000000..f9981167
--- /dev/null
+++ b/test/README.md
@@ -0,0 +1,27 @@
+# Test project configuration
+
+`vitest.shared.ts`는 repository Vitest project의 공통 runner policy 정본이다.
+Package와 site의 `vitest.config.ts`에는 project 이름, source alias, plugin, dedupe,
+특수 include처럼 실제 차이만 둔다.
+
+```text
+vitest.config.ts
+`-- test.projects
+ |-- packages/*/vitest.config.ts
+ `-- site/vitest.config.ts
+
+test/vitest.shared.ts
+|-- defineNodeProject
+|-- defineNodeReactProject
+|-- defineDOMProject
+`-- defineDOMReactProject
+```
+
+- 전체 project: `npm run test:projects`
+- 선택 project: `npm run test:projects -- --project `
+- package 단독: 각 workspace의 기존 `npm test` command
+- browser acceptance: `npm run browser:test`
+
+Playwright의 `setup` project는 acceptance server readiness를 먼저 증명하고
+`chrome` project가 이를 dependency로 선언한다. Unit/conformance project와 browser
+acceptance project는 서로 대체하지 않는다.
diff --git a/test/vitest.shared.ts b/test/vitest.shared.ts
new file mode 100644
index 00000000..5db4c355
--- /dev/null
+++ b/test/vitest.shared.ts
@@ -0,0 +1,37 @@
+import { defineConfig, mergeConfig } from "vitest/config";
+import type { UserConfig } from "vite";
+
+const typescriptTests = ["tests/**/*.test.ts"];
+const typescriptReactTests = ["tests/**/*.test.ts", "tests/**/*.test.tsx"];
+
+function defineProject(
+ name: string,
+ environment: "node" | "jsdom",
+ include: string[],
+ config: UserConfig,
+) {
+ return defineConfig(mergeConfig({
+ test: {
+ name,
+ environment,
+ include,
+ isolate: true,
+ },
+ }, config));
+}
+
+export function defineNodeProject(name: string, config: UserConfig = {}) {
+ return defineProject(name, "node", typescriptTests, config);
+}
+
+export function defineNodeReactProject(name: string, config: UserConfig = {}) {
+ return defineProject(name, "node", typescriptReactTests, config);
+}
+
+export function defineDOMProject(name: string, config: UserConfig = {}) {
+ return defineProject(name, "jsdom", typescriptTests, config);
+}
+
+export function defineDOMReactProject(name: string, config: UserConfig = {}) {
+ return defineProject(name, "jsdom", typescriptReactTests, config);
+}
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 00000000..d5a1be70
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vitest/config";
+
+export default defineConfig({
+ test: {
+ projects: ["packages/*/vitest.config.ts", "site/vitest.config.ts"],
+ },
+});