Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[code-infra] Remove lazy require.context from regression tests #44964

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@
"test:karma": "nx run nx_test_karma",
"test:karma:profile": "nx run nx_test_karma_profile",
"test:regressions": "cross-env NODE_ENV=production pnpm test:regressions:build && concurrently --success first --kill-others \"pnpm test:regressions:run\" \"pnpm test:regressions:server\"",
"test:regressions:build": "webpack --config test/regressions/webpack.config.js",
"test:regressions:dev": "concurrently \"pnpm test:regressions:build --watch\" \"pnpm test:regressions:server\"",
"test:regressions:build": "vite build test/regressions",
"test:regressions:dev": "vite test/regressions --port 5001",
"test:regressions:run": "nx run nx_test_regressions_run",
"test:regressions:server": "serve test/regressions -p 5001",
"test:regressions:server": "vite preview test/regressions --port 5001",
"test:regressions-pigment-css": "cross-env NODE_ENV=production pnpm test:regressions-pigment-css:build && concurrently --success first --kill-others \"pnpm test:regressions-pigment-css:run\" \"pnpm test:regressions-pigment-css:server\"",
"test:regressions-pigment-css:build": "pnpm --filter @app/vite-app run build",
"test:regressions-pigment-css:dev": "concurrently \"pnpm test:regressions-pigment-css:build --watch\" \"pnpm test:regressions-pigment-css:server\"",
Expand Down Expand Up @@ -138,6 +138,8 @@
"@typescript-eslint/parser": "^7.18.0",
"@vitest/browser": "^2.1.8",
"@vitest/coverage-v8": "^2.1.8",
"@vitejs/plugin-react": "^4.3.4",
"vite": "^6.0.7",
"babel-loader": "^9.2.1",
"babel-plugin-istanbul": "^7.0.0",
"babel-plugin-module-resolver": "^5.0.2",
Expand Down
641 changes: 500 additions & 141 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

34 changes: 16 additions & 18 deletions test/regressions/TestViewer.js → test/regressions/TestViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,27 @@ function TestViewer(props) {
},
}}
/>
<React.Suspense fallback={<div aria-busy />}>
{window.location.pathname.startsWith('/docs-joy') ? (
<CssVarsProvider>
<JoyBox
aria-busy={!ready}
data-testid="testcase"
data-testpath={path}
sx={{ bgcolor: 'background.body', ...viewerBoxSx }}
>
{children}
</JoyBox>
</CssVarsProvider>
) : (
<Box
{path.startsWith('/docs-joy') ? (
<CssVarsProvider>
<JoyBox
aria-busy={!ready}
data-testid="testcase"
data-testpath={path}
sx={{ bgcolor: 'background.default', ...viewerBoxSx }}
sx={{ bgcolor: 'background.body', ...viewerBoxSx }}
>
{children}
</Box>
)}
</React.Suspense>
</JoyBox>
</CssVarsProvider>
) : (
<Box
aria-busy={!ready}
data-testid="testcase"
data-testpath={path}
sx={{ bgcolor: 'background.default', ...viewerBoxSx }}
>
{children}
</Box>
)}
</React.Fragment>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
<body>
<div id="test-viewer"></div>
<div id="react-root"></div>
<script type="module" src="/index.jsx"></script>
</body>
</html>
126 changes: 73 additions & 53 deletions test/regressions/index.js → test/regressions/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ window.muiFixture = {
};

// Get all the fixtures specifically written for preventing visual regressions.
const importRegressionFixtures = require.context('./fixtures', true, /\.(js|ts|tsx)$/, 'lazy');
const importRegressionFixtures = import.meta.glob(['./fixtures/**/*.(js|ts|tsx)'], {
import: 'default',
eager: true,
});

const regressionFixtures = [];
importRegressionFixtures.keys().forEach((path) => {

Object.keys(importRegressionFixtures).forEach((path) => {
const [suite, name] = path
.replace('./', '')
.replace('./fixtures/', '')
.replace(/\.\w+$/, '')
.split('/');

Expand All @@ -33,7 +38,7 @@ importRegressionFixtures.keys().forEach((path) => {
path,
suite: `regression-${suite}`,
name,
Component: React.lazy(() => importRegressionFixtures(path)),
Component: importRegressionFixtures[path],
});
}
}, []);
Expand Down Expand Up @@ -269,10 +274,34 @@ function excludeDemoFixture(suite, name) {
}

// Also use some of the demos to avoid code duplication.
const importDemos = require.context('docs/data', true, /(?<!pagesApi)\.js$/, 'lazy');
const importDemos = import.meta.glob(
[
'../../docs/data/*/**/*.js',
'!**/*.d.ts',
'!**.preview',
'!**/.eslintrc.js',
'!**/pages.ts',
'!**/pagesApi.js',
'!**/SearchIcons.js',
'!**/getting-started/**',
'!**/docs-guides/**',
'!**/material-icons/SearchIcons.js',
],
{
import: 'default',
eager: true,
},
);

console.log(importDemos);

const demoFixtures = [];
importDemos.keys().forEach((path) => {
const [name, ...suiteArray] = path.replace('./', '').replace('.js', '').split('/').reverse();
Object.keys(importDemos).forEach((path) => {
const [name, ...suiteArray] = path
.replace('./docs/data/', '')
.replace('.js', '')
.split('/')
.reverse();
const suite = `docs-${suiteArray
.reverse()
.join('-')
Expand All @@ -285,7 +314,7 @@ importDemos.keys().forEach((path) => {
path,
suite,
name,
Component: React.lazy(() => importDemos(path)),
Component: importDemos[path],
});
}
}, []);
Expand All @@ -298,32 +327,26 @@ if (unusedBlacklistPatterns.size > 0) {
);
}

const viewerRoot = document.getElementById('test-viewer');

function FixtureRenderer({ component: FixtureComponent, path }) {
const viewerReactRoot = React.useRef(null);

React.useLayoutEffect(() => {
const renderTimeout = setTimeout(() => {
const children = (
<TestViewer path={path}>
React.useEffect(() => {
const viewerRoot = document.getElementById('test-viewer');
const testRoot = document.createElement('div');
viewerRoot.appendChild(testRoot);
const reactRoot = ReactDOMClient.createRoot(testRoot);
React.startTransition(() => {
reactRoot.render(
<TestViewer path={path} FixtureComponent={FixtureComponent}>
<FixtureComponent />
</TestViewer>
</TestViewer>,
);

if (viewerReactRoot.current === null) {
viewerReactRoot.current = ReactDOMClient.createRoot(viewerRoot);
}

viewerReactRoot.current.render(children);
});

return () => {
clearTimeout(renderTimeout);
setTimeout(() => {
viewerReactRoot.current.unmount();
viewerReactRoot.current = null;
});
reactRoot.unmount();
}, 0);

viewerRoot.removeChild(testRoot);
};
}, [FixtureComponent, path]);

Expand Down Expand Up @@ -384,8 +407,6 @@ function App(props) {
});
}, []);

const fixturePrepared = fontState !== 'pending';

function computePath(fixture) {
return `/${fixture.suite}/${fixture.name}`;
}
Expand All @@ -397,29 +418,27 @@ function App(props) {

return (
<React.Fragment>
<Routes>
{fixtures.map((fixture) => {
const path = computePath(fixture);
const FixtureComponent = fixture.Component;
if (FixtureComponent === undefined) {
console.warn('Missing `Component` for ', fixture);
return null;
}

return (
<Route
key={path}
exact
path={path}
element={
fixturePrepared ? (
<FixtureRenderer component={FixtureComponent} path={path} />
) : null
}
/>
);
})}
</Routes>
{fontState === 'active' ? (
<Routes>
{fixtures.map((fixture) => {
const path = computePath(fixture);
const FixtureComponent = fixture.Component;
if (FixtureComponent === undefined) {
console.warn('Missing `Component` for ', fixture);
return null;
}

return (
<Route
key={path}
exact
path={path}
element={<FixtureRenderer component={FixtureComponent} path={path} />}
/>
);
})}
</Routes>
) : null}

{isDev ? (
<div>
Expand All @@ -436,6 +455,7 @@ function App(props) {
<ol>
{fixtures.map((fixture) => {
const path = computePath(fixture);

return (
<li key={path}>
<Link to={path}>{path}</Link>
Expand All @@ -458,7 +478,7 @@ App.propTypes = {
const container = document.getElementById('react-root');
const children = (
<Router>
<App fixtures={regressionFixtures.concat(demoFixtures)} />{' '}
<App fixtures={regressionFixtures.concat(demoFixtures)} />
</Router>
);
const reactRoot = ReactDOMClient.createRoot(container);
Expand Down
26 changes: 26 additions & 0 deletions test/regressions/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"tsBuildInfoFile": "../node_modules/.tmp/regressions/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}
4 changes: 4 additions & 0 deletions test/regressions/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"files": [],
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
}
24 changes: 24 additions & 0 deletions test/regressions/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "../node_modules/.tmp/regressions/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
Loading
Loading