From 24301b65c87cdb057062de051a43192dc3025106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dudak?= Date: Wed, 8 Jan 2025 11:29:18 +0100 Subject: [PATCH] [test] Add the isJSDOM utility (#1281) --- .../src/accordion/root/AccordionRoot.test.tsx | 4 +--- .../root/AlertDialogRoot.test.tsx | 4 +--- .../indicator/CheckboxIndicator.test.tsx | 6 ++--- .../src/checkbox/root/CheckboxRoot.test.tsx | 4 +--- .../panel/CollapsiblePanel.test.tsx | 4 +--- .../collapsible/root/CollapsibleRoot.test.tsx | 4 +--- .../src/composite/root/CompositeRoot.test.tsx | 3 +-- .../src/dialog/popup/DialogPopup.test.tsx | 4 +--- .../react/src/dialog/root/DialogRoot.test.tsx | 10 ++++----- .../MenuCheckboxItemIndicator.test.tsx | 6 ++--- .../checkbox-item/MenuCheckboxItem.test.tsx | 6 ++--- .../react/src/menu/item/MenuItem.test.tsx | 4 ++-- .../menu/positioner/MenuPositioner.test.tsx | 10 ++++----- .../MenuRadioItemIndicator.test.tsx | 6 ++--- .../menu/radio-item/MenuRadioItem.test.tsx | 4 ++-- .../react/src/menu/root/MenuRoot.test.tsx | 22 +++++++++---------- .../root/NumberFieldRoot.test.tsx | 6 ++--- .../scrub-area/NumberFieldScrubArea.test.tsx | 4 ++-- .../src/popover/root/PopoverRoot.test.tsx | 8 +++---- .../root/PreviewCardRoot.test.tsx | 10 ++++----- .../indicator/ProgressIndicator.test.tsx | 4 +--- .../react/src/radio-group/RadioGroup.test.tsx | 3 +-- .../radio/indicator/RadioIndicator.test.tsx | 6 ++--- .../corner/ScrollAreaCorner.test.tsx | 4 +--- .../scroll-area/root/ScrollAreaRoot.test.tsx | 4 +--- .../react/src/select/item/SelectItem.test.tsx | 4 +--- .../react/src/select/root/SelectRoot.test.tsx | 8 +++---- .../react/src/slider/root/SliderRoot.test.tsx | 4 +--- .../react/src/switch/root/SwitchRoot.test.tsx | 4 ++-- .../src/tabs/indicator/TabsIndicator.test.tsx | 4 ++-- .../react/src/tabs/root/TabsRoot.test.tsx | 4 +--- .../src/toggle-group/ToggleGroup.test.tsx | 4 +--- .../src/tooltip/root/TooltipRoot.test.tsx | 4 +--- .../react/src/use-button/useButton.test.tsx | 4 +--- packages/react/test/index.ts | 1 + packages/react/test/utils.ts | 4 ++++ 36 files changed, 79 insertions(+), 116 deletions(-) create mode 100644 packages/react/test/utils.ts diff --git a/packages/react/src/accordion/root/AccordionRoot.test.tsx b/packages/react/src/accordion/root/AccordionRoot.test.tsx index 22eccc23de..ed0d42860c 100644 --- a/packages/react/src/accordion/root/AccordionRoot.test.tsx +++ b/packages/react/src/accordion/root/AccordionRoot.test.tsx @@ -4,9 +4,7 @@ import { spy } from 'sinon'; import { flushMicrotasks } from '@mui/internal-test-utils'; import { DirectionProvider } from '@base-ui-components/react/direction-provider'; import { Accordion } from '@base-ui-components/react/accordion'; -import { createRenderer, describeConformance } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; const PANEL_CONTENT_1 = 'Panel contents 1'; const PANEL_CONTENT_2 = 'Panel contents 2'; diff --git a/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx b/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx index 607aa83523..3ea5355b68 100644 --- a/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx +++ b/packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx @@ -2,11 +2,9 @@ import * as React from 'react'; import { expect } from 'chai'; import { screen, waitFor } from '@mui/internal-test-utils'; import { AlertDialog } from '@base-ui-components/react/alert-dialog'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { spy } from 'sinon'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx b/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx index 7a83c8fafc..3bc3f913f9 100644 --- a/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx +++ b/packages/react/src/checkbox/indicator/CheckboxIndicator.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { Checkbox } from '@base-ui-components/react/checkbox'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { screen, waitFor } from '@mui/internal-test-utils'; import { CheckboxRootContext } from '../root/CheckboxRootContext'; @@ -98,7 +98,7 @@ describe('', () => { }); it('should remove the indicator when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -128,7 +128,7 @@ describe('', () => { }); it('should remove the indicator when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/checkbox/root/CheckboxRoot.test.tsx b/packages/react/src/checkbox/root/CheckboxRoot.test.tsx index e5b6934a0e..c7f74e7e23 100644 --- a/packages/react/src/checkbox/root/CheckboxRoot.test.tsx +++ b/packages/react/src/checkbox/root/CheckboxRoot.test.tsx @@ -3,9 +3,7 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { act, fireEvent } from '@mui/internal-test-utils'; import { Checkbox } from '@base-ui-components/react/checkbox'; -import { createRenderer, describeConformance } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/collapsible/panel/CollapsiblePanel.test.tsx b/packages/react/src/collapsible/panel/CollapsiblePanel.test.tsx index 7efbd900fb..43be8ef490 100644 --- a/packages/react/src/collapsible/panel/CollapsiblePanel.test.tsx +++ b/packages/react/src/collapsible/panel/CollapsiblePanel.test.tsx @@ -3,12 +3,10 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { act, fireEvent, flushMicrotasks } from '@mui/internal-test-utils'; import { Collapsible } from '@base-ui-components/react/collapsible'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { NOOP } from '../../utils/noop'; import { CollapsibleRootContext } from '../root/CollapsibleRootContext'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - const PANEL_CONTENT = 'This is panel content'; const contextValue: CollapsibleRootContext = { diff --git a/packages/react/src/collapsible/root/CollapsibleRoot.test.tsx b/packages/react/src/collapsible/root/CollapsibleRoot.test.tsx index b8d77691f2..f09c088559 100644 --- a/packages/react/src/collapsible/root/CollapsibleRoot.test.tsx +++ b/packages/react/src/collapsible/root/CollapsibleRoot.test.tsx @@ -3,9 +3,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { flushMicrotasks } from '@mui/internal-test-utils'; import { Collapsible } from '@base-ui-components/react/collapsible'; -import { createRenderer, describeConformance } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; const PANEL_CONTENT = 'This is panel content'; diff --git a/packages/react/src/composite/root/CompositeRoot.test.tsx b/packages/react/src/composite/root/CompositeRoot.test.tsx index 05233e590e..8d17bb8250 100644 --- a/packages/react/src/composite/root/CompositeRoot.test.tsx +++ b/packages/react/src/composite/root/CompositeRoot.test.tsx @@ -1,11 +1,10 @@ import * as React from 'react'; import { expect } from 'chai'; import { act, createRenderer, fireEvent, flushMicrotasks } from '@mui/internal-test-utils'; +import { isJSDOM } from '#test-utils'; import { CompositeItem } from '../item/CompositeItem'; import { CompositeRoot } from './CompositeRoot'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('Composite', () => { const { render } = createRenderer(); diff --git a/packages/react/src/dialog/popup/DialogPopup.test.tsx b/packages/react/src/dialog/popup/DialogPopup.test.tsx index 49db5ac7a8..a561d77bfd 100644 --- a/packages/react/src/dialog/popup/DialogPopup.test.tsx +++ b/packages/react/src/dialog/popup/DialogPopup.test.tsx @@ -3,9 +3,7 @@ import { expect } from 'chai'; import { Dialog } from '@base-ui-components/react/dialog'; import { AlertDialog } from '@base-ui-components/react/alert-dialog'; import { act, waitFor, screen } from '@mui/internal-test-utils'; -import { describeConformance, createRenderer } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { describeConformance, createRenderer, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/dialog/root/DialogRoot.test.tsx b/packages/react/src/dialog/root/DialogRoot.test.tsx index c2f14e2b7a..8b6041d041 100644 --- a/packages/react/src/dialog/root/DialogRoot.test.tsx +++ b/packages/react/src/dialog/root/DialogRoot.test.tsx @@ -3,12 +3,10 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { act, fireEvent, screen, waitFor } from '@mui/internal-test-utils'; import { Dialog } from '@base-ui-components/react/dialog'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { Menu } from '@base-ui-components/react/menu'; import { Select } from '@base-ui-components/react/select'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('', () => { beforeEach(() => { globalThis.BASE_UI_ANIMATIONS_DISABLED = true; @@ -58,7 +56,7 @@ describe('', () => { }); it('should remove the popup when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -88,7 +86,7 @@ describe('', () => { }); it('should remove the popup when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -380,7 +378,7 @@ describe('', () => { } `; - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } 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 0f716c1d99..349f2b6d80 100644 --- a/packages/react/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.test.tsx +++ b/packages/react/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { screen, waitFor } from '@mui/internal-test-utils'; import { expect } from 'chai'; @@ -29,7 +29,7 @@ describe('', () => { })); it('should remove the indicator when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -67,7 +67,7 @@ describe('', () => { }); it('should remove the indicator when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx b/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx index 612faf326b..eb8e4ea270 100644 --- a/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx +++ b/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { fireEvent, act, waitFor } from '@mui/internal-test-utils'; import { Menu } from '@base-ui-components/react/menu'; -import { describeConformance, createRenderer } from '../../../test'; +import { describeConformance, createRenderer, isJSDOM } from '#test-utils'; describe('', () => { const { render, clock } = createRenderer({ @@ -22,7 +22,7 @@ describe('', () => { })); it('perf: does not rerender menu items unnecessarily', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -191,7 +191,7 @@ describe('', () => { }); it(`toggles the checked state when Enter is pressed`, async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/menu/item/MenuItem.test.tsx b/packages/react/src/menu/item/MenuItem.test.tsx index 17cc9f86d4..f38eb8408d 100644 --- a/packages/react/src/menu/item/MenuItem.test.tsx +++ b/packages/react/src/menu/item/MenuItem.test.tsx @@ -4,7 +4,7 @@ import { spy } from 'sinon'; import { MemoryRouter, Route, Routes, Link, useLocation } from 'react-router-dom'; import { act, screen, waitFor } from '@mui/internal-test-utils'; import { Menu } from '@base-ui-components/react/menu'; -import { describeConformance, createRenderer } from '#test-utils'; +import { describeConformance, createRenderer, isJSDOM } from '#test-utils'; describe('', () => { const { render, clock } = createRenderer({ @@ -45,7 +45,7 @@ describe('', () => { }); it('perf: does not rerender menu items unnecessarily', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/menu/positioner/MenuPositioner.test.tsx b/packages/react/src/menu/positioner/MenuPositioner.test.tsx index eee26af0ab..3ece80ff0a 100644 --- a/packages/react/src/menu/positioner/MenuPositioner.test.tsx +++ b/packages/react/src/menu/positioner/MenuPositioner.test.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import userEvent from '@testing-library/user-event'; import { flushMicrotasks } from '@mui/internal-test-utils'; import { Menu } from '@base-ui-components/react/menu'; -import { describeConformance, createRenderer } from '#test-utils'; +import { describeConformance, createRenderer, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); @@ -21,7 +21,7 @@ describe('', () => { describe('prop: anchor', () => { it('should be placed near the specified element when a ref is passed', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -68,7 +68,7 @@ describe('', () => { it('should be placed near the specified element when an element is passed', async ({ skip, }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -118,7 +118,7 @@ describe('', () => { it('should be placed near the specified element when a function returning an element is passed', async ({ skip, }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -168,7 +168,7 @@ describe('', () => { }); it('should be placed at the specified position', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } 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 52768f4686..f78529f19c 100644 --- a/packages/react/src/menu/radio-item-indicator/MenuRadioItemIndicator.test.tsx +++ b/packages/react/src/menu/radio-item-indicator/MenuRadioItemIndicator.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { screen, waitFor } from '@mui/internal-test-utils'; import { expect } from 'chai'; @@ -27,7 +27,7 @@ describe('', () => { })); it('should remove the indicator when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -72,7 +72,7 @@ describe('', () => { }); it('should remove the indicator when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx b/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx index 42d263225f..0a49072b98 100644 --- a/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx +++ b/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { fireEvent, act, waitFor } from '@mui/internal-test-utils'; import { Menu } from '@base-ui-components/react/menu'; -import { describeConformance, createRenderer } from '#test-utils'; +import { describeConformance, createRenderer, isJSDOM } from '#test-utils'; import { MenuRadioGroupContext } from '../radio-group/MenuRadioGroupContext'; const testRadioGroupContext = { @@ -34,7 +34,7 @@ describe('', () => { })); it('perf: does not rerender menu items unnecessarily', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/menu/root/MenuRoot.test.tsx b/packages/react/src/menu/root/MenuRoot.test.tsx index 3861752820..7addd73267 100644 --- a/packages/react/src/menu/root/MenuRoot.test.tsx +++ b/packages/react/src/menu/root/MenuRoot.test.tsx @@ -5,9 +5,7 @@ import { DirectionProvider } from '@base-ui-components/react/direction-provider' import { Menu } from '@base-ui-components/react/menu'; import userEvent from '@testing-library/user-event'; import { spy } from 'sinon'; -import { createRenderer } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { createRenderer, isJSDOM } from '#test-utils'; describe('', () => { beforeEach(() => { @@ -147,7 +145,7 @@ describe('', () => { describe('text navigation', () => { it('changes the highlighted item', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // useMenuPopup Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JSDOM skip(); @@ -192,7 +190,7 @@ describe('', () => { }); it('changes the highlighted item using text navigation on label prop', async ({ skip }) => { - if (!/jsdom/.test(window.navigator.userAgent)) { + if (!isJSDOM) { // This test is very flaky in real browsers skip(); } @@ -247,7 +245,7 @@ describe('', () => { }); it('skips the non-stringifiable items', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // useMenuPopup Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JSDOM skip(); @@ -293,7 +291,7 @@ describe('', () => { }); it('navigate to options with diacritic characters', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // useMenuPopup Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JSDOM skip(); @@ -334,7 +332,7 @@ describe('', () => { }); it('navigate to next options beginning with diacritic characters', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // useMenuPopup Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JSDOM skip(); @@ -371,7 +369,7 @@ describe('', () => { it('does not trigger the onClick event when Space is pressed during text navigation', async ({ skip, }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // useMenuPopup Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JSDOM skip(); @@ -577,7 +575,7 @@ describe('', () => { }); it('focuses the trigger after the menu is closed but not unmounted', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // TODO: this stopped working in vitest JSDOM mode skip(); } @@ -721,7 +719,7 @@ describe('', () => { describe('controlled mode', () => { it('should remove the popup when and there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -753,7 +751,7 @@ describe('', () => { }); it('should remove the popup when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/number-field/root/NumberFieldRoot.test.tsx b/packages/react/src/number-field/root/NumberFieldRoot.test.tsx index edfc388637..4e0f31ed8d 100644 --- a/packages/react/src/number-field/root/NumberFieldRoot.test.tsx +++ b/packages/react/src/number-field/root/NumberFieldRoot.test.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import { act, screen, fireEvent } from '@mui/internal-test-utils'; import { NumberField as NumberFieldBase } from '@base-ui-components/react/number-field'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); @@ -442,7 +442,7 @@ describe('', () => { describe('form handling', () => { it('should include the input value in the form submission', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // FormData is not available in JSDOM skip(); } @@ -487,7 +487,7 @@ describe('', () => { }); }); - describe.skipIf(/jsdom/.test(window.navigator.userAgent))('pasting', () => { + describe.skipIf(isJSDOM)('pasting', () => { it('should allow pasting a valid number', async () => { await render(); const input = screen.getByRole('textbox'); diff --git a/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.test.tsx b/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.test.tsx index b43f9f3cde..2a61ebcdf8 100644 --- a/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.test.tsx +++ b/packages/react/src/number-field/scrub-area/NumberFieldScrubArea.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { screen, waitFor, act } from '@mui/internal-test-utils'; import { NumberField } from '@base-ui-components/react/number-field'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { isWebKit } from '../../utils/detectBrowser'; import { NumberFieldRootContext } from '../root/NumberFieldRootContext'; @@ -49,7 +49,7 @@ describe('', () => { }); // Only run the following tests in Chromium/Firefox. - if (/jsdom/.test(window.navigator.userAgent) || isWebKit()) { + if (isJSDOM || isWebKit()) { return; } diff --git a/packages/react/src/popover/root/PopoverRoot.test.tsx b/packages/react/src/popover/root/PopoverRoot.test.tsx index f3302b6266..1ceaaa5d16 100644 --- a/packages/react/src/popover/root/PopoverRoot.test.tsx +++ b/packages/react/src/popover/root/PopoverRoot.test.tsx @@ -3,11 +3,9 @@ import { Popover } from '@base-ui-components/react/popover'; import { act, fireEvent, flushMicrotasks, screen, waitFor } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { OPEN_DELAY } from '../utils/constants'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - function Root(props: Popover.Root.Props) { return ; } @@ -190,7 +188,7 @@ describe('', () => { }); it('should remove the popup when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -223,7 +221,7 @@ describe('', () => { }); it('should remove the popup when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx b/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx index 4289e6f366..972551c579 100644 --- a/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx +++ b/packages/react/src/preview-card/root/PreviewCardRoot.test.tsx @@ -3,11 +3,9 @@ import { PreviewCard } from '@base-ui-components/react/preview-card'; import { act, fireEvent, screen, flushMicrotasks, waitFor } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { CLOSE_DELAY, OPEN_DELAY } from '../utils/constants'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - function Root(props: PreviewCard.Root.Props) { return ; } @@ -85,7 +83,7 @@ describe('', () => { }); it('should open when the trigger is focused', async () => { - if (!/jsdom/.test(window.navigator.userAgent)) { + if (!isJSDOM) { // Ignore due to `:focus-visible` being required in the browser. return; } @@ -167,7 +165,7 @@ describe('', () => { }); it('should remove the popup when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -199,7 +197,7 @@ describe('', () => { }); it('should remove the popup when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/progress/indicator/ProgressIndicator.test.tsx b/packages/react/src/progress/indicator/ProgressIndicator.test.tsx index 8f26765134..c3f90ef149 100644 --- a/packages/react/src/progress/indicator/ProgressIndicator.test.tsx +++ b/packages/react/src/progress/indicator/ProgressIndicator.test.tsx @@ -1,11 +1,9 @@ import * as React from 'react'; import { expect } from 'chai'; import { Progress } from '@base-ui-components/react/progress'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { ProgressRootContext } from '../root/ProgressRootContext'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - const contextValue: ProgressRootContext = { max: 100, min: 0, diff --git a/packages/react/src/radio-group/RadioGroup.test.tsx b/packages/react/src/radio-group/RadioGroup.test.tsx index 4f62d6904c..f7fa355072 100644 --- a/packages/react/src/radio-group/RadioGroup.test.tsx +++ b/packages/react/src/radio-group/RadioGroup.test.tsx @@ -7,11 +7,10 @@ import { } from '@base-ui-components/react/direction-provider'; import { expect } from 'chai'; import { spy } from 'sinon'; +import { isJSDOM } from '#test-utils'; import { createRenderer, act, screen, fireEvent } from '@mui/internal-test-utils'; import { describeConformance } from '../../test/describeConformance'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/radio/indicator/RadioIndicator.test.tsx b/packages/react/src/radio/indicator/RadioIndicator.test.tsx index e062cb231f..ee08121d1c 100644 --- a/packages/react/src/radio/indicator/RadioIndicator.test.tsx +++ b/packages/react/src/radio/indicator/RadioIndicator.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { screen, waitFor } from '@mui/internal-test-utils'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { Radio } from '@base-ui-components/react/radio'; import { expect } from 'chai'; import { RadioGroup } from '@base-ui-components/react/radio-group'; @@ -20,7 +20,7 @@ describe('', () => { })); it('should remove the indicator when there is no exit animation defined', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -59,7 +59,7 @@ describe('', () => { }); it('should remove the indicator when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/scroll-area/corner/ScrollAreaCorner.test.tsx b/packages/react/src/scroll-area/corner/ScrollAreaCorner.test.tsx index bd6f43df67..803a2cda10 100644 --- a/packages/react/src/scroll-area/corner/ScrollAreaCorner.test.tsx +++ b/packages/react/src/scroll-area/corner/ScrollAreaCorner.test.tsx @@ -2,11 +2,9 @@ import * as React from 'react'; import { ScrollArea } from '@base-ui-components/react/scroll-area'; import { expect } from 'chai'; import { screen } from '@mui/internal-test-utils'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { describeConformance } from '../../../test/describeConformance'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/scroll-area/root/ScrollAreaRoot.test.tsx b/packages/react/src/scroll-area/root/ScrollAreaRoot.test.tsx index 45b545c5a7..284bd41a30 100644 --- a/packages/react/src/scroll-area/root/ScrollAreaRoot.test.tsx +++ b/packages/react/src/scroll-area/root/ScrollAreaRoot.test.tsx @@ -1,12 +1,10 @@ import * as React from 'react'; import { ScrollArea } from '@base-ui-components/react/scroll-area'; import { screen } from '@mui/internal-test-utils'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { expect } from 'chai'; import { describeConformance } from '../../../test/describeConformance'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - const VIEWPORT_SIZE = 200; const SCROLLABLE_CONTENT_SIZE = 1000; const SCROLLBAR_WIDTH = 10; diff --git a/packages/react/src/select/item/SelectItem.test.tsx b/packages/react/src/select/item/SelectItem.test.tsx index ae1a7a39cc..1d2b1c64a4 100644 --- a/packages/react/src/select/item/SelectItem.test.tsx +++ b/packages/react/src/select/item/SelectItem.test.tsx @@ -1,11 +1,9 @@ import * as React from 'react'; import { Select } from '@base-ui-components/react/select'; import { fireEvent, flushMicrotasks, screen, waitFor } from '@mui/internal-test-utils'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import { expect } from 'chai'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/select/root/SelectRoot.test.tsx b/packages/react/src/select/root/SelectRoot.test.tsx index fab8b3d937..c58eaf6283 100644 --- a/packages/react/src/select/root/SelectRoot.test.tsx +++ b/packages/react/src/select/root/SelectRoot.test.tsx @@ -1,12 +1,10 @@ import * as React from 'react'; import { Select } from '@base-ui-components/react/select'; import { fireEvent, flushMicrotasks, screen, waitFor } from '@mui/internal-test-utils'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('', () => { beforeEach(() => { globalThis.BASE_UI_ANIMATIONS_DISABLED = true; @@ -216,7 +214,7 @@ describe('', () => { it('when `false`, should remove the popup when there is no exit animation defined', async ({ skip, }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } @@ -248,7 +246,7 @@ describe('', () => { }); it('when `false`, should remove the popup when the animation finishes', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { skip(); } diff --git a/packages/react/src/slider/root/SliderRoot.test.tsx b/packages/react/src/slider/root/SliderRoot.test.tsx index f3e3799662..49dcf02ffb 100644 --- a/packages/react/src/slider/root/SliderRoot.test.tsx +++ b/packages/react/src/slider/root/SliderRoot.test.tsx @@ -4,13 +4,11 @@ import { spy, stub } from 'sinon'; import { act, fireEvent, screen } from '@mui/internal-test-utils'; import { DirectionProvider } from '@base-ui-components/react/direction-provider'; import { Slider } from '@base-ui-components/react/slider'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; import type { SliderRoot } from './SliderRoot'; type Touches = Array>; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - const GETBOUNDINGCLIENTRECT_HORIZONTAL_SLIDER_RETURN_VAL = { width: 100, height: 10, diff --git a/packages/react/src/switch/root/SwitchRoot.test.tsx b/packages/react/src/switch/root/SwitchRoot.test.tsx index ca5ca89abb..dc759610da 100644 --- a/packages/react/src/switch/root/SwitchRoot.test.tsx +++ b/packages/react/src/switch/root/SwitchRoot.test.tsx @@ -4,7 +4,7 @@ import { spy } from 'sinon'; import { act, fireEvent, screen } from '@mui/internal-test-utils'; import { Switch } from '@base-ui-components/react/switch'; import { userEvent } from '@testing-library/user-event'; -import { describeConformance, createRenderer } from '#test-utils'; +import { describeConformance, createRenderer, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); @@ -208,7 +208,7 @@ describe('', () => { }); it('should include the switch value in the form submission', async ({ skip }) => { - if (/jsdom/.test(window.navigator.userAgent)) { + if (isJSDOM) { // FormData is not available in JSDOM skip(); } diff --git a/packages/react/src/tabs/indicator/TabsIndicator.test.tsx b/packages/react/src/tabs/indicator/TabsIndicator.test.tsx index 1d2fb3a00b..7a0dd89055 100644 --- a/packages/react/src/tabs/indicator/TabsIndicator.test.tsx +++ b/packages/react/src/tabs/indicator/TabsIndicator.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { Tabs } from '@base-ui-components/react/tabs'; import { waitFor } from '@mui/internal-test-utils'; -import { createRenderer, describeConformance } from '#test-utils'; +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); @@ -22,7 +22,7 @@ describe('', () => { testRenderPropWith: 'div', })); - describe.skipIf(/jsdom/.test(window.navigator.userAgent))('rendering', () => { + describe.skipIf(isJSDOM)('rendering', () => { it('should not render when no tab is selected', async () => { const { queryByTestId } = await render( diff --git a/packages/react/src/tabs/root/TabsRoot.test.tsx b/packages/react/src/tabs/root/TabsRoot.test.tsx index 69a84f0c53..2233008e34 100644 --- a/packages/react/src/tabs/root/TabsRoot.test.tsx +++ b/packages/react/src/tabs/root/TabsRoot.test.tsx @@ -7,9 +7,7 @@ import { type TextDirection, } from '@base-ui-components/react/direction-provider'; import { Tabs } from '@base-ui-components/react/tabs'; -import { createRenderer, describeConformance } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/toggle-group/ToggleGroup.test.tsx b/packages/react/src/toggle-group/ToggleGroup.test.tsx index 5471abde15..c098c973da 100644 --- a/packages/react/src/toggle-group/ToggleGroup.test.tsx +++ b/packages/react/src/toggle-group/ToggleGroup.test.tsx @@ -8,9 +8,7 @@ import { } from '@base-ui-components/react/direction-provider'; import { ToggleGroup } from '@base-ui-components/react/toggle-group'; import { Toggle } from '@base-ui-components/react/toggle'; -import { createRenderer, describeConformance } from '#test-utils'; - -const isJSDOM = /jsdom/.test(window.navigator.userAgent); +import { createRenderer, describeConformance, isJSDOM } from '#test-utils'; describe('', () => { const { render } = createRenderer(); diff --git a/packages/react/src/tooltip/root/TooltipRoot.test.tsx b/packages/react/src/tooltip/root/TooltipRoot.test.tsx index 4cd088431d..30669c6d8a 100644 --- a/packages/react/src/tooltip/root/TooltipRoot.test.tsx +++ b/packages/react/src/tooltip/root/TooltipRoot.test.tsx @@ -3,11 +3,9 @@ import { Tooltip } from '@base-ui-components/react/tooltip'; import { act, fireEvent, flushMicrotasks, screen, waitFor } from '@mui/internal-test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { OPEN_DELAY } from '../utils/constants'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - function Root(props: Tooltip.Root.Props) { return ; } diff --git a/packages/react/src/use-button/useButton.test.tsx b/packages/react/src/use-button/useButton.test.tsx index 0792153dcc..946f67ed82 100644 --- a/packages/react/src/use-button/useButton.test.tsx +++ b/packages/react/src/use-button/useButton.test.tsx @@ -2,11 +2,9 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import { act, fireEvent } from '@mui/internal-test-utils'; -import { createRenderer } from '#test-utils'; +import { createRenderer, isJSDOM } from '#test-utils'; import { useButton } from '.'; -const isJSDOM = /jsdom/.test(window.navigator.userAgent); - describe('useButton', () => { const { render, renderToString } = createRenderer(); diff --git a/packages/react/test/index.ts b/packages/react/test/index.ts index 19595a45e5..d97fe5b37a 100644 --- a/packages/react/test/index.ts +++ b/packages/react/test/index.ts @@ -1,2 +1,3 @@ export { createRenderer } from './createRenderer'; export { describeConformance } from './describeConformance'; +export { isJSDOM } from './utils'; diff --git a/packages/react/test/utils.ts b/packages/react/test/utils.ts new file mode 100644 index 0000000000..ea2cd0b7cf --- /dev/null +++ b/packages/react/test/utils.ts @@ -0,0 +1,4 @@ +/** + * Whether the test runs in JSDOM environment + */ +export const isJSDOM = /jsdom/.test(window.navigator.userAgent);