diff --git a/README.md b/README.md index 31c1333..59dedf6 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,7 @@ This MVP uses Drizzle with Bun SQLite for local file-backed persistence. - `bun run test`: run the unit test stage in all workspaces. - `bun run test:unit`: run Vitest explicitly as the unit test stage. - `bun run test:e2e`: build and run Playwright browser smoke and QA checks. -- `bun run test:qa`: run the release gate through Turbo across check, unit, - build, Storybook, and e2e tasks. +- `bun run test:qa`: run the release gate through Turbo. - `bun run build`: build the UI package, production website, and Bun server. - `bun run preview`: preview the production web build. - `bun run storybook`: start the UI package component explorer on port 6006. @@ -103,9 +102,7 @@ bun run test:qa The gate runs TypeScript checks, Vitest coverage for model, persistence, renderer, datasource mocks, and presentation boundaries, the production build, the static Storybook build, and Playwright desktop/mobile -smoke checks against the built adapter output. Turbo owns the release task -graph; app package scripts stay as leaf commands and do not re-run the QA -pipeline internally. Playwright also performs +smoke checks against the built adapter output. Playwright also performs baseline screenshot checks, keyboard navigation checks, reduced-motion checks, landmark checks, and axe accessibility checks against the real model-driven route. diff --git a/apps/web/package.json b/apps/web/package.json index c2c183f..7875aa8 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -11,6 +11,7 @@ "test": "vitest run", "test:unit": "vitest run", "test:e2e": "env -u NO_COLOR playwright test", + "test:qa": "bun run check && bun run test:unit && bun run build && bun run test:e2e", "db:generate": "drizzle-kit generate", "db:check": "drizzle-kit check" }, diff --git a/apps/web/playwright.config.ts b/apps/web/playwright.config.ts index ac0fe5e..afba557 100644 --- a/apps/web/playwright.config.ts +++ b/apps/web/playwright.config.ts @@ -21,13 +21,13 @@ export default defineConfig({ }, webServer: [ { - command: `DISABLE_LIVE_DATASOURCES=1 DATABASE_URL=${databaseUrl} HOST=127.0.0.1 PORT=${port} bun build/index.js`, + command: `DISABLE_LIVE_DATASOURCES=1 bun run build && DISABLE_LIVE_DATASOURCES=1 DATABASE_URL=${databaseUrl} HOST=127.0.0.1 PORT=${port} bun build/index.js`, url: baseURL, reuseExistingServer: false, timeout: 120_000, }, { - command: `cd ../.. && STORYBOOK_STATIC_PORT=${storybookPort} bun apps/web/tests/e2e/storybook-server.ts`, + command: `cd ../.. && bun run build-storybook && STORYBOOK_STATIC_PORT=${storybookPort} bun apps/web/tests/e2e/storybook-server.ts`, url: storybookURL, reuseExistingServer: false, timeout: 120_000, diff --git a/apps/web/src/lib/workspace-boundary.test.ts b/apps/web/src/lib/workspace-boundary.test.ts index 51652dc..66a11c5 100644 --- a/apps/web/src/lib/workspace-boundary.test.ts +++ b/apps/web/src/lib/workspace-boundary.test.ts @@ -18,62 +18,10 @@ describe("workspace boundaries", () => { expect(packageJson.private).toBe(true); expect(packageJson.workspaces).toEqual(["apps/*", "packages/*"]); - expect(packageJson.scripts?.build).toBe("turbo run build"); + expect(packageJson.scripts?.build).toBe("turbo build"); expect(existsSync(join(root, "turbo.json"))).toBe(true); }); - test("keeps release orchestration in the root turbo task graph", () => { - const rootPackage = JSON.parse( - readFileSync(join(root, "package.json"), "utf8"), - ) as { - scripts?: Record; - }; - const webPackage = JSON.parse( - readFileSync(join(root, "apps/web/package.json"), "utf8"), - ) as { scripts?: Record }; - const turboConfig = JSON.parse( - readFileSync(join(root, "turbo.json"), "utf8"), - ) as { - globalDependencies?: string[]; - tasks?: Record; - }; - - expect(rootPackage.scripts?.["test:qa"]).toBe( - "turbo run check test:unit build @dimensionlab/ui#build-storybook @dimensionlab/web#test:e2e", - ); - expect(webPackage.scripts).not.toHaveProperty("test:qa"); - expect(turboConfig.tasks).not.toHaveProperty("test:qa"); - expect(turboConfig.globalDependencies).toEqual( - expect.arrayContaining(["bun.lock", "tsconfig.base.json"]), - ); - expect(turboConfig.tasks?.["test:e2e"]?.env).toEqual( - expect.arrayContaining([ - "CI", - "PLAYWRIGHT_DATABASE_URL", - "PLAYWRIGHT_PORT", - "PLAYWRIGHT_STORYBOOK_PORT", - ]), - ); - }); - - test("lets turbo build app and Storybook artifacts before e2e serves them", () => { - const playwrightConfig = readFileSync( - join(root, "apps/web/playwright.config.ts"), - "utf8", - ); - const turboConfig = JSON.parse( - readFileSync(join(root, "turbo.json"), "utf8"), - ) as { - tasks?: Record; - }; - - expect(playwrightConfig).not.toContain("bun run build &&"); - expect(playwrightConfig).not.toContain("bun run build-storybook"); - expect(turboConfig.tasks?.["test:e2e"]?.dependsOn).toEqual( - expect.arrayContaining(["@dimensionlab/ui#build-storybook"]), - ); - }); - test("keeps the website app and reusable UI library as separate packages", () => { const webPackage = JSON.parse( readFileSync(join(root, "apps/web/package.json"), "utf8"), diff --git a/package.json b/package.json index e33d3aa..5b94c8f 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,18 @@ "packages/*" ], "scripts": { - "dev": "turbo run dev --filter=@dimensionlab/web", - "build": "turbo run build", - "preview": "turbo run preview --filter=@dimensionlab/web", - "storybook": "turbo run storybook --filter=@dimensionlab/ui", - "build-storybook": "turbo run build-storybook --filter=@dimensionlab/ui", - "check": "turbo run check", - "test": "turbo run test:unit", - "test:unit": "turbo run test:unit", - "test:e2e": "turbo run test:e2e --filter=@dimensionlab/web", - "test:qa": "turbo run check test:unit build @dimensionlab/ui#build-storybook @dimensionlab/web#test:e2e", - "db:generate": "turbo run db:generate --filter=@dimensionlab/web", - "db:check": "turbo run db:check --filter=@dimensionlab/web" + "dev": "turbo dev --filter=@dimensionlab/web", + "build": "turbo build", + "preview": "bun run --cwd apps/web preview", + "storybook": "turbo storybook --filter=@dimensionlab/ui", + "build-storybook": "turbo build-storybook --filter=@dimensionlab/ui", + "check": "turbo check", + "test": "turbo test:unit", + "test:unit": "turbo test:unit", + "test:e2e": "turbo test:e2e --filter=@dimensionlab/web", + "test:qa": "turbo test:qa", + "db:generate": "bun run --cwd apps/web db:generate", + "db:check": "bun run --cwd apps/web db:check" }, "devDependencies": { "turbo": "^2.5.0" diff --git a/turbo.json b/turbo.json index 446d6fe..ee027a8 100644 --- a/turbo.json +++ b/turbo.json @@ -1,16 +1,9 @@ { "$schema": "https://turbo.build/schema.json", - "globalDependencies": [ - "bun.lock", - "package.json", - "tsconfig.base.json", - "tsconfig.json" - ], "tasks": { "build": { "dependsOn": ["^build"], - "outputs": ["dist/**", "build/**"], - "env": ["NODE_ENV", "VITE_*"] + "outputs": ["dist/**", "build/**"] }, "check": { "dependsOn": ["^build"], @@ -18,78 +11,33 @@ }, "test:unit": { "dependsOn": ["^build"], - "outputs": [], - "env": [ - "AGENT_CONFIG_TOKEN", - "DASHBOARD_MIGRATIONS_DIR", - "DATABASE_URL", - "DISABLE_LIVE_DATASOURCES", - "PROMETHEUS_BASE_URL" - ] + "outputs": [] }, "build-storybook": { "dependsOn": ["^build"], - "outputs": ["storybook-static/**"], - "env": ["NODE_ENV", "STORYBOOK_*", "VITE_*"] + "outputs": ["storybook-static/**"] }, "test:e2e": { + "dependsOn": ["build", "^build"], + "outputs": ["test-results/**", "playwright-report/**"] + }, + "test:qa": { "dependsOn": [ + "check", + "test:unit", "build", - "^build", - "@dimensionlab/ui#build-storybook" + "build-storybook", + "test:e2e" ], - "outputs": ["test-results/**", "playwright-report/**"], - "env": [ - "AGENT_CONFIG_TOKEN", - "CI", - "DASHBOARD_MIGRATIONS_DIR", - "DATABASE_URL", - "DISABLE_LIVE_DATASOURCES", - "PLAYWRIGHT_DATABASE_URL", - "PLAYWRIGHT_PORT", - "PLAYWRIGHT_STORYBOOK_PORT", - "PROMETHEUS_BASE_URL", - "STORYBOOK_STATIC_PORT" - ] - }, - "db:generate": { - "cache": false - }, - "db:check": { - "outputs": [], - "env": ["DATABASE_URL"] + "outputs": [] }, "dev": { "cache": false, - "persistent": true, - "env": [ - "AGENT_CONFIG_TOKEN", - "DASHBOARD_DEV_API_HOST", - "DASHBOARD_DEV_API_PORT", - "DASHBOARD_DEV_API_TARGET", - "DASHBOARD_MIGRATIONS_DIR", - "DATABASE_URL", - "HOST", - "PORT", - "PROMETHEUS_BASE_URL" - ] - }, - "preview": { - "cache": false, - "persistent": true, - "env": [ - "AGENT_CONFIG_TOKEN", - "DASHBOARD_MIGRATIONS_DIR", - "DATABASE_URL", - "HOST", - "PORT", - "PROMETHEUS_BASE_URL" - ] + "persistent": true }, "storybook": { "cache": false, - "persistent": true, - "env": ["HOST", "PORT", "STORYBOOK_*", "VITE_*"] + "persistent": true } } }