Files
react-test/vitest.shared.mts
how2ice 005cf56baf
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
init project
2025-12-12 14:26:25 +09:00

175 lines
5.6 KiB
TypeScript

import 'dotenv/config';
import { configDefaults, defineProject } from 'vitest/config';
import * as fs from 'fs/promises';
import * as path from 'path';
import { fileURLToPath } from 'url';
import react from '@vitejs/plugin-react';
import { Plugin, transformWithEsbuild } from 'vite';
import { playwright } from '@vitest/browser-playwright';
import { BrowserInstanceOption } from 'vitest/node';
function forceJsxForJsFiles(): Plugin {
return {
name: 'force-jsx-loader-for-js',
enforce: 'pre',
async transform(code, id) {
if (id.includes('/node_modules/')) {
return null;
}
if (!id.endsWith('.js')) {
return null;
}
const result = await transformWithEsbuild(code, id, {
loader: 'jsx',
});
// @vitejs/plugin-react only adds the React import for .jsx files.
if (!result.code.includes("from 'react'") && !result.code.includes('from "react"')) {
result.code = `import * as React from 'react';\n${result.code}`;
}
return result;
},
};
}
function getVitestEnvironment(fileName: string): 'browser' | 'node' {
const basename = path.basename(fileName);
if (basename.includes('.browser.')) {
return 'browser';
}
return 'node';
}
const MONOREPO_ROOT = path.resolve(__dirname, '.');
export interface CreateOptions {
jsdom?: boolean;
enableScrollbars?: boolean;
}
export default async function create(
fileUrl: string,
{ jsdom = false, enableScrollbars = false }: CreateOptions = {},
) {
const file = fileURLToPath(fileUrl);
const testEnv = getVitestEnvironment(file);
const pkgJson = path.resolve(file, '../package.json');
const pkg = await fs.readFile(pkgJson, 'utf8').then((content) => JSON.parse(content));
const name = `${testEnv}:${pkg.name}`;
const ignore = await fs.readFile(path.resolve(MONOREPO_ROOT, './.gitignore'), 'utf8');
const excludes = ignore
.trim()
.split('\n')
.filter((line) => line.startsWith('#'))
.map((line) => (line.startsWith('/') ? line.slice(1) : line));
return defineProject({
plugins: [react(), forceJsxForJsFiles()],
define: {
'process.env.NODE_ENV': JSON.stringify('test'),
},
test: {
name,
exclude: ['**/node_modules/**', '**/build/**', '**/*.spec.*', '**/.next/**', ...excludes],
globals: true,
disableConsoleIntercept: true,
setupFiles: [
path.resolve(MONOREPO_ROOT, './packages-internal/test-utils/src/setupVitest.ts'),
...(jsdom || testEnv === 'browser'
? [
path.resolve(
MONOREPO_ROOT,
'./packages-internal/test-utils/src/setupVitestBrowser.ts',
),
]
: []),
],
environment: jsdom ? 'jsdom' : 'node',
fakeTimers: {
// We use performance.now in the codebase
toFake: [...(configDefaults.fakeTimers.toFake ?? []), 'performance'],
},
browser: {
enabled: testEnv === 'browser',
provider: playwright({
launchOptions: {
ignoreDefaultArgs: [...(enableScrollbars ? ['--hide-scrollbars'] : [])],
},
}),
headless: true,
viewport: {
width: 1024,
height: 896,
},
instances: (process.env.VITEST_BROWSERS || 'chromium')
.split(',')
.map((browser) => ({ browser }) as BrowserInstanceOption),
screenshotFailures: false,
},
env: {
VITEST: 'true',
},
},
resolve: {
dedupe: ['react', 'react-dom'],
alias: {
'@mui/internal-test-utils': path.resolve(
MONOREPO_ROOT,
'./packages-internal/test-utils/src',
),
'@mui/internal-docs-utils': path.resolve(
MONOREPO_ROOT,
'./packages-internal/docs-utils/src',
),
'@mui/material': path.resolve(MONOREPO_ROOT, './packages/mui-material/src'),
'@mui/system': path.resolve(MONOREPO_ROOT, './packages/mui-system/src'),
'@mui/types': path.resolve(MONOREPO_ROOT, './packages/mui-types/src'),
'@mui/utils': path.resolve(MONOREPO_ROOT, './packages/mui-utils/src'),
'@mui/styled-engine': path.resolve(MONOREPO_ROOT, './packages/mui-styled-engine/src'),
'@mui/styled-engine-sc': path.resolve(MONOREPO_ROOT, './packages/mui-styled-engine-sc/src'),
'@mui/styles': path.resolve(MONOREPO_ROOT, './packages/mui-styles/src'),
'@mui/stylis-plugin-rtl': path.resolve(
MONOREPO_ROOT,
'./packages/mui-stylis-plugin-rtl/src',
),
'@mui/icons-material': path.resolve(MONOREPO_ROOT, './packages/mui-icons-material/lib/esm'),
'@mui/lab': path.resolve(MONOREPO_ROOT, './packages/mui-lab/src'),
'@mui/private-theming': path.resolve(MONOREPO_ROOT, './packages/mui-private-theming/src'),
'@mui/joy': path.resolve(MONOREPO_ROOT, './packages/mui-joy/src'),
'@mui/docs': path.resolve(MONOREPO_ROOT, './packages/mui-docs/src'),
'@mui/material-nextjs': path.resolve(MONOREPO_ROOT, './packages/mui-material-nextjs/src'),
docs: path.resolve(MONOREPO_ROOT, './docs'),
},
},
optimizeDeps: {
esbuildOptions: {
plugins: [
{
name: 'js-as-jsx',
setup(build) {
build.onLoad({ filter: /\.js$/ }, async (args) => {
if (args.path.includes('/node_modules/')) {
return null;
}
const contents = await fs.readFile(args.path, 'utf8');
return {
contents,
loader: 'jsx',
};
});
},
},
],
},
},
});
}