I couldn't find any solution in any other questions similar to mine so I decided to ask you for help.
I have tests to my <Login/> page:
import React from 'react';
import { render } from '../../__test__/utils';
import Login from '.';
test('Renders the Login page', () => {
const { getByTestId } = render(<Login />);
expect(getByTestId('login-page')).toBeInTheDocument(); //WORKS
});
test('Renders disabled submit button by default', () => {
const { getByTestId } = render(<Login />);
expect(getByTestId('login-button')).toHaveAttribute('disabled'); // ERROR HERE
});
test('should match base snapshot', () => {
const { asFragment } = render(<Login />);
expect(asFragment()).toMatchSnapshot(); //WORKS
});
I am using the 'utils.js' in my tests because I want to wrap every testing component in the providers I am using. Here is how the utils file looks like:
import React, { useState } from 'react';
import { render as rtlRender } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { renderRoutes } from 'react-router-config';
import { Router } from 'react-router-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { ThemeProvider } from '@material-ui/styles';
import { createMemoryHistory } from 'history';
import StylesProvider from '../components/StylesProvider';
import routes from '../routes';
import reducer from '../reducers';
import { theme } from '../theme';
const history = createMemoryHistory();
const render = (
ui,
{ initialState, store = createStore(reducer, initialState), ...renderOptions } = {}
) => {
const Wrapper = ({ children }) => {
const [direction] = useState('ltr');
return (
<Provider store={store}>
<ThemeProvider theme={theme}>
<StylesProvider direction={direction}>
<Router history={history}>
{children}
{renderRoutes(routes)}
</Router>
</StylesProvider>
</ThemeProvider>
</Provider>
);
};
return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
};
export * from '@testing-library/react';
export { render };
Unfortunately, I cannot show the whole app code so I'll make it short. The <Login /> component looks like below:
import React from 'react';
import { makeStyles } from '@material-ui/styles';
import {
Card, CardContent, CardHeader, Typography, Divider, Grid
} from '@material-ui/core';
import Page from 'src/components/Page';
import LoginForm from './LoginForm';
const Login = () => (
<Page className={classes.root} title="Login" dataTestId="login-page">
//here the component body//
<LoginForm
afterLoginRoute="/overview"
loginEndpoint="login"
userRole={userRoles.USER}
className={classes.loginForm}
/>
</Page>
)
In the <LoginForm /> component I have a Material-UI button with data-testid="login-button"
LoginForm:
return (
<div>
<Snackbar open={loginStatus.error} autoHideDuration={6000}>
<Alert severity="error">
Se ha producido un error, comprueba los credenciales y prueba de nuevo.
</Alert>
</Snackbar>
<form {...rest} className={clsx(classes.root, className)} onSubmit={handleSubmit}>
<div className={classes.fields}>
<TextField
className={classes.input}
error={hasError('email')}
fullWidth
helperText={hasError('email') ? formState.errors.email[0] : null}
label="Email"
name="email"
onChange={handleChange}
value={formState.values.email || ''}
variant="outlined"
/>
<TextField
className={classes.input}
error={hasError('password')}
fullWidth
helperText={hasError('password') ? formState.errors.password[0] : null}
label="ContraseƱa"
name="password"
onChange={handleChange}
type="password"
value={formState.values.password || ''}
variant="outlined"
/>
</div>
<Button
className={classes.submitButton}
color="secondary"
disabled={!formState.isValid}
size="large"
type="submit"
variant="contained"
data-testid="login-button"
>
Entrar
</Button>
</form>
</div>
);
Current test result I have is TestingLibraryElementError: Found multiple elements by: [data-testid="login-button"]. I am out of ideas right now. Could this happen because I try to pass the data-testid prop to the <Button /> which is imported from Material-UI library? Then, shouldn't I see other error message? Please help.