I am using material-ui in my react.js project. When I try to test my Row component, I get that console.error:
Warning: validateDOMNesting(...): <tr> cannot appear as a child of <div>.
Here is my Row component:
const Row: React.FC<RowProps> = ({ course }) => {
const [open, setOpen] = useState(false);
const classes = useRowStyles();
const isDesktopOrLaptop = useMediaQuery({
query: '(min-device-width: 992px)',
});
const boxMargin = isDesktopOrLaptop ? 8 : 1;
return (
<>
<TableRow className={classes.root}>
<TableCell>
<IconButton
aria-label="expand row"
size="small"
onClick={() => setOpen(!open)}>
{open ? (
<KeyboardArrowUpIcon fontSize="large" />
) : (
<KeyboardArrowDownIcon fontSize="large" />
)}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
<Typography variant="h5" component="h5">
{course.course}
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="h5" component="h5">
{course.openedLessonsCount}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box marginX={boxMargin} marginY={1}>
<Typography variant="h5" gutterBottom component="h5">
Projects
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>
<Typography variant="h6" gutterBottom component="h6">
Name
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="h6" gutterBottom component="h6">
Completed Lessons
</Typography>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{course.projects &&
course.projects.map((project: IProject) => (
<TableRow key={project.project}>
<TableCell component="th" scope="row">
<Typography variant="body1" gutterBottom>
{project.project}
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="body1" gutterBottom>
{project.completedLessonsCount}
</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</>
);
};
And here is generated snapshot for it:
<body>
<div>
<tr
class="MuiTableRow-root makeStyles-root-1"
>
<td
class="MuiTableCell-root"
>
<button
aria-label="expand row"
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeSmall"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</td>
<th
class="MuiTableCell-root"
role="cell"
scope="row"
>
<h5
class="MuiTypography-root MuiTypography-h5"
>
Course1
</h5>
</th>
<td
class="MuiTableCell-root MuiTableCell-alignRight"
>
<h5
class="MuiTypography-root MuiTypography-h5"
>
3
</h5>
</td>
</tr>
<tr
class="MuiTableRow-root"
>
<td
class="MuiTableCell-root"
colspan="6"
style="padding-bottom: 0px; padding-top: 0px;"
/>
</tr>
</div>
</body>
So it looks like the problem is the <div> element inside the <body>, but I don't know how to fix that error. I use React.Fragment (<>) to grab these two of TableRow, so that <div> shouldn't exist in my opinion...
That Row component I took from material-ui docs for collapsible table:
https://material-ui.com/components/tables/
And there is codesandbox code for it (also from docs): https://codesandbox.io/s/material-demo-forked-fnisr?file=/demo.js
@@ UPDATE
I had to wrap Row component with <table> and <tbody>. I've created a wrapper for that. This is how the test code looks like now:
const Wrapper: React.FC = ({ children }) => {
return (
<table>
<tbody>{children}</tbody>
</table>
);
};
test('Basic render', () => {
const component = render(
<Wrapper>
<Row course={props} />
</Wrapper>
);
expect(component.baseElement).toMatchSnapshot();
});