learning_ai_invt_trdg/web/vite.config.ts
Saravana Achu Mac 8db23bde2d test(ui): add Playwright and Storybook testing infrastructure
- Installed Playwright and Storybook packages
- Created playwright.config.ts with viewport matrix and browser configurations
- Installed Playwright chromium browser
- Created e2e/viewport-matrix.spec.ts for viewport matrix testing
- Created e2e/horizontal-overflow.spec.ts for horizontal overflow testing
- Added test scripts to package.json (test:e2e, test:e2e:ui, test:e2e:viewport, test:e2e:overflow)
- Updated LAUNCH_READY_UI_UX_ROADMAP.md checklist with testing infrastructure status
2026-05-09 13:19:14 -07:00

130 lines
4.7 KiB
TypeScript

/// <reference types="vitest/config" />
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
import { playwright } from '@vitest/browser-playwright';
const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
const monacoEditorPath = path.resolve(__dirname, '../node_modules/.pnpm/monaco-editor@0.55.1/node_modules/monaco-editor');
const workspaceRoot = path.resolve(__dirname, '..', '..');
const commonPlatRoot = path.join(workspaceRoot, 'learning_ai_common_plat');
function commonPlatSourceEntry(pkg: string): string | null {
const sourceEntry = path.join(commonPlatRoot, 'packages', pkg, 'src', 'index.ts');
return fs.existsSync(sourceEntry) ? sourceEntry : null;
}
// Resolve a @bytelyst/* package: prefer web/node_modules, fall back to vendor/
function bytelystAlias(pkg: string): string {
const sourceEntry = commonPlatSourceEntry(pkg);
if (sourceEntry) return sourceEntry;
const nmPath = path.resolve(__dirname, 'node_modules/@bytelyst', pkg);
const vendorPath = path.resolve(__dirname, '../vendor/bytelyst', pkg);
if (fs.existsSync(nmPath)) return nmPath;
if (fs.existsSync(vendorPath)) return vendorPath;
return nmPath; // let Vite surface the missing-module error
}
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss()],
// Shared files (../shared/*.ts) live outside web/ so Vite resolves their imports
// from the repo root where @bytelyst/* are not installed. Redirect all @bytelyst/*
// imports first to web/node_modules, then fall back to the monorepo vendor/ dir.
resolve: {
// Deduplicate React so the vendored react-auth dist resolves the same react instance
dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react-router-dom'],
alias: [
// Vendor packages that live only in vendor/ (not in web/node_modules/)
{
find: '@bytelyst/api-client',
replacement: bytelystAlias('api-client')
}, {
find: '@bytelyst/design-tokens',
replacement: path.join(commonPlatRoot, 'packages', 'design-tokens')
}, {
find: '@bytelyst/errors',
replacement: bytelystAlias('errors')
}, {
find: '@bytelyst/kill-switch-client',
replacement: bytelystAlias('kill-switch-client')
}, {
find: '@bytelyst/react-auth',
replacement: bytelystAlias('react-auth')
}, {
find: '@bytelyst/telemetry-client',
replacement: bytelystAlias('telemetry-client')
}, {
find: '@bytelyst/ui',
replacement: bytelystAlias('ui')
},
// Monaco is an explicit web dependency, but this workspace often runs
// against pnpm's root store without a web/node_modules symlink when the
// private mobile registry is unavailable. Keep local worker imports
// resolvable for Vite in that partially installed state.
{
find: /^monaco-editor$/,
replacement: monacoEditorPath
}, {
find: /^monaco-editor\/(.+)/,
replacement: `${monacoEditorPath}/$1`
},
// General catch-all: every other @bytelyst/* → web/node_modules
{
find: /^@bytelyst\/(.+)/,
replacement: path.resolve(__dirname, 'node_modules/@bytelyst/$1')
}]
},
build: {
chunkSizeWarningLimit: 5000,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('monaco-editor') || id.includes('@monaco-editor')) {
return 'monaco-vendor';
}
if (id.includes('/node_modules/lucide-react/')) {
return 'ui-vendor';
}
if (id.includes('/node_modules/')) {
return 'vendor';
}
return undefined;
}
}
}
},
test: {
projects: [{
extends: true,
test: {
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts'],
include: ['src/**/*.test.ts', 'src/**/*.test.tsx', 'src/**/*.dom.test.tsx']
}
}, {
extends: true,
plugins: [
// The plugin will run tests for the stories defined in your Storybook config
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
storybookTest({
configDir: path.join(dirname, '.storybook')
})],
test: {
name: 'storybook',
browser: {
enabled: true,
headless: true,
provider: playwright({}),
instances: [{
browser: 'chromium'
}]
}
}
}]
}
});