From 49eb46244adbb27a181c66c4f140416ac29ea390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dudak?= Date: Wed, 8 Jan 2025 10:45:43 +0100 Subject: [PATCH] Simplify controlling animations in tests --- .../alert-dialog/root/AlertDialogRoot.test.tsx | 2 +- .../indicator/CheckboxIndicator.test.tsx | 4 ++-- .../react/src/dialog/root/DialogRoot.test.tsx | 8 ++++---- packages/react/src/global.d.ts | 9 +++++++++ .../MenuCheckboxItemIndicator.test.tsx | 4 ++-- .../MenuRadioItemIndicator.test.tsx | 2 +- packages/react/src/menu/root/MenuRoot.test.tsx | 6 +++--- .../src/popover/root/PopoverRoot.test.tsx | 6 +++--- .../preview-card/root/PreviewCardRoot.test.tsx | 6 +++--- .../radio/indicator/RadioIndicator.test.tsx | 4 ++-- .../react/src/select/root/SelectRoot.test.tsx | 6 +++--- .../src/tooltip/root/TooltipRoot.test.tsx | 4 ++-- .../react/src/utils/useAnimationsFinished.ts | 5 +---- packages/react/tsconfig.test.json | 2 +- pnpm-lock.yaml | 3 +++ test/package.json | 1 + test/setupVitest.ts | 18 ++++++++++-------- test/tsconfig.json | 4 ++-- 18 files changed, 53 insertions(+), 41 deletions(-) create mode 100644 packages/react/src/global.d.ts diff --git a/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx b/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx index 0e85d28a21..607aa83523 100644 --- a/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx +++ b/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx @@ -169,7 +169,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx b/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx index cb828c893f..7a83c8fafc 100644 --- a/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx +++ b/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx @@ -18,7 +18,7 @@ const testContext = { describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render } = createRenderer(); @@ -132,7 +132,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { diff --git a/packages/react/src/dialog/root/DialogRoot.test.tsx b/packages/react/src/dialog/root/DialogRoot.test.tsx index 51145b7034..c2f14e2b7a 100644 --- a/packages/react/src/dialog/root/DialogRoot.test.tsx +++ b/packages/react/src/dialog/root/DialogRoot.test.tsx @@ -11,7 +11,7 @@ const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render } = createRenderer(); @@ -92,7 +92,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { @@ -384,7 +384,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; const notifyTransitionEnd = spy(); @@ -621,7 +621,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/global.d.ts b/packages/react/src/global.d.ts new file mode 100644 index 0000000000..836da4cddd --- /dev/null +++ b/packages/react/src/global.d.ts @@ -0,0 +1,9 @@ +declare global { + /** + * When `true`, disables animation-related code, even if supported by the runtime enviroment. + */ + // eslint-disable-next-line no-var, vars-on-top + var BASE_UI_ANIMATIONS_DISABLED: boolean; +} + +export type {}; diff --git a/packages/react/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.test.tsx b/packages/react/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.test.tsx index 977dd9f0e8..0f716c1d99 100644 --- a/packages/react/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.test.tsx +++ b/packages/react/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.test.tsx @@ -6,7 +6,7 @@ import { expect } from 'chai'; describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render } = createRenderer(); @@ -71,7 +71,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { diff --git a/packages/react/src/menu/radio-item-indicator/MenuRadioItemIndicator.test.tsx b/packages/react/src/menu/radio-item-indicator/MenuRadioItemIndicator.test.tsx index d78df03c54..52768f4686 100644 --- a/packages/react/src/menu/radio-item-indicator/MenuRadioItemIndicator.test.tsx +++ b/packages/react/src/menu/radio-item-indicator/MenuRadioItemIndicator.test.tsx @@ -76,7 +76,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { diff --git a/packages/react/src/menu/root/MenuRoot.test.tsx b/packages/react/src/menu/root/MenuRoot.test.tsx index 90d961364d..3861752820 100644 --- a/packages/react/src/menu/root/MenuRoot.test.tsx +++ b/packages/react/src/menu/root/MenuRoot.test.tsx @@ -11,7 +11,7 @@ const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render } = createRenderer(); @@ -757,7 +757,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { @@ -915,7 +915,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/popover/root/PopoverRoot.test.tsx b/packages/react/src/popover/root/PopoverRoot.test.tsx index 9b2e698454..f3302b6266 100644 --- a/packages/react/src/popover/root/PopoverRoot.test.tsx +++ b/packages/react/src/popover/root/PopoverRoot.test.tsx @@ -14,7 +14,7 @@ function Root(props: Popover.Root.Props) { describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render, clock } = createRenderer(); @@ -227,7 +227,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { @@ -574,7 +574,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx b/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx index cad25b4c61..4289e6f366 100644 --- a/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx +++ b/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx @@ -22,7 +22,7 @@ function Trigger(props: PreviewCard.Trigger.Props) { describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render, clock } = createRenderer(); @@ -208,7 +208,7 @@ describe('', () => { animationFinished = true; }; - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; function Test() { const style = ` @@ -534,7 +534,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/radio/indicator/RadioIndicator.test.tsx b/packages/react/src/radio/indicator/RadioIndicator.test.tsx index aa434f47ba..e062cb231f 100644 --- a/packages/react/src/radio/indicator/RadioIndicator.test.tsx +++ b/packages/react/src/radio/indicator/RadioIndicator.test.tsx @@ -7,7 +7,7 @@ import { RadioGroup } from '@base-ui-components/react/radio-group'; describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render } = createRenderer(); @@ -63,7 +63,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { diff --git a/packages/react/src/select/root/SelectRoot.test.tsx b/packages/react/src/select/root/SelectRoot.test.tsx index 02efb39e31..fab8b3d937 100644 --- a/packages/react/src/select/root/SelectRoot.test.tsx +++ b/packages/react/src/select/root/SelectRoot.test.tsx @@ -9,7 +9,7 @@ const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render } = createRenderer(); @@ -252,7 +252,7 @@ describe('', () => { skip(); } - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let animationFinished = false; const notifyAnimationFinished = () => { @@ -469,7 +469,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/tooltip/root/TooltipRoot.test.tsx b/packages/react/src/tooltip/root/TooltipRoot.test.tsx index b9b250f191..4cd088431d 100644 --- a/packages/react/src/tooltip/root/TooltipRoot.test.tsx +++ b/packages/react/src/tooltip/root/TooltipRoot.test.tsx @@ -14,7 +14,7 @@ function Root(props: Tooltip.Root.Props) { describe('', () => { beforeEach(() => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = true; + globalThis.BASE_UI_ANIMATIONS_DISABLED = true; }); const { render, clock } = createRenderer(); @@ -433,7 +433,7 @@ describe('', () => { }); it('is called on close when the exit animation finishes', async () => { - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED = false; + globalThis.BASE_UI_ANIMATIONS_DISABLED = false; let onCloseCompleteCalled = false; function notifyonCloseComplete() { diff --git a/packages/react/src/utils/useAnimationsFinished.ts b/packages/react/src/utils/useAnimationsFinished.ts index cae58f948f..145bd9bbce 100644 --- a/packages/react/src/utils/useAnimationsFinished.ts +++ b/packages/react/src/utils/useAnimationsFinished.ts @@ -25,10 +25,7 @@ export function useAnimationsFinished(ref: React.RefObject) return; } - if ( - typeof element.getAnimations !== 'function' || - (globalThis as any).BASE_UI_ANIMATIONS_DISABLED - ) { + if (typeof element.getAnimations !== 'function' || globalThis.BASE_UI_ANIMATIONS_DISABLED) { fnToExecute(); } else { frameRef.current = requestAnimationFrame(() => { diff --git a/packages/react/tsconfig.test.json b/packages/react/tsconfig.test.json index a154255042..a9f1684beb 100644 --- a/packages/react/tsconfig.test.json +++ b/packages/react/tsconfig.test.json @@ -11,6 +11,6 @@ "outDir": "build-tests", "types": ["vitest/globals", "@types/chai", "@types/chai-dom"] }, - "include": ["src/**/*.spec.ts*", "src/**/*.test.ts*", "src/index.test.js", "test"], + "include": ["src/**/*.spec.ts*", "src/**/*.test.ts*", "src/index.test.js", "test", "src/global.d.ts"], "references": [{ "path": "./tsconfig.build.json" }] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bdfa3fcc67..d2d1df725a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -689,6 +689,9 @@ importers: '@types/chai': specifier: ^4.3.20 version: 4.3.20 + '@types/chai-dom': + specifier: ^1.11.3 + version: 1.11.3 '@types/react': specifier: ^19.0.2 version: 19.0.2 diff --git a/test/package.json b/test/package.json index baf6df1e4c..cde08e96a6 100644 --- a/test/package.json +++ b/test/package.json @@ -12,6 +12,7 @@ "@playwright/test": "1.49.1", "@testing-library/dom": "^10.4.0", "@types/chai": "^4.3.20", + "@types/chai-dom": "^1.11.3", "@types/react": "^19.0.2", "@types/react-dom": "^19.0.2", "@types/sinon": "^17.0.3", diff --git a/test/setupVitest.ts b/test/setupVitest.ts index a63bc2bfa7..cc8995ad04 100644 --- a/test/setupVitest.ts +++ b/test/setupVitest.ts @@ -1,21 +1,23 @@ -import { beforeAll, afterAll, vi } from 'vitest'; +/* eslint-disable no-var */ +/* eslint-disable vars-on-top */ +import { beforeAll, afterAll } from 'vitest'; import chai from 'chai'; - import chaiDom from 'chai-dom'; import chaiPlugin from '@mui/internal-test-utils/chaiPlugin'; +declare global { + var before: typeof beforeAll; + var after: typeof afterAll; + var BASE_UI_ANIMATIONS_DISABLED: boolean; +} + chai.use(chaiDom); chai.use(chaiPlugin); -// @ts-ignore +// required for conformance tests (until everything is migrated to Vite) globalThis.before = beforeAll; -// @ts-ignore globalThis.after = afterAll; -// @ts-ignore -globalThis.vi = vi; - -// @ts-ignore globalThis.BASE_UI_ANIMATIONS_DISABLED = true; const isVitestJsdom = process.env.VITEST_ENV === 'jsdom'; diff --git a/test/tsconfig.json b/test/tsconfig.json index 5dbefccfec..dd8127255e 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -2,9 +2,9 @@ "extends": "../tsconfig.base.json", "compilerOptions": { "module": "es2022", - "moduleResolution": "Node", + "moduleResolution": "bundler", "types": ["vite/client", "vitest/globals"] }, - "include": ["e2e/**/*", "regressions/**/*"], + "include": ["e2e/**/*", "regressions/**/*", "./*.ts"], "exclude": ["node_modules", "build"] }