Skip to content
Open
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ docs/public/static/blog/feed/*
.nx/workspace-data
screenshots
packed
test-results
.env

# typescript
*.tsbuildinfo
Expand Down
2 changes: 1 addition & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {
],
recursive: true,
timeout: (process.env.CIRCLECI === 'true' ? 5 : 2) * 1000, // Circle CI has low-performance CPUs.
reporter: 'dot',
reporter: 'spec',
require: ['@mui/internal-test-utils/setupBabel', '@mui/internal-test-utils/setupJSDOM'],
'watch-ignore': [
// default
Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"@mui/internal-test-utils": "workspace:^",
"@playwright/test": "^1.56.1",
"@types/autosuggest-highlight": "^3.2.3",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/chance": "^1.1.7",
"@types/css-mediaquery": "^0.1.4",
"@types/fg-loadcss": "^3.1.3",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@
"@babel/plugin-transform-react-constant-elements": "^7.27.1",
"@mui-internal/api-docs-builder": "workspace:^",
"@mui-internal/api-docs-builder-core": "workspace:^",
"@mui/internal-bundle-size-checker": "^1.0.9-canary.55",
"@mui/internal-babel-plugin-minify-errors": "^2.0.8-canary.11",
"@mui/internal-bundle-size-checker": "^1.0.9-canary.55",
"@mui/internal-code-infra": "^0.0.3-canary.51",
"@mui/internal-docs-utils": "workspace:^",
"@mui/internal-netlify-cache": "^0.0.2-canary.1",
Expand All @@ -116,8 +116,8 @@
"@next/eslint-plugin-next": "^15.5.6",
"@octokit/rest": "^22.0.1",
"@pigment-css/react": "0.0.30",
"@pnpm/find-workspace-dir": "^1000.1.3",
"@playwright/test": "1.56.1",
"@pnpm/find-workspace-dir": "^1000.1.3",
"@types/babel__core": "^7.20.5",
"@types/babel__register": "^7.17.3",
"@types/mocha": "^10.0.10",
Expand Down
2 changes: 1 addition & 1 deletion packages-internal/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"devDependencies": {
"@babel/register": "^7.28.3",
"@types/babel__core": "^7.20.5",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/doctrine": "^0.0.9",
"@types/node": "^20.19.25",
"@types/react": "^19.2.4",
Expand Down
4 changes: 3 additions & 1 deletion packages-internal/test-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.6.1",
"assertion-error": "^2.0.1",
"chai-dom": "^1.12.1",
"dom-accessibility-api": "^0.7.0",
"es-toolkit": "^1.41.0",
Expand All @@ -59,9 +60,10 @@
},
"devDependencies": {
"@playwright/test": "^1.56.1",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/chai-dom": "^1.11.3",
"@types/format-util": "^1.0.4",
"@types/jsdom": "^21.1.7",
"@types/prop-types": "^15.7.15",
"@types/react": "^19.2.4",
"@types/react-dom": "^19.2.3",
Expand Down
8 changes: 0 additions & 8 deletions packages-internal/test-utils/src/chai-augmentation.d.ts

This file was deleted.

5 changes: 3 additions & 2 deletions packages-internal/test-utils/src/chaiPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as chai from 'chai';
import { computeAccessibleDescription, computeAccessibleName } from 'dom-accessibility-api';
import formatUtil from 'format-util';
import { kebabCase } from 'es-toolkit/string';
import { AssertionError } from 'assertion-error';
import './chai.types';

const isKarma = Boolean(process.env.KARMA);
Expand Down Expand Up @@ -315,7 +316,7 @@ const chaiPlugin: Parameters<typeof chai.use>[0] = (chaiAPI, utils) => {
const element = utils.flag(this, 'object') as HTMLElement;
if (element?.nodeType !== 1) {
// Same pre-condition for negated and unnegated assertion
throw new chai.AssertionError(`Expected an Element but got ${String(element)}`);
throw new AssertionError(`Expected an Element but got ${String(element)}`);
}

assertMatchingStyles.call(this, element.style, expectedStyleUnnormalized, {
Expand All @@ -330,7 +331,7 @@ const chaiPlugin: Parameters<typeof chai.use>[0] = (chaiAPI, utils) => {
const element = utils.flag(this, 'object') as HTMLElement;
if (element?.nodeType !== 1) {
// Same pre-condition for negated and unnegated assertion
throw new chai.AssertionError(`Expected an Element but got ${String(element)}`);
throw new AssertionError(`Expected an Element but got ${String(element)}`);
}
const computedStyle = element.ownerDocument.defaultView!.getComputedStyle(element);

Expand Down
95 changes: 80 additions & 15 deletions packages-internal/test-utils/src/createRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { userEvent } from '@testing-library/user-event';
import * as React from 'react';
import * as ReactDOMServer from 'react-dom/server';
import { useFakeTimers } from 'sinon';
import { VitestUtils } from 'vitest';
import reactMajor from './reactMajor';

function queryAllDescriptionsOf(baseElement: HTMLElement, element: Element): HTMLElement[] {
Expand Down Expand Up @@ -200,36 +201,76 @@ function createVitestClock(
defaultMode: 'fake' | 'real',
config: ClockConfig,
options: Exclude<Parameters<typeof useFakeTimers>[0], number | Date>,
vi: any,
vi: import('vitest').VitestUtils,
): Clock {
if (defaultMode === 'fake') {
beforeEach(() => {
vi.useFakeTimers(options);
vi.useFakeTimers({
now: config,
// useIsFocusVisible schedules a global timer that needs to persist regardless of whether components are mounted or not.
// Technically we'd want to reset all modules between tests but we don't have that technology.
// In the meantime just continue to clear native timers like we did for the past years when using `sinon` < 8.
shouldClearNativeTimers: true,
toFake: [
'setTimeout',
'setInterval',
'clearTimeout',
'clearInterval',
'requestAnimationFrame',
'cancelAnimationFrame',
'performance',
'Date',
],
...options,
});
if (config) {
vi.setSystemTime(config);
}
});
afterEach(() => {
vi.useRealTimers();
});
} else {
beforeEach(() => {
if (config) {
vi.setSystemTime(config);
}
});
afterEach(() => {
vi.useRealTimers();
});
}

afterEach(async () => {
if (vi.isFakeTimers()) {
await rtlAct(async () => {
vi.runOnlyPendingTimers();
});
vi.useRealTimers();
}
});

return {
withFakeTimers: () => {
if (vi.isFakeTimers()) {
return;
}
beforeEach(() => {
vi.useFakeTimers(options);
});
afterEach(() => {
vi.useRealTimers();
vi.useFakeTimers({
now: config,
// useIsFocusVisible schedules a global timer that needs to persist regardless of whether components are mounted or not.
// Technically we'd want to reset all modules between tests but we don't have that technology.
// In the meantime just continue to clear native timers like we did for the past years when using `sinon` < 8.
shouldClearNativeTimers: true,
toFake: [
'setTimeout',
'setInterval',
'clearTimeout',
'clearInterval',
'requestAnimationFrame',
'cancelAnimationFrame',
'performance',
'Date',
],
...options,
});
if (config) {
vi.setSystemTime(config);
}
});
},
runToLast: () => {
Expand Down Expand Up @@ -351,7 +392,7 @@ export interface CreateRendererOptions extends Pick<RenderOptions, 'strict' | 's
* Vitest needs to be injected because this file is transpiled to commonjs and vitest is an esm module.
* @default {}
*/
vi?: any;
vi?: VitestUtils;
}

export function createRenderer(globalOptions: CreateRendererOptions = {}): Renderer {
Expand All @@ -360,7 +401,7 @@ export function createRenderer(globalOptions: CreateRendererOptions = {}): Rende
clockConfig,
strict: globalStrict = true,
strictEffects: globalStrictEffects = globalStrict,
vi = (globalThis as any).vi,
vi = (globalThis as any).vi as typeof import('vitest').vi | undefined,
clockOptions,
} = globalOptions;
// save stack to re-use in test-hooks
Expand Down Expand Up @@ -615,6 +656,30 @@ function act<T>(callback: () => void | T | Promise<T>) {

const bodyBoundQueries = within(document.body, { ...queries, ...customQueries });

export * from '@testing-library/react/pure';
export { renderHook, waitFor, within } from '@testing-library/react/pure';
export { act, fireEvent };
export const screen: Screen & typeof bodyBoundQueries = { ...rtlScreen, ...bodyBoundQueries };

export async function flushEffects(): Promise<void> {
await act(async () => {});
}

/**
* returns true when touch is suported and can be mocked
*/
export function supportsTouch() {
// only run in supported browsers
if (typeof Touch === 'undefined') {
return false;
}

try {
// eslint-disable-next-line no-new
new Touch({ identifier: 0, target: window, pageX: 0, pageY: 0 });
} catch {
// Touch constructor not supported
return false;
}

return true;
}
9 changes: 3 additions & 6 deletions packages-internal/test-utils/src/initPlaywrightMatchers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as chai from 'chai';
import * as DomTestingLibrary from '@testing-library/dom';
import type { ElementHandle } from '@playwright/test';
import { AssertionError } from 'assertion-error';

// https://stackoverflow.com/a/46755166/3406963
declare global {
Expand Down Expand Up @@ -33,9 +34,7 @@ chai.use((chaiAPI, utils) => {
chai.Assertion.addMethod('toHaveFocus', async function elementHandleIsFocused() {
const $elementOrHandle: ElementHandle | Promise<ElementHandle> = utils.flag(this, 'object');
if ($elementOrHandle == null) {
throw new chai.AssertionError(
`Expected an element handle but got ${String($elementOrHandle)}.`,
);
throw new AssertionError(`Expected an element handle but got ${String($elementOrHandle)}.`);
}
const $element =
typeof ($elementOrHandle as Promise<any>).then === 'function'
Expand Down Expand Up @@ -68,9 +67,7 @@ chai.use((chaiAPI, utils) => {
async function elementHandleHasAttribute(attributeName: string, attributeValue?: string) {
const $elementOrHandle: ElementHandle | Promise<ElementHandle> = utils.flag(this, 'object');
if ($elementOrHandle == null) {
throw new chai.AssertionError(
`Expected an element handle but got ${String($elementOrHandle)}.`,
);
throw new AssertionError(`Expected an element handle but got ${String($elementOrHandle)}.`);
}
const $element =
typeof ($elementOrHandle as Promise<any>).then === 'function'
Expand Down
3 changes: 1 addition & 2 deletions packages-internal/test-utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react",
// https://github.com/vitest-dev/vitest/issues/4688
// TODO: Remove after fully migrated chai to vitest
// Remove when https://github.com/thomasbrodusch/vitest-fail-on-console/issues/160 is resolved
"skipLibCheck": true
},
"include": ["./src/**/*"]
Expand Down
2 changes: 1 addition & 1 deletion packages/api-docs-builder-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"es-toolkit": "^1.41.0"
},
"devDependencies": {
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/mocha": "^10.0.10",
"@types/node": "^20.19.25",
"@types/sinon": "^17.0.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/api-docs-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"devDependencies": {
"@types/babel__core": "^7.20.5",
"@types/babel__traverse": "^7.28.0",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/doctrine": "^0.0.9",
"@types/mdast": "4.0.4",
"@types/mocha": "^10.0.10",
Expand Down
2 changes: 1 addition & 1 deletion packages/markdown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"prismjs": "^1.30.0"
},
"devDependencies": {
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"chai": "^6.0.1"
},
"publishConfig": {
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-codemod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"devDependencies": {
"@material-ui/core": "^4.12.4",
"@mui/material-v5": "npm:@mui/[email protected]",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/jscodeshift": "0.12.0",
"chai": "^6.0.1"
},
Expand Down
1 change: 1 addition & 0 deletions packages/mui-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"devDependencies": {
"@mui/icons-material": "workspace:*",
"@mui/material": "workspace:*",
"@types/chai": "^5.2.2",
"@types/gtag.js": "^0.0.20",
"@types/node": "^20.19.25",
"@types/prop-types": "^15.7.15",
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-envinfo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"envinfo": "^7.20.0"
},
"devDependencies": {
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"chai": "^6.0.1"
},
"publishConfig": {
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-icons-material/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@mui/icons-material": "workspace:*",
"@mui/internal-waterfall": "workspace:^",
"@mui/material": "workspace:^",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/react": "^19.2.4",
"chai": "^6.0.1",
"chalk": "^5.6.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"devDependencies": {
"@mui/internal-test-utils": "workspace:^",
"@mui/material": "workspace:^",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/prop-types": "^15.7.15",
"@types/react": "^19.2.4",
"@types/react-dom": "^19.2.3",
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/MenuItem/MenuItem.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { act, createRenderer, fireEvent, screen } from '@mui/internal-test-utils';
import { act, createRenderer, fireEvent, screen, supportsTouch } from '@mui/internal-test-utils';
import { MenuProvider, MenuProviderValue } from '@mui/base/useMenu';
import { ThemeProvider } from '@mui/joy/styles';
import MenuItem, { menuItemClasses as classes } from '@mui/joy/MenuItem';
Expand Down Expand Up @@ -142,7 +142,7 @@ describe('Joy <MenuItem />', () => {

it('should fire onTouchStart', function touchStartTest() {
// only run in supported browsers
if (typeof Touch === 'undefined') {
if (!supportsTouch()) {
this.skip();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/mui-lab/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"devDependencies": {
"@mui/internal-test-utils": "workspace:^",
"@mui/material": "workspace:^",
"@types/chai": "^4.3.20",
"@types/chai": "^5.2.2",
"@types/prop-types": "^15.7.15",
"@types/react": "^19.2.4",
"@types/react-dom": "^19.2.3",
Expand Down
Loading
Loading