diff --git a/docs/pages/joy-ui/api/tooltip.json b/docs/pages/joy-ui/api/tooltip.json index a2ff5c760db364..8ec531a901a955 100644 --- a/docs/pages/joy-ui/api/tooltip.json +++ b/docs/pages/joy-ui/api/tooltip.json @@ -223,7 +223,7 @@ "isGlobal": false } ], - "spread": true, + "spread": false, "themeDefaultProps": true, "muiName": "JoyTooltip", "forwardsRefTo": "HTMLButtonElement", diff --git a/docs/pages/material-ui/api/switch.json b/docs/pages/material-ui/api/switch.json index 118a43aa8dc2dc..b469b4f66308ca 100644 --- a/docs/pages/material-ui/api/switch.json +++ b/docs/pages/material-ui/api/switch.json @@ -133,7 +133,7 @@ "isGlobal": false } ], - "spread": false, + "spread": true, "themeDefaultProps": false, "muiName": "MuiSwitch", "forwardsRefTo": "HTMLSpanElement", diff --git a/packages/mui-base/test/describeConformanceUnstyled.tsx b/packages/mui-base/test/describeConformanceUnstyled.tsx index 750748d411eed9..1360f8d764212b 100644 --- a/packages/mui-base/test/describeConformanceUnstyled.tsx +++ b/packages/mui-base/test/describeConformanceUnstyled.tsx @@ -9,7 +9,6 @@ import { SlotTestingOptions, describeRef, randomStringValue, - testClassName, testComponentProp, testReactTestRenderer, } from '@mui-internal/test-utils'; @@ -266,6 +265,25 @@ function testSlotPropsProp( }); } +function testClassName(element: React.ReactElement, getOptions: () => ConformanceOptions) { + it('applies the className to the root component', async () => { + const { render } = getOptions(); + + if (!render) { + throwMissingPropError('render'); + } + + const className = randomStringValue(); + const testId = randomStringValue(); + + const { getByTestId } = await render( + React.cloneElement(element, { className, 'data-testid': testId }), + ); + + expect(getByTestId(testId)).to.have.class(className); + }); +} + interface TestOwnerState { 'data-testid'?: string; } diff --git a/packages/mui-joy/src/Autocomplete/Autocomplete.tsx b/packages/mui-joy/src/Autocomplete/Autocomplete.tsx index dbbb1631332c72..75793e1f4f4013 100644 --- a/packages/mui-joy/src/Autocomplete/Autocomplete.tsx +++ b/packages/mui-joy/src/Autocomplete/Autocomplete.tsx @@ -632,9 +632,14 @@ const Autocomplete = React.forwardRef(function Autocomplete( }, }); - const defaultRenderOption = (optionProps: any, option: unknown) => ( - {getOptionLabel(option)} - ); + const defaultRenderOption = (optionProps: any, option: unknown) => { + const { key, ...rest } = optionProps; + return ( + + {getOptionLabel(option)} + + ); + }; const renderOption = renderOptionProp || defaultRenderOption; diff --git a/packages/mui-joy/src/Menu/Menu.test.tsx b/packages/mui-joy/src/Menu/Menu.test.tsx index d6969b30334951..92ddb6198476fe 100644 --- a/packages/mui-joy/src/Menu/Menu.test.tsx +++ b/packages/mui-joy/src/Menu/Menu.test.tsx @@ -31,12 +31,6 @@ describe('Joy ', () => { {node}, ); }, - wrapMount: (mount) => (node: React.ReactNode) => { - const wrapper = mount( - {node}, - ); - return wrapper.childAt(0); - }, ThemeProvider, muiName: 'JoyMenu', refInstanceof: window.HTMLUListElement, diff --git a/packages/mui-joy/src/MenuButton/MenuButton.test.tsx b/packages/mui-joy/src/MenuButton/MenuButton.test.tsx index 92052dba8ebc6d..f12ff0dc8252e6 100644 --- a/packages/mui-joy/src/MenuButton/MenuButton.test.tsx +++ b/packages/mui-joy/src/MenuButton/MenuButton.test.tsx @@ -22,12 +22,6 @@ describe('', () => { describeConformance(, () => ({ classes, inheritComponent: 'button', - wrapMount: (mount) => (node: React.ReactNode) => { - const wrapper = mount( - {node}, - ); - return wrapper.childAt(0); - }, muiName: 'JoyMenuButton', refInstanceof: window.HTMLButtonElement, render: (node) => { diff --git a/packages/mui-joy/src/MenuItem/MenuItem.test.tsx b/packages/mui-joy/src/MenuItem/MenuItem.test.tsx index 7492c1e39340e3..993abec30b8df9 100644 --- a/packages/mui-joy/src/MenuItem/MenuItem.test.tsx +++ b/packages/mui-joy/src/MenuItem/MenuItem.test.tsx @@ -36,10 +36,6 @@ describe('Joy ', () => { classes, inheritComponent: ListItemButton, render: (node) => render({node}), - wrapMount: (mount) => (node) => { - const wrapper = mount({node}); - return wrapper.childAt(0); - }, ThemeProvider, refInstanceof: window.HTMLLIElement, testComponentPropWith: 'a', diff --git a/packages/mui-joy/src/Tab/Tab.test.tsx b/packages/mui-joy/src/Tab/Tab.test.tsx index 37113dc2be0e6e..7eafea0d7b0541 100644 --- a/packages/mui-joy/src/Tab/Tab.test.tsx +++ b/packages/mui-joy/src/Tab/Tab.test.tsx @@ -32,7 +32,6 @@ describe('Joy ', () => { classes, inheritComponent: 'button', render: (node) => render({node}), - wrapMount: (mount) => (node) => mount({node}), ThemeProvider, muiName: 'JoyTab', refInstanceof: window.HTMLButtonElement, diff --git a/packages/mui-joy/src/TabList/TabList.test.tsx b/packages/mui-joy/src/TabList/TabList.test.tsx index 515450dbed9eef..e9885817c7357f 100644 --- a/packages/mui-joy/src/TabList/TabList.test.tsx +++ b/packages/mui-joy/src/TabList/TabList.test.tsx @@ -21,7 +21,6 @@ describe('Joy ', () => { classes, inheritComponent: 'div', render: (node) => render({node}), - wrapMount: (mount) => (node) => mount({node}), ThemeProvider, muiName: 'JoyTabList', refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-joy/src/TabPanel/TabPanel.test.tsx b/packages/mui-joy/src/TabPanel/TabPanel.test.tsx index 9bf7a615fde964..c8649afceb1781 100644 --- a/packages/mui-joy/src/TabPanel/TabPanel.test.tsx +++ b/packages/mui-joy/src/TabPanel/TabPanel.test.tsx @@ -20,7 +20,6 @@ describe('Joy ', () => { classes, inheritComponent: 'div', render: (node) => render({node}), - wrapMount: (mount) => (node) => mount({node}), ThemeProvider, muiName: 'JoyTabPanel', refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-joy/src/Tooltip/Tooltip.test.tsx b/packages/mui-joy/src/Tooltip/Tooltip.test.tsx index 7a277704e347dd..0bc6969c4563fc 100644 --- a/packages/mui-joy/src/Tooltip/Tooltip.test.tsx +++ b/packages/mui-joy/src/Tooltip/Tooltip.test.tsx @@ -52,6 +52,12 @@ describe('', () => { 'themeVariants', // react-transition-group issue 'reactTestRenderer', + // Props are spread to root and children + // We cannot use the standard propsSpread test which relies on data-testid only on the root + 'propsSpread', + // Props are spread to root and children + // We cannot use the standard mergeClassName test which relies on data-testid only on the root + 'mergeClassName', ], }), ); diff --git a/packages/mui-lab/src/TabList/TabList.test.js b/packages/mui-lab/src/TabList/TabList.test.js index 2f34f2b0994517..7dbad4514c67bc 100644 --- a/packages/mui-lab/src/TabList/TabList.test.js +++ b/packages/mui-lab/src/TabList/TabList.test.js @@ -19,10 +19,6 @@ describe('', () => { * @param {React.ReactNode} node */ render: (node) => render({node}), - wrapMount: (mount) => (node) => { - const wrapper = mount({node}); - return wrapper.childAt(0); - }, refInstanceof: window.HTMLDivElement, // TODO: no idea why reactTestRenderer fails skip: [ diff --git a/packages/mui-lab/src/TabPanel/TabPanel.test.tsx b/packages/mui-lab/src/TabPanel/TabPanel.test.tsx index ba0487616e45f9..168d8eaf754e62 100644 --- a/packages/mui-lab/src/TabPanel/TabPanel.test.tsx +++ b/packages/mui-lab/src/TabPanel/TabPanel.test.tsx @@ -12,7 +12,6 @@ describe('', () => { classes, inheritComponent: 'div', render: (node) => render({node}), - wrapMount: (mount) => (node) => mount({node}), refInstanceof: window.HTMLDivElement, muiName: 'MuiTabPanel', skip: [ diff --git a/packages/mui-material/src/Fade/Fade.test.js b/packages/mui-material/src/Fade/Fade.test.js index 14b68f38e02560..c9efbfb053f4f1 100644 --- a/packages/mui-material/src/Fade/Fade.test.js +++ b/packages/mui-material/src/Fade/Fade.test.js @@ -16,6 +16,7 @@ describe('', () => { }; describeConformance(, () => ({ + render, classes: {}, inheritComponent: Transition, refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-material/src/Grow/Grow.test.js b/packages/mui-material/src/Grow/Grow.test.js index 5f0f6a49f75095..fc256b86b4dfb0 100644 --- a/packages/mui-material/src/Grow/Grow.test.js +++ b/packages/mui-material/src/Grow/Grow.test.js @@ -17,10 +17,11 @@ describe('', () => { }; describeConformance( - +
, () => ({ + render, classes: {}, inheritComponent: Transition, refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-material/src/MenuList/MenuList.test.js b/packages/mui-material/src/MenuList/MenuList.test.js index 4e72262e4ce9d8..58eb8e4edf9e53 100644 --- a/packages/mui-material/src/MenuList/MenuList.test.js +++ b/packages/mui-material/src/MenuList/MenuList.test.js @@ -23,6 +23,7 @@ describe('', () => { const { render } = createRenderer(); describeConformance(, () => ({ + render, classes: {}, inheritComponent: List, refInstanceof: window.HTMLUListElement, diff --git a/packages/mui-material/src/NativeSelect/NativeSelectInput.test.js b/packages/mui-material/src/NativeSelect/NativeSelectInput.test.js index 8f0dbace379d31..fe8de03804657b 100644 --- a/packages/mui-material/src/NativeSelect/NativeSelectInput.test.js +++ b/packages/mui-material/src/NativeSelect/NativeSelectInput.test.js @@ -11,6 +11,7 @@ describe('', () => { const { render } = createRenderer(); describeConformance(, () => ({ + render, only: ['refForwarding'], refInstanceof: window.HTMLSelectElement, muiName: 'MuiNativeSelectInput', diff --git a/packages/mui-material/src/RadioGroup/RadioGroup.test.js b/packages/mui-material/src/RadioGroup/RadioGroup.test.js index ad9c3d2068eebe..df4c3d649ea96a 100644 --- a/packages/mui-material/src/RadioGroup/RadioGroup.test.js +++ b/packages/mui-material/src/RadioGroup/RadioGroup.test.js @@ -12,6 +12,7 @@ describe('', () => { const { render } = createRenderer(); describeConformance(, () => ({ + render, classes: {}, inheritComponent: FormGroup, refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-material/src/Slide/Slide.test.js b/packages/mui-material/src/Slide/Slide.test.js index d8c516943c4885..c61e34b5112d51 100644 --- a/packages/mui-material/src/Slide/Slide.test.js +++ b/packages/mui-material/src/Slide/Slide.test.js @@ -23,6 +23,7 @@ describe('', () => {
, () => ({ + render, classes: {}, inheritComponent: Transition, refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-material/src/StepContent/StepContent.test.js b/packages/mui-material/src/StepContent/StepContent.test.js index 0033a0ff1ca6da..9a9abc967135eb 100644 --- a/packages/mui-material/src/StepContent/StepContent.test.js +++ b/packages/mui-material/src/StepContent/StepContent.test.js @@ -13,22 +13,6 @@ describe('', () => { describeConformance(, () => ({ classes, inheritComponent: 'div', - wrapMount: (mount) => (node) => { - const wrapper = mount( - - {node} - , - ); - // `wrapper.find(Step)` tree. - // "->" indicates the path we want - // "n:" indicates the index - // - // -> 0: - // 0: // from Emotion - // -> 1:
- // -> 0: - return wrapper.find(Step).childAt(0).childAt(1).childAt(0); - }, muiName: 'MuiStepContent', refInstanceof: window.HTMLDivElement, render: (node) => { diff --git a/packages/mui-material/src/SwipeableDrawer/SwipeableDrawer.test.js b/packages/mui-material/src/SwipeableDrawer/SwipeableDrawer.test.js index d11b9f01c4a29a..1f197b487bce9e 100644 --- a/packages/mui-material/src/SwipeableDrawer/SwipeableDrawer.test.js +++ b/packages/mui-material/src/SwipeableDrawer/SwipeableDrawer.test.js @@ -63,6 +63,7 @@ describe('', () => { const { render } = createRenderer({ clock: 'fake' }); describeConformance( {}} onClose={() => {}} open />, () => ({ + render, classes: {}, inheritComponent: Drawer, refInstanceof: window.HTMLDivElement, diff --git a/packages/mui-material/src/Switch/Switch.test.js b/packages/mui-material/src/Switch/Switch.test.js index 99f454cdb3006b..774e6450b7ad38 100644 --- a/packages/mui-material/src/Switch/Switch.test.js +++ b/packages/mui-material/src/Switch/Switch.test.js @@ -17,7 +17,16 @@ describe('', () => { { slotName: 'input', slotClassName: classes.input }, ], refInstanceof: window.HTMLSpanElement, - skip: ['componentProp', 'componentsProp', 'propsSpread', 'themeDefaultProps', 'themeVariants'], + skip: [ + 'componentProp', + 'componentsProp', + 'themeDefaultProps', + 'themeVariants', + // Props are spread to the root's child but className is added to the root + // We cannot use the standard mergeClassName test which relies on data-testid on the root + // We should fix this when refactoring with Base UI + 'mergeClassName', + ], })); describe('styleSheet', () => { @@ -142,4 +151,12 @@ describe('', () => { }); }); }); + + describe('mergeClassName', () => { + it('should merge the className', () => { + const { container } = render(); + + expect(container.firstChild).to.have.class('test-class-name'); + }); + }); }); diff --git a/packages/mui-material/src/TableBody/TableBody.test.js b/packages/mui-material/src/TableBody/TableBody.test.js index 8faaa00569c13c..708b0add1c5230 100644 --- a/packages/mui-material/src/TableBody/TableBody.test.js +++ b/packages/mui-material/src/TableBody/TableBody.test.js @@ -15,10 +15,6 @@ describe('', () => { describeConformance(, () => ({ classes, inheritComponent: 'tbody', - wrapMount: (mount) => (node) => { - const wrapper = mount({node}
); - return wrapper.find('table').childAt(0); - }, render: (node) => { const { container, ...other } = render({node}
); return { container: container.firstChild, ...other }; diff --git a/packages/mui-material/src/TableCell/TableCell.test.js b/packages/mui-material/src/TableCell/TableCell.test.js index 427864cf0df7e7..3d767a3c3066d3 100644 --- a/packages/mui-material/src/TableCell/TableCell.test.js +++ b/packages/mui-material/src/TableCell/TableCell.test.js @@ -32,16 +32,6 @@ describe('', () => { ); return { container: container.firstChild.firstChild.firstChild, ...other }; }, - wrapMount: (mount) => (node) => { - const wrapper = mount( - - - {node} - -
, - ); - return wrapper.find('tr').childAt(0); - }, muiName: 'MuiTableCell', testVariantProps: { variant: 'body' }, refInstanceof: window.HTMLTableCellElement, diff --git a/packages/mui-material/src/TableFooter/TableFooter.test.js b/packages/mui-material/src/TableFooter/TableFooter.test.js index b0ffcd15d9da50..8f06544194906e 100644 --- a/packages/mui-material/src/TableFooter/TableFooter.test.js +++ b/packages/mui-material/src/TableFooter/TableFooter.test.js @@ -19,10 +19,6 @@ describe('', () => { const { container, ...other } = render({node}
); return { container: container.firstChild, ...other }; }, - wrapMount: (mount) => (node) => { - const wrapper = mount({node}
); - return wrapper.find('table').childAt(0); - }, muiName: 'MuiTableFooter', testVariantProps: { variant: 'foo' }, refInstanceof: window.HTMLTableSectionElement, diff --git a/packages/mui-material/src/TableHead/TableHead.test.js b/packages/mui-material/src/TableHead/TableHead.test.js index 0d898aee753bc2..6b235c3974b0fc 100644 --- a/packages/mui-material/src/TableHead/TableHead.test.js +++ b/packages/mui-material/src/TableHead/TableHead.test.js @@ -14,10 +14,6 @@ describe('', () => { describeConformance(, () => ({ classes, inheritComponent: 'thead', - wrapMount: (mount) => (node) => { - const wrapper = mount({node}
); - return wrapper.find('table').childAt(0); - }, render: (node) => { const { container, ...other } = render({node}
); return { container: container.firstChild, ...other }; diff --git a/packages/mui-material/src/TablePagination/TablePagination.test.js b/packages/mui-material/src/TablePagination/TablePagination.test.js index dd84205b454d2d..aae4498c9e6d5a 100644 --- a/packages/mui-material/src/TablePagination/TablePagination.test.js +++ b/packages/mui-material/src/TablePagination/TablePagination.test.js @@ -45,16 +45,6 @@ describe('', () => { ); return { container: container.firstChild.firstChild.firstChild, ...other }; }, - wrapMount: (mount) => (node) => { - const wrapper = mount( - - - {node} - -
, - ); - return wrapper.find('tr').childAt(0); - }, muiName: 'MuiTablePagination', refInstanceof: window.HTMLTableCellElement, testComponentPropWith: 'td', diff --git a/packages/mui-material/src/TableRow/TableRow.test.js b/packages/mui-material/src/TableRow/TableRow.test.js index 5dee6de9e0dc3e..1c16402755ecc3 100644 --- a/packages/mui-material/src/TableRow/TableRow.test.js +++ b/packages/mui-material/src/TableRow/TableRow.test.js @@ -26,14 +26,6 @@ describe('', () => { ); return { container: container.firstChild.firstChild, ...other }; }, - wrapMount: (mount) => (node) => { - const wrapper = mount( - - {node} -
, - ); - return wrapper.find('tbody').childAt(0); - }, muiName: 'MuiTableRow', testVariantProps: { variant: 'foo' }, refInstanceof: window.HTMLTableRowElement, diff --git a/packages/mui-material/src/Zoom/Zoom.test.js b/packages/mui-material/src/Zoom/Zoom.test.js index c3d272f2dd0650..19d330e846e811 100644 --- a/packages/mui-material/src/Zoom/Zoom.test.js +++ b/packages/mui-material/src/Zoom/Zoom.test.js @@ -15,6 +15,7 @@ describe('', () => {
, () => ({ + render, classes: {}, inheritComponent: Transition, refInstanceof: window.HTMLDivElement, diff --git a/packages/test-utils/src/describeConformance.tsx b/packages/test-utils/src/describeConformance.tsx index 3063749ac0d095..d1625eba4c5189 100644 --- a/packages/test-utils/src/describeConformance.tsx +++ b/packages/test-utils/src/describeConformance.tsx @@ -1,11 +1,8 @@ /* eslint-env mocha */ import * as React from 'react'; import { expect } from 'chai'; -import { ReactWrapper } from 'enzyme'; import ReactTestRenderer from 'react-test-renderer'; -import createMount from './createMount'; import createDescribe from './createDescribe'; -import findOutermostIntrinsic from './findOutermostIntrinsic'; import { MuiRenderResult } from './createRenderer'; function capitalize(string: string): string { @@ -45,11 +42,19 @@ export interface ConformanceOptions { refInstanceof: any; after?: () => void; inheritComponent?: React.ElementType; - render: (node: React.ReactElement) => MuiRenderResult; - mount?: (node: React.ReactElement) => ReactWrapper; + render: (node: React.ReactElement) => MuiRenderResult; only?: Array; skip?: Array; testComponentsRootPropWith?: string; + /** + * A custom React component to test if the component prop is implemented correctly. + * + * It must either: + * - Be a string that is a valid HTML tag, or + * - A component that spread props to the underlying rendered element. + * + * If not provided, the default 'em' element is used. + */ testComponentPropWith?: string | React.ElementType; testDeepOverrides?: SlotTestOverride | SlotTestOverride[]; testRootOverrides?: SlotTestOverride; @@ -57,42 +62,11 @@ export interface ConformanceOptions { testCustomVariant?: boolean; testVariantProps?: object; testLegacyComponentsProp?: boolean; - wrapMount?: ( - mount: (node: React.ReactElement) => ReactWrapper, - ) => (node: React.ReactElement) => ReactWrapper; slots?: Record; ThemeProvider?: React.ElementType; createTheme?: (arg: any) => any; } -/** - * @param {object} node - * @returns - */ -function assertDOMNode(node: unknown) { - // duck typing a DOM node - expect(typeof (node as HTMLElement).nodeName).to.equal('string'); -} - -/** - * Utility method to make assertions about the ref on an element - * The element should have a component wrapped in withStyles as the root - */ -function testRef( - element: React.ReactElement, - mount: ConformanceOptions['mount'], - onRef: (instance: unknown, wrapper: import('enzyme').ReactWrapper) => void = assertDOMNode, -) { - if (!mount) { - throwMissingPropError('mount'); - } - - const ref = React.createRef(); - - const wrapper = mount({React.cloneElement(element, { ref })}); - onRef(ref.current, wrapper); -} - /** * Glossary * - root component: @@ -102,18 +76,6 @@ function testRef( * - has the type of `inheritComponent` */ -/** - * Returns the component with the same constructor as `component` that renders - * the outermost host - */ -export function findRootComponent(wrapper: ReactWrapper, component: string | React.ElementType) { - const outermostHostElement = findOutermostIntrinsic(wrapper).getElement(); - - return wrapper.find(component as string).filterWhere((componentWrapper) => { - return componentWrapper.contains(outermostHostElement); - }); -} - export function randomStringValue() { return `s${Math.random().toString(36).slice(2)}`; } @@ -131,16 +93,20 @@ function throwMissingPropError(field: string): never { */ export function testClassName(element: React.ReactElement, getOptions: () => ConformanceOptions) { it('applies the className to the root component', () => { - const { mount } = getOptions(); - if (!mount) { - throwMissingPropError('mount'); + const { render } = getOptions(); + + if (!render) { + throwMissingPropError('render'); } const className = randomStringValue(); + const testId = randomStringValue(); - const wrapper = mount(React.cloneElement(element, { className })); + const { getByTestId } = render( + React.cloneElement(element, { className, 'data-testid': testId }), + ); - expect(findOutermostIntrinsic(wrapper).instance()).to.have.class(className); + expect(getByTestId(testId)).to.have.class(className); }); } @@ -154,42 +120,54 @@ export function testComponentProp( ) { describe('prop: component', () => { it('can render another root component with the `component` prop', () => { - const { mount, testComponentPropWith: component = 'em' } = getOptions(); - if (!mount) { - throwMissingPropError('mount'); + const { render, testComponentPropWith: component = 'em' } = getOptions(); + if (!render) { + throwMissingPropError('render'); } - const wrapper = mount(React.cloneElement(element, { component })); + const testId = randomStringValue(); - expect(findRootComponent(wrapper, component).exists()).to.equal(true); + if (typeof component === 'string') { + const { getByTestId } = render( + React.cloneElement(element, { component, 'data-testid': testId }), + ); + expect(getByTestId(testId)).not.to.equal(null); + expect(getByTestId(testId).nodeName.toLowerCase()).to.eq(component); + } else { + const componentWithTestId = (props: {}) => + React.createElement(component, { ...props, 'data-testid': testId }); + const { getByTestId } = render( + React.cloneElement(element, { + component: componentWithTestId, + }), + ); + expect(getByTestId(testId)).not.to.equal(null); + } }); }); } /** - * MUI components can spread additional props to a documented component. + * MUI components spread additional props to its root. */ export function testPropsSpread(element: React.ReactElement, getOptions: () => ConformanceOptions) { it(`spreads props to the root component`, () => { // type def in ConformanceOptions - const { inheritComponent, mount } = getOptions(); - if (!mount) { - throwMissingPropError('mount'); - } + const { render } = getOptions(); - if (inheritComponent === undefined) { - throw new TypeError( - 'Unable to test props spread without `inheritComponent`. Either skip the test or pass a React element type.', - ); + if (!render) { + throwMissingPropError('render'); } const testProp = 'data-test-props-spread'; const value = randomStringValue(); + const testId = randomStringValue(); - const wrapper = mount(React.cloneElement(element, { [testProp]: value })); - const root = findRootComponent(wrapper, inheritComponent); + const { getByTestId } = render( + React.cloneElement(element, { [testProp]: value, 'data-testid': testId }), + ); - expect(root.props()).to.have.property(testProp, value); + expect(getByTestId(testId)).to.have.attribute(testProp, value); }); } @@ -203,16 +181,17 @@ export function describeRef(element: React.ReactElement, getOptions: () => Confo describe('ref', () => { it(`attaches the ref`, () => { // type def in ConformanceOptions - const { inheritComponent, mount, refInstanceof } = getOptions(); + const { render, refInstanceof } = getOptions(); + + if (!render) { + throwMissingPropError('render'); + } - testRef(element, mount, (instance, wrapper) => { - expect(instance).to.be.instanceof(refInstanceof); + const ref = React.createRef(); - if (inheritComponent !== undefined && (instance as HTMLElement).nodeType === 1) { - const rootHost = findOutermostIntrinsic(wrapper); - expect(instance).to.equal(rootHost.instance()); - } - }); + render(React.cloneElement(element, { ref })); + + expect(ref.current).to.be.instanceof(refInstanceof); }); }); } @@ -571,14 +550,18 @@ function testSlotPropsCallback(element: React.ReactElement, getOptions: () => Co function testComponentsProp(element: React.ReactElement, getOptions: () => ConformanceOptions) { describe('prop components:', () => { it('can render another root component with the `components` prop', () => { - const { mount, testComponentsRootPropWith: component = 'em' } = getOptions(); - if (!mount) { - throwMissingPropError('mount'); + const { render, testComponentsRootPropWith: component = 'em' } = getOptions(); + if (!render) { + throwMissingPropError('render'); } - const wrapper = mount(React.cloneElement(element, { components: { Root: component } })); + const testId = randomStringValue(); - expect(findRootComponent(wrapper, component).exists()).to.equal(true); + const { getByTestId } = render( + React.cloneElement(element, { components: { Root: component }, 'data-testid': testId }), + ); + expect(getByTestId(testId)).not.to.equal(null); + expect(getByTestId(testId).nodeName.toLowerCase()).to.eq(component); }); }); } @@ -1056,7 +1039,6 @@ function describeConformance( only = Object.keys(fullSuite), slots, skip = [], - wrapMount, } = getOptions(); let filteredTests = Object.keys(fullSuite).filter( @@ -1071,21 +1053,11 @@ function describeConformance( filteredTests = filteredTests.filter((testKey) => !slotBasedTests.includes(testKey)); } - const baseMount = createMount(); - const mount = wrapMount !== undefined ? wrapMount(baseMount) : baseMount; - after(runAfterHook); - function getTestOptions(): ConformanceOptions { - return { - ...getOptions(), - mount, - }; - } - filteredTests.forEach((testKey) => { const test = fullSuite[testKey]; - test(minimalElement, getTestOptions); + test(minimalElement, getOptions); }); }