diff --git a/docs/src/pages/components/icons/icons.md b/docs/src/pages/components/icons/icons.md
index e7ee3583d1dc69..fa609498872cbc 100644
--- a/docs/src/pages/components/icons/icons.md
+++ b/docs/src/pages/components/icons/icons.md
@@ -76,6 +76,20 @@ Each icon also has a "theme": Filled (default), Outlined, Rounded, Two tone and
{{"demo": "pages/components/icons/SvgMaterialIcons.js"}}
+### Testing
+
+For testing purposes, each icon exposed from `@material-ui/icons` has a `data-testid` attribute with the name of the icon. For instance:
+
+```jsx
+import DeleteIcon from '@material-ui/icons/Delete';
+```
+
+has the following attribute once mounted:
+
+```html
+
+```
+
## SvgIcon
If you need a custom SVG icon (not available in the Material Icons [default set](/components/material-icons/)) you can use the `SvgIcon` wrapper.
diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
index 8addf692fb46c5..8e47b279d5a5d8 100644
--- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
+++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
@@ -386,7 +386,7 @@ describe('', () => {
it('should remove the last option', () => {
const handleChange = spy();
const options = ['one', 'two'];
- const { container } = render(
+ const { getAllByTestId } = render(
', () => {
multiple
/>,
);
- fireEvent.click(container.querySelectorAll('svg[data-mui-test="CancelIcon"]')[1]);
+ fireEvent.click(getAllByTestId('CancelIcon')[1]);
expect(handleChange.callCount).to.equal(1);
expect(handleChange.args[0][1]).to.deep.equal([options[0]]);
});
diff --git a/packages/material-ui-lab/src/Pagination/Pagination.test.js b/packages/material-ui-lab/src/Pagination/Pagination.test.js
index c401085a22e012..cf5b014b97f7d7 100644
--- a/packages/material-ui-lab/src/Pagination/Pagination.test.js
+++ b/packages/material-ui-lab/src/Pagination/Pagination.test.js
@@ -63,15 +63,12 @@ describe('', () => {
const buttons = getAllByRole('button');
- expect(buttons[0].querySelector('svg')).to.have.attribute('data-mui-test', 'LastPageIcon');
- expect(buttons[1].querySelector('svg')).to.have.attribute('data-mui-test', 'NavigateNextIcon');
+ expect(buttons[0].querySelector('svg')).to.have.attribute('data-testid', 'LastPageIcon');
+ expect(buttons[1].querySelector('svg')).to.have.attribute('data-testid', 'NavigateNextIcon');
expect(buttons[2].textContent).to.equal('1');
expect(buttons[6].textContent).to.equal('5');
- expect(buttons[7].querySelector('svg')).to.have.attribute(
- 'data-mui-test',
- 'NavigateBeforeIcon',
- );
- expect(buttons[8].querySelector('svg')).to.have.attribute('data-mui-test', 'FirstPageIcon');
+ expect(buttons[7].querySelector('svg')).to.have.attribute('data-testid', 'NavigateBeforeIcon');
+ expect(buttons[8].querySelector('svg')).to.have.attribute('data-testid', 'FirstPageIcon');
});
it('renders correct amount of buttons on correct order when boundaryCount is zero', () => {
@@ -86,13 +83,10 @@ describe('', () => {
);
const buttons = getAllByRole('button');
- expect(buttons[4].querySelector('svg')).to.have.attribute(
- 'data-mui-test',
- 'NavigateBeforeIcon',
- );
+ expect(buttons[4].querySelector('svg')).to.have.attribute('data-testid', 'NavigateBeforeIcon');
expect(buttons[1].textContent).to.equal('5');
expect(buttons[2].textContent).to.equal('6');
expect(buttons[3].textContent).to.equal('7');
- expect(buttons[0].querySelector('svg')).to.have.attribute('data-mui-test', 'NavigateNextIcon');
+ expect(buttons[0].querySelector('svg')).to.have.attribute('data-testid', 'NavigateNextIcon');
});
});
diff --git a/packages/material-ui-lab/src/SpeedDialIcon/SpeedDialIcon.test.js b/packages/material-ui-lab/src/SpeedDialIcon/SpeedDialIcon.test.js
index d69fa04f366110..0e2cb78885d89f 100644
--- a/packages/material-ui-lab/src/SpeedDialIcon/SpeedDialIcon.test.js
+++ b/packages/material-ui-lab/src/SpeedDialIcon/SpeedDialIcon.test.js
@@ -23,7 +23,7 @@ describe('', () => {
it('should render the Add icon by default', () => {
const wrapper = mount();
- expect(findOutermostIntrinsic(wrapper).find('svg[data-mui-test="AddIcon"]').length).to.equal(1);
+ expect(findOutermostIntrinsic(wrapper).find('svg[data-testid="AddIcon"]').length).to.equal(1);
});
it('should render an Icon', () => {
diff --git a/packages/material-ui/src/Avatar/Avatar.test.js b/packages/material-ui/src/Avatar/Avatar.test.js
index 40b4b59126b5dd..6cc04f4b197682 100644
--- a/packages/material-ui/src/Avatar/Avatar.test.js
+++ b/packages/material-ui/src/Avatar/Avatar.test.js
@@ -127,7 +127,7 @@ describe('', () => {
it('should render a div containing an svg icon', () => {
expect(avatar.tagName).to.equal('DIV');
const cancelIcon = avatar.firstChild;
- expect(cancelIcon).to.have.attribute('data-mui-test', 'CancelIcon');
+ expect(cancelIcon).to.have.attribute('data-testid', 'CancelIcon');
});
it('should merge user classes & spread custom props to the root node', () => {
diff --git a/packages/material-ui/src/Breadcrumbs/Breadcrumbs.test.js b/packages/material-ui/src/Breadcrumbs/Breadcrumbs.test.js
index 273e3a009d0bec..c397f4b9f0b821 100644
--- a/packages/material-ui/src/Breadcrumbs/Breadcrumbs.test.js
+++ b/packages/material-ui/src/Breadcrumbs/Breadcrumbs.test.js
@@ -62,7 +62,7 @@ describe('', () => {
expect(listitems).to.have.length(3);
expect(getByRole('list')).to.have.text('first//ninth');
- expect(getByRole('button').querySelector('[data-mui-test="MoreHorizIcon"]')).not.to.equal(null);
+ expect(getByRole('button').querySelector('[data-testid="MoreHorizIcon"]')).not.to.equal(null);
});
it('should expand when `BreadcrumbCollapsed` is clicked', () => {
diff --git a/packages/material-ui/src/Checkbox/Checkbox.test.js b/packages/material-ui/src/Checkbox/Checkbox.test.js
index b605a3805db2d8..e6cb29dcf7918e 100644
--- a/packages/material-ui/src/Checkbox/Checkbox.test.js
+++ b/packages/material-ui/src/Checkbox/Checkbox.test.js
@@ -64,10 +64,8 @@ describe('', () => {
describe('prop: indeterminate', () => {
it('should render an indeterminate icon', () => {
- const { container } = render();
- expect(
- container.querySelector('svg[data-mui-test="IndeterminateCheckBoxIcon"]'),
- ).not.to.equal(null);
+ const { getByTestId } = render();
+ expect(getByTestId('IndeterminateCheckBoxIcon')).not.to.equal(null);
});
});
diff --git a/packages/material-ui/src/Chip/Chip.test.js b/packages/material-ui/src/Chip/Chip.test.js
index 99f16380e39d3e..1c8910ba7cc0a9 100644
--- a/packages/material-ui/src/Chip/Chip.test.js
+++ b/packages/material-ui/src/Chip/Chip.test.js
@@ -253,27 +253,27 @@ describe('', () => {
describe('prop: deleteIcon', () => {
it('should render a default icon with the root, deletable, deleteIcon and deleteIconOutlinedColorSecondary classes', () => {
- const { container, getByRole } = render(
+ const { getByRole, getByTestId } = render(
{}} />,
);
- const icon = container.querySelector('svg[data-mui-test="CancelIcon"]');
+ const icon = getByTestId('CancelIcon');
expect(getByRole('button')).to.contain(icon);
expect(icon).to.have.class(classes.deleteIcon);
});
it('should render a default icon with the root, deletable and deleteIcon classes', () => {
- const { container, getByRole } = render(
+ const { getByRole, getByTestId } = render(
{}} />,
);
- const icon = container.querySelector('svg[data-mui-test="CancelIcon"]');
+ const icon = getByTestId('CancelIcon');
expect(getByRole('button')).to.contain(icon);
expect(icon).to.have.class(classes.deleteIcon);
});
it('should render default icon with the root, deletable and deleteIcon primary class', () => {
- const { container } = render(
+ const { container, getByTestId } = render(
{}} color="primary" />,
);
@@ -281,13 +281,13 @@ describe('', () => {
expect(chip).to.have.class(classes.colorPrimary);
expect(chip).to.have.class(classes.deletable);
expect(chip).to.have.class(classes.deletableColorPrimary);
- const icon = chip.querySelector('svg[data-mui-test="CancelIcon"]');
+ const icon = getByTestId('CancelIcon');
expect(icon).to.have.class(classes.deleteIcon);
expect(icon).to.have.class(classes.deleteIconColorPrimary);
});
it('should render a default icon with the root, deletable, deleteIcon secondary class', () => {
- const { container } = render(
+ const { container, getByTestId } = render(
{}} color="secondary" />,
);
@@ -295,18 +295,18 @@ describe('', () => {
expect(chip).to.have.class(classes.colorSecondary);
expect(chip).to.have.class(classes.deletable);
expect(chip).to.have.class(classes.deletableColorSecondary);
- const icon = chip.querySelector('svg[data-mui-test="CancelIcon"]');
+ const icon = getByTestId('CancelIcon');
expect(icon).to.have.class(classes.deleteIcon);
expect(icon).to.have.class(classes.deleteIconColorSecondary);
});
it('accepts a custom icon', () => {
const handleDelete = spy();
- const { container } = render(
+ const { getByTestId } = render(
} />,
);
- fireEvent.click(container.querySelector('svg[data-mui-test="CheckBoxIcon"]'));
+ fireEvent.click(getByTestId('CheckBoxIcon'));
expect(handleDelete.callCount).to.equal(1);
});
@@ -532,9 +532,9 @@ describe('', () => {
});
it('should render the delete icon with the deleteIcon and deleteIconSmall classes', () => {
- const { container } = render( {}} />);
+ const { getByTestId } = render( {}} />);
- const icon = container.querySelector('svg[data-mui-test="CancelIcon"]');
+ const icon = getByTestId('CancelIcon');
expect(icon).to.have.class(classes.deleteIcon);
expect(icon).to.have.class(classes.deleteIconSmall);
});
diff --git a/packages/material-ui/src/MobileStepper/MobileStepper.test.js b/packages/material-ui/src/MobileStepper/MobileStepper.test.js
index 157c873fea3e91..01ec40bb94fe7d 100644
--- a/packages/material-ui/src/MobileStepper/MobileStepper.test.js
+++ b/packages/material-ui/src/MobileStepper/MobileStepper.test.js
@@ -63,14 +63,14 @@ describe('', () => {
const wrapper = mount();
const backButton = wrapper.find('button[aria-label="back"]');
expect(backButton.exists()).to.equal(true);
- expect(backButton.find('svg[data-mui-test="KeyboardArrowLeftIcon"]')).to.have.lengthOf(1);
+ expect(backButton.find('svg[data-testid="KeyboardArrowLeftIcon"]')).to.have.lengthOf(1);
});
it('should render next button', () => {
const wrapper = mount();
const nextButton = wrapper.find('button[aria-label="next"]');
expect(nextButton.exists()).to.equal(true);
- expect(nextButton.find('svg[data-mui-test="KeyboardArrowRightIcon"]')).to.have.lengthOf(1);
+ expect(nextButton.find('svg[data-testid="KeyboardArrowRightIcon"]')).to.have.lengthOf(1);
});
it('should render two buttons and text displaying progress when supplied with variant text', () => {
diff --git a/packages/material-ui/src/Radio/Radio.test.js b/packages/material-ui/src/Radio/Radio.test.js
index 3b37589edecc29..d3e39f979b5e1b 100644
--- a/packages/material-ui/src/Radio/Radio.test.js
+++ b/packages/material-ui/src/Radio/Radio.test.js
@@ -32,19 +32,15 @@ describe('', () => {
describe('prop: unchecked', () => {
it('should render an unchecked icon', () => {
- const { container } = render();
- expect(
- container.querySelectorAll('svg[data-mui-test="RadioButtonUncheckedIcon"]').length,
- ).to.equal(1);
+ const { getAllByTestId } = render();
+ expect(getAllByTestId('RadioButtonUncheckedIcon').length).to.equal(1);
});
});
describe('prop: checked', () => {
it('should render a checked icon', () => {
- const { container } = render();
- expect(
- container.querySelectorAll('svg[data-mui-test="RadioButtonCheckedIcon"]').length,
- ).to.equal(1);
+ const { getAllByTestId } = render();
+ expect(getAllByTestId('RadioButtonCheckedIcon').length).to.equal(1);
});
});
diff --git a/packages/material-ui/src/StepIcon/StepIcon.test.js b/packages/material-ui/src/StepIcon/StepIcon.test.js
index 5f2f013aa2e56c..64b7c435892d05 100644
--- a/packages/material-ui/src/StepIcon/StepIcon.test.js
+++ b/packages/material-ui/src/StepIcon/StepIcon.test.js
@@ -21,14 +21,14 @@ describe('', () => {
}));
it('renders when completed', () => {
- const { container } = render();
+ const { getAllByTestId } = render();
- expect(container.querySelectorAll('svg[data-mui-test="CheckCircleIcon"]')).to.have.length(1);
+ expect(getAllByTestId('CheckCircleIcon')).to.have.length(1);
});
it('renders when error occurred', () => {
- const { container } = render();
- expect(container.querySelectorAll('svg[data-mui-test="WarningIcon"]')).to.have.length(1);
+ const { getAllByTestId } = render();
+ expect(getAllByTestId('WarningIcon')).to.have.length(1);
});
it('contains text "3" when position is "3"', () => {
diff --git a/packages/material-ui/src/StepLabel/StepLabel.test.js b/packages/material-ui/src/StepLabel/StepLabel.test.js
index 20bedb790c4606..747985cda0d3fe 100644
--- a/packages/material-ui/src/StepLabel/StepLabel.test.js
+++ b/packages/material-ui/src/StepLabel/StepLabel.test.js
@@ -47,7 +47,7 @@ describe('', () => {
const icon = container.querySelector(`.${iconClasses.root}`);
// Should render WarningIcon instead of CheckCircleIcon because of { error: true } props
- expect(icon).to.have.attribute('data-mui-test').equal('WarningIcon');
+ expect(icon).to.have.attribute('data-testid').equal('WarningIcon');
});
});
@@ -65,7 +65,7 @@ describe('', () => {
getByTestId('custom-icon');
expect(icon).to.not.equal(null);
- expect(icon).to.not.have.attribute('data-mui-test').equal('CheckCircleIcon');
+ expect(icon).to.not.have.attribute('data-testid').equal('CheckCircleIcon');
expect(label).to.have.class(classes.active);
expect(label).to.have.class(classes.completed);
});
diff --git a/packages/material-ui/src/TabScrollButton/TabScrollButton.test.js b/packages/material-ui/src/TabScrollButton/TabScrollButton.test.js
index 205ceb9976663a..41ee14947e2ccb 100644
--- a/packages/material-ui/src/TabScrollButton/TabScrollButton.test.js
+++ b/packages/material-ui/src/TabScrollButton/TabScrollButton.test.js
@@ -39,21 +39,17 @@ describe('', () => {
describe('prop: direction', () => {
it('should render with the left icon', () => {
- const { container } = render(
+ const { getAllByTestId } = render(
,
);
- expect(
- container.querySelectorAll('svg[data-mui-test="KeyboardArrowLeftIcon"]').length,
- ).to.equal(1);
+ expect(getAllByTestId('KeyboardArrowLeftIcon').length).to.equal(1);
});
it('should render with the right icon', () => {
- const { container } = render(
+ const { getAllByTestId } = render(
,
);
- expect(
- container.querySelectorAll('svg[data-mui-test="KeyboardArrowRightIcon"]').length,
- ).to.equal(1);
+ expect(getAllByTestId('KeyboardArrowRightIcon').length).to.equal(1);
});
});
});
diff --git a/packages/material-ui/src/TableSortLabel/TableSortLabel.test.js b/packages/material-ui/src/TableSortLabel/TableSortLabel.test.js
index 7745f3e44a8671..f611c1c7f22793 100644
--- a/packages/material-ui/src/TableSortLabel/TableSortLabel.test.js
+++ b/packages/material-ui/src/TableSortLabel/TableSortLabel.test.js
@@ -57,9 +57,8 @@ describe('', () => {
});
it('should accept a custom icon for the sort icon', () => {
- const { container } = render();
- const icon = container.querySelector(`svg.${classes.icon}[data-mui-test="SortIcon"]`);
- expect(icon).to.not.equal(null);
+ const { getAllByTestId } = render();
+ expect(getAllByTestId('SortIcon')).to.not.equal(null);
});
});
diff --git a/packages/material-ui/src/Tabs/Tabs.test.js b/packages/material-ui/src/Tabs/Tabs.test.js
index 72935034196771..4a148bc9fda9d5 100644
--- a/packages/material-ui/src/Tabs/Tabs.test.js
+++ b/packages/material-ui/src/Tabs/Tabs.test.js
@@ -17,7 +17,7 @@ import Tabs from './Tabs';
import { createMuiTheme, ThemeProvider } from '../styles';
function findScrollButton(container, direction) {
- return container.querySelector(`svg[data-mui-test="KeyboardArrow${capitalize(direction)}Icon"]`);
+ return container.querySelector(`svg[data-testid="KeyboardArrow${capitalize(direction)}Icon"]`);
}
function hasLeftScrollButton(container) {
diff --git a/packages/material-ui/src/utils/createSvgIcon.js b/packages/material-ui/src/utils/createSvgIcon.js
index 2d146ab87dafa5..5f53ccca289bfd 100644
--- a/packages/material-ui/src/utils/createSvgIcon.js
+++ b/packages/material-ui/src/utils/createSvgIcon.js
@@ -6,7 +6,7 @@ import SvgIcon from '../SvgIcon';
*/
export default function createSvgIcon(path, displayName) {
const Component = (props, ref) => (
-
+
{path}
);