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

[test] Run tests with vitest #749

Merged
merged 17 commits into from
Oct 29, 2024
Merged
16 changes: 8 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,17 +150,17 @@ jobs:
- install_js:
react-version: << parameters.react-version >>
- run:
name: Tests fake browser
command: pnpm test:coverage:ci
name: Run tests on JSDOM
command: pnpm test:jsdom --coverage
- run:
name: Check coverage generated
name: Check if coverage report is generated
command: |
if ! [[ -s coverage/lcov.info ]]
then
exit 1
fi
- run:
name: Coverage
name: Upload coverage report to Codecov
command: |
curl -Os https://uploader.codecov.io/latest/linux/codecov
chmod +x codecov
Expand Down Expand Up @@ -295,17 +295,17 @@ jobs:
react-version: << parameters.react-version >>
browsers: true
- run:
name: Tests real browsers
command: pnpm test:karma
name: Run tests on headless Chromium
command: pnpm test:chromium --coverage
- run:
name: Check coverage generated
name: Check if coverage report is generated
command: |
if ! [[ -s coverage/lcov.info ]]
then
exit 1
fi
- run:
name: Coverage
name: Upload coverage report to Codecov
command: |
curl -Os https://uploader.codecov.io/latest/linux/codecov
chmod +x codecov
Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"@babel/preset-typescript": "^7.24.7",
"@mui/internal-docs-utils": "^1.0.15",
"@mui/internal-scripts": "^1.0.25",
"@mui/internal-test-utils": "1.0.18",
"@mui/internal-test-utils": "https://pkg.csb.dev/mui/material-ui/commit/92c23999/@mui/internal-test-utils",
"@types/chai": "^4.3.20",
"@types/gtag.js": "^0.0.20",
"@types/hast": "^3.0.4",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/blocks/sandbox/packDemo.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, it } from 'mocha';
import { describe, it } from 'vitest';
import { expect } from 'chai';
import { DemoFile } from 'docs/src/blocks/Demo';
import { packDemo } from './packDemo';
Expand Down
15 changes: 15 additions & 0 deletions docs/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { mergeConfig, defineProject } from 'vitest/config';
import sharedConfig from '../vitest.shared';

export default mergeConfig(
sharedConfig,
defineProject({
test: {
environment: 'node',
browser: {
enabled: false,
name: 'node',
},
},
}),
);
13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
"test:regressions:server": "serve test/regressions -p 5001",
"test:umd": "node packages/mui-material/test/umd/run.js",
"test:unit": "cross-env NODE_ENV=test mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}'",
"test:jsdom": "cross-env NODE_ENV=test VITEST_ENV=jsdom vitest",
"test:chromium": "cross-env NODE_ENV=test VITEST_ENV=chromium vitest",
"test:firefox": "cross-env NODE_ENV=test VITEST_ENV=firefox vitest",
"test:argos": "node ./scripts/pushArgos.mjs",
"typescript": "tsc -b tsconfig.json",
"validate-declarations": "tsx scripts/validateTypescriptDeclarations.mts",
Expand All @@ -79,7 +82,7 @@
"@mui/internal-docs-utils": "^1.0.15",
"@mui/internal-markdown": "^1.0.18",
"@mui/internal-scripts": "^1.0.25",
"@mui/internal-test-utils": "1.0.18",
"@mui/internal-test-utils": "https://pkg.csb.dev/mui/material-ui/commit/92c23999/@mui/internal-test-utils",
"@mui/monorepo": "github:mui/material-ui#v6.1.5",
"@mui/utils": "6.1.5",
"@next/eslint-plugin-next": "^14.2.13",
Expand All @@ -93,13 +96,18 @@
"@types/yargs": "^17.0.33",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"@vitejs/plugin-react": "^4.3.2",
"@vitest/browser": "^2.1.3",
"@vitest/coverage-v8": "^2.1.3",
"@vitest/ui": "2.1.3",
"babel-loader": "^9.2.1",
"babel-plugin-istanbul": "^6.1.1",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-module-resolver": "^5.0.2",
"babel-plugin-optimize-clsx": "^2.6.2",
"babel-plugin-react-remove-properties": "^0.3.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"chai-dom": "^1.12.0",
"chalk": "^5.3.0",
"compression-webpack-plugin": "^11.1.0",
"concurrently": "^8.2.2",
Expand Down Expand Up @@ -149,7 +157,9 @@
"prettier-plugin-tailwindcss": "^0.6.8",
"pretty-quick": "^4.0.0",
"process": "^0.11.10",
"react": "^18.3.1",
"react-docgen": "^5.4.3",
"react-dom": "^18.3.1",
"recast": "^0.23.9",
"remark": "^15.0.1",
"rimraf": "^5.0.10",
Expand All @@ -163,6 +173,7 @@
"tsx": "^4.8.2",
"typescript": "^5.4.5",
"unist-util-visit": "^5.0.0",
"vitest": "^2.1.3",
"webpack": "^5.91.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^5.1.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"use-sync-external-store": "^1.2.2"
},
"devDependencies": {
"@mui/internal-test-utils": "1.0.18",
"@mui/internal-test-utils": "https://pkg.csb.dev/mui/material-ui/commit/92c23999/@mui/internal-test-utils",
"@testing-library/react": "^16.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/chai": "^4.3.20",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
// This file must be present for the doc gen to work

describe('<AlertDialogRoot />', () => {
it('no-op', () => {});
});
20 changes: 6 additions & 14 deletions packages/mui-base/src/Checkbox/Root/CheckboxRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,7 @@ describe('<Checkbox.Root />', () => {
});

describe('form handling', () => {
it('should toggle the checkbox when a parent label is clicked', async function test() {
// Clicking the label causes unrelated browser tests to fail.
if (!isJSDOM) {
this.skip();
}

it('should toggle the checkbox when a parent label is clicked', async () => {
const { getByTestId, getAllByRole } = await render(
<label data-testid="label">
<Checkbox.Root />
Expand All @@ -246,12 +241,7 @@ describe('<Checkbox.Root />', () => {
expect(checkbox).to.have.attribute('aria-checked', 'true');
});

it('should toggle the checkbox when a linked label is clicked', async function test() {
// Clicking the label causes unrelated browser tests to fail.
if (!isJSDOM) {
this.skip();
}

it('should toggle the checkbox when a linked label is clicked', async () => {
const { getByTestId, getAllByRole } = await render(
<div>
<label htmlFor="test-checkbox" data-testid="label">
Expand All @@ -274,10 +264,12 @@ describe('<Checkbox.Root />', () => {
});
});

it('should include the checkbox value in the form submission', async function test() {
it('should include the checkbox value in the form submission', async function test(t = {}) {
if (isJSDOM) {
// FormData is not available in JSDOM
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

let stringifiedFormData = '';
Expand Down
22 changes: 15 additions & 7 deletions packages/mui-base/src/Collapsible/Root/CollapsibleRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { createRenderer, act } from '@mui/internal-test-utils';
import { createRenderer, act, describeSkipIf } from '@mui/internal-test-utils';
import { Collapsible } from '@base_ui/react/Collapsible';
import { describeConformance } from '../../../test/describeConformance';

Expand All @@ -20,7 +20,7 @@ describe('<Collapsible.Root />', () => {
describe('ARIA attributes', () => {
it('sets ARIA attributes', async () => {
const { getByTestId, getByRole } = await render(
<Collapsible.Root>
<Collapsible.Root animated={false}>
<Collapsible.Trigger />
<Collapsible.Content data-testid="content" />
</Collapsible.Root>,
Expand Down Expand Up @@ -64,7 +64,13 @@ describe('<Collapsible.Root />', () => {
expect(content).to.have.attribute('hidden');
});

it('uncontrolled mode', async () => {
it('uncontrolled mode', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}
Comment on lines +69 to +72
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No way to make this cleaner?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet. We'll get rid of this once we drop mocha completely (= soon, I hope)


const { getByTestId, getByRole, user } = await render(
<Collapsible.Root defaultOpen={false} animated={false}>
<Collapsible.Trigger />
Expand Down Expand Up @@ -93,7 +99,7 @@ describe('<Collapsible.Root />', () => {
});
});

describe('keyboard interactions', () => {
describeSkipIf(/jsdom/.test(window.navigator.userAgent))('keyboard interactions', () => {
['Enter', 'Space'].forEach((key) => {
it(`key: ${key} should toggle the Collapsible`, async () => {
const { getByTestId, getByRole, user } = await render(
Expand Down Expand Up @@ -128,10 +134,12 @@ describe('<Collapsible.Root />', () => {
});

describe('prop: htmlHidden', () => {
it('supports "hidden until found" state', async function test() {
it('supports "hidden until found" state', async function test(t = {}) {
// we test firefox in browserstack which does not support this yet
if (!('onbeforematch' in window)) {
this.skip();
if (!('onbeforematch' in window) || /jsdom/.test(window.navigator.userAgent)) {
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

const handleOpenChange = spy();
Expand Down
18 changes: 3 additions & 15 deletions packages/mui-base/src/Dialog/Root/DialogRoot.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, fireEvent, waitFor } from '@mui/internal-test-utils';
import { act, describeSkipIf, fireEvent, waitFor } from '@mui/internal-test-utils';
import { Dialog } from '@base_ui/react/Dialog';
import { createRenderer } from '#test-utils';

Expand Down Expand Up @@ -123,13 +123,7 @@ describe('<Dialog.Root />', () => {
});
});

describe('prop: animated', () => {
before(function test() {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
}
});

describeSkipIf(/jsdom/.test(window.navigator.userAgent))('prop: animated', () => {
const css = `
.dialog {
opacity: 0;
Expand Down Expand Up @@ -168,13 +162,7 @@ describe('<Dialog.Root />', () => {
});
});

describe('focus management', () => {
before(function test() {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
}
});

describeSkipIf(/jsdom/.test(window.navigator.userAgent))('focus management', () => {
it('should focus the first focusable element within the popup', async () => {
const { getByText, getByTestId } = await render(
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ describe('<Menu.CheckboxItem />', () => {
refInstanceof: window.HTMLDivElement,
}));

it('perf: does not rerender menu items unnecessarily', async function test() {
it('perf: does not rerender menu items unnecessarily', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

const renderItem1Spy = spy();
Expand Down
6 changes: 4 additions & 2 deletions packages/mui-base/src/Menu/Item/MenuItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ describe('<Menu.Item />', () => {
refInstanceof: window.HTMLDivElement,
}));

it('perf: does not rerender menu items unnecessarily', async function test() {
it('perf: does not rerender menu items unnecessarily', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

const renderItem1Spy = spy();
Expand Down
30 changes: 19 additions & 11 deletions packages/mui-base/src/Menu/Positioner/MenuPositioner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ describe('<Menu.Positioner />', () => {
}));

describe('prop: anchor', () => {
it('should be placed near the specified element when a ref is passed', async function test() {
it('should be placed near the specified element when a ref is passed', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

function TestComponent() {
const anchor = React.useRef<HTMLDivElement | null>(null);

return (
<div>
<div style={{ margin: '50px' }}>
<Menu.Root open animated={false}>
<Menu.Positioner side="bottom" alignment="start" anchor={anchor} arrowPadding={0}>
<Menu.Popup>
Expand Down Expand Up @@ -82,9 +84,11 @@ describe('<Menu.Positioner />', () => {
);
});

it('should be placed near the specified element when an element is passed', async function test() {
it('should be placed near the specified element when an element is passed', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

function TestComponent() {
Expand All @@ -94,7 +98,7 @@ describe('<Menu.Positioner />', () => {
}, []);

return (
<div>
<div style={{ margin: '50px' }}>
<Menu.Root open animated={false}>
<Menu.Positioner side="bottom" alignment="start" anchor={anchor} arrowPadding={0}>
<Menu.Popup>
Expand Down Expand Up @@ -122,9 +126,11 @@ describe('<Menu.Positioner />', () => {
);
});

it('should be placed near the specified element when a function returingn an element is passed', async function test() {
it('should be placed near the specified element when a function returning an element is passed', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

function TestComponent() {
Expand All @@ -136,7 +142,7 @@ describe('<Menu.Positioner />', () => {
const getAnchor = React.useCallback(() => anchor, [anchor]);

return (
<div>
<div style={{ margin: '50px' }}>
<Menu.Root open animated={false}>
<Menu.Positioner side="bottom" alignment="start" anchor={getAnchor} arrowPadding={0}>
<Menu.Popup>
Expand Down Expand Up @@ -164,9 +170,11 @@ describe('<Menu.Positioner />', () => {
);
});

it('should be placed at the specified position', async function test() {
it('should be placed at the specified position', async function test(t = {}) {
if (/jsdom/.test(window.navigator.userAgent)) {
this.skip();
// @ts-expect-error to support mocha and vitest
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this?.skip?.() || t?.skip();
}

const boundingRect = {
Expand Down
Loading