diff --git a/src/login/tests/AccountActivationMessage.test.jsx b/src/login/tests/AccountActivationMessage.test.jsx
index 740f270bd9..df2a0c0859 100644
--- a/src/login/tests/AccountActivationMessage.test.jsx
+++ b/src/login/tests/AccountActivationMessage.test.jsx
@@ -2,7 +2,9 @@ import React from 'react';
import { mergeConfig } from '@edx/frontend-platform';
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
-import { mount } from 'enzyme';
+import {
+ render, screen,
+} from '@testing-library/react';
import AccountActivationMessage from '../AccountActivationMessage';
import { ACCOUNT_ACTIVATION_MESSAGE } from '../data/constants';
@@ -17,18 +19,22 @@ describe('AccountActivationMessage', () => {
});
it('should match account already activated message', () => {
- const accountActivationMessage = mount(
+ render(
,
);
const expectedMessage = 'This account has already been activated.';
- expect(accountActivationMessage.find('#account-activation-message').find('div').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toBe(expectedMessage);
});
it('should match account activated success message', () => {
- const accountActivationMessage = mount(
+ render(
,
@@ -37,11 +43,15 @@ describe('AccountActivationMessage', () => {
const expectedMessage = 'Success! You have activated your account.'
+ 'You will now receive email updates and alerts from us related to '
+ 'the courses you are enrolled in. Sign in to continue.';
- expect(accountActivationMessage.find('#account-activation-message').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toBe(expectedMessage);
});
it('should match account activation error message', () => {
- const accountActivationMessage = mount(
+ render(
,
@@ -49,17 +59,22 @@ describe('AccountActivationMessage', () => {
const expectedMessage = 'Your account could not be activated'
+ 'Something went wrong, please contact support to resolve this issue.';
- expect(accountActivationMessage.find('#account-activation-message').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toBe(expectedMessage);
});
it('should not display anything for invalid message type', () => {
- const accountActivationMessage = mount(
+ const { container } = render(
,
);
- expect(accountActivationMessage).toEqual({});
+ const accountActivationMessage = container.querySelectorAll('#account-activation-message');
+ expect(accountActivationMessage[0]).toBe(undefined);
});
});
@@ -71,36 +86,45 @@ describe('EmailConfirmationMessage', () => {
});
it('should match email already confirmed message', () => {
- const accountVerificationMessage = mount(
+ render(
,
);
const expectedMessage = 'This email has already been confirmed.';
- expect(accountVerificationMessage.find('#account-activation-message').find('div').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toBe(expectedMessage);
});
it('should match email confirmation success message', () => {
- const accountVerificationMessage = mount(
+ render(
,
);
-
const expectedMessage = 'Success! You have confirmed your email.Sign in to continue.';
- expect(accountVerificationMessage.find('#account-activation-message').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toBe(expectedMessage);
});
it('should match email confirmation error message', () => {
- const accountVerificationMessage = mount(
+ render(
,
);
-
const expectedMessage = 'Your email could not be confirmed'
+ 'Something went wrong, please contact support to resolve this issue.';
- expect(accountVerificationMessage.find('#account-activation-message').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toBe(expectedMessage);
});
});
diff --git a/src/login/tests/ChangePasswordPrompt.test.jsx b/src/login/tests/ChangePasswordPrompt.test.jsx
index 0c5c2776e2..f544a55c6c 100644
--- a/src/login/tests/ChangePasswordPrompt.test.jsx
+++ b/src/login/tests/ChangePasswordPrompt.test.jsx
@@ -2,7 +2,9 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
-import { mount } from 'enzyme';
+import {
+ fireEvent, render, screen,
+} from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { MemoryRouter } from 'react-router-dom';
@@ -39,7 +41,7 @@ describe('ChangePasswordPromptTests', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL };
- const changePasswordPrompt = mount(
+ render(
@@ -47,7 +49,7 @@ describe('ChangePasswordPromptTests', () => {
,
);
- changePasswordPrompt.find('button#password-security-close').simulate('click');
+ fireEvent.click(screen.getByText('Close'));
expect(window.location.href).toBe(dashboardUrl);
});
@@ -56,7 +58,7 @@ describe('ChangePasswordPromptTests', () => {
variant: 'block',
};
- const changePasswordPrompt = mount(
+ render(
@@ -65,10 +67,12 @@ describe('ChangePasswordPromptTests', () => {
);
await act(async () => {
- await changePasswordPrompt.find('div.pgn__modal-backdrop').first().simulate('click');
+ await fireEvent.click(screen.getByText(
+ '',
+ { selector: '.pgn__modal-backdrop' },
+ ));
});
- changePasswordPrompt.update();
expect(mockedNavigator).toHaveBeenCalledWith(RESET_PAGE);
});
});
diff --git a/src/login/tests/LoginFailure.test.jsx b/src/login/tests/LoginFailure.test.jsx
index 2357b61129..dc97fccb12 100644
--- a/src/login/tests/LoginFailure.test.jsx
+++ b/src/login/tests/LoginFailure.test.jsx
@@ -1,7 +1,9 @@
import React from 'react';
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
-import { mount } from 'enzyme';
+import {
+ render, screen,
+} from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import {
@@ -44,7 +46,7 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
@@ -55,7 +57,10 @@ describe('LoginFailureMessage', () => {
+ 'password-reset message to the email address associated with this account. '
+ 'Thank you for helping us keep your data safe.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('should match inactive user error message', () => {
@@ -70,7 +75,7 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
@@ -80,8 +85,12 @@ describe('LoginFailureMessage', () => {
+ 'We just sent an activation link to text@example.com. If you do not receive an email, '
+ 'check your spam folders or contact openedX support.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
- expect(loginFailureMessage.find('#login-failure-alert').find('a').props().href).toEqual('http://support.openedx.test');
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
+
+ expect(screen.getByRole('link', { name: 'contact openedX support' }).getAttribute('href')).toBe('http://support.openedx.test');
});
it('test match failed login attempt error', () => {
@@ -97,15 +106,19 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
+
const expectedMessage = 'We couldn\'t sign you in.The username, email or password you entered is incorrect. '
+ 'You have 3 more sign in attempts before your account is temporarily locked.If you\'ve forgotten your password, click here to reset it.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('test match failed login error first attempt', () => {
@@ -120,14 +133,18 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
+
const expectedMessage = 'We couldn\'t sign you in.The username, email, or password you entered is incorrect. Please try again.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('test match failed login error second attempt', () => {
@@ -142,14 +159,18 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
+
const expectedMessage = 'We couldn\'t sign you in.The username, email, or password you entered is incorrect. Please try again or reset your password.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('should match rate limit error message', () => {
@@ -159,14 +180,18 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
const expectedMessage = 'We couldn\'t sign you in.Too many failed login attempts. Try again later.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('should match internal server error message', () => {
@@ -176,14 +201,18 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
const expectedMessage = 'We couldn\'t sign you in.An error has occurred. Try refreshing the page, or check your internet connection.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('should match invalid form error message', () => {
@@ -193,14 +222,17 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
const expectedMessage = 'We couldn\'t sign you in.Please fill in the fields below.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('should match internal server of error message', () => {
@@ -210,14 +242,17 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
);
const expectedMessage = 'We couldn\'t sign you in.An error has occurred. Try refreshing the page, or check your internet connection.';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toBe(expectedMessage);
});
it('should match tpa authentication failed error message', () => {
@@ -230,7 +265,7 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
@@ -238,8 +273,15 @@ describe('LoginFailureMessage', () => {
const expectedMessageSubstring = 'We are sorry, you are not authorized to access';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toContain(expectedMessageSubstring);
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toContain('An error occurred');
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toContain(expectedMessageSubstring);
+
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toContain('An error occurred');
});
it('should show modal that nudges users to change password', () => {
@@ -249,7 +291,7 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
@@ -257,11 +299,16 @@ describe('LoginFailureMessage', () => {
,
);
- expect(loginFailureMessage.find('.pgn__modal-title').text()).toEqual('Password security');
- expect(loginFailureMessage.find('.pgn__modal-body').text()).toEqual(
- 'Our system detected that your password is vulnerable. '
- + 'We recommend you change it so that your account stays secure.',
- );
+ const message = 'Our system detected that your password is vulnerable. '
+ + 'We recommend you change it so that your account stays secure.';
+ expect(screen.getByText(
+ 'Password security',
+ { selector: '.pgn__modal-title' },
+ ).textContent).toEqual('Password security');
+ expect(screen.getByText(
+ '',
+ { selector: '.pgn__modal-body' },
+ ).textContent).toEqual(message);
});
it('should show modal that requires users to change password', () => {
@@ -271,7 +318,7 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
@@ -279,8 +326,14 @@ describe('LoginFailureMessage', () => {
,
);
- expect(loginFailureMessage.find('.pgn__modal-title').text()).toEqual('Password change required');
- expect(loginFailureMessage.find('.pgn__modal-body').text()).toEqual(
+ expect(screen.getByText(
+ 'Password change required',
+ { selector: '.pgn__modal-title' },
+ ).textContent).toEqual('Password change required');
+ expect(screen.getByText(
+ '',
+ { selector: '.pgn__modal-body' },
+ ).textContent).toEqual(
'Our system detected that your password is vulnerable. '
+ 'Change your password so that your account stays secure.',
);
@@ -299,7 +352,7 @@ describe('LoginFailureMessage', () => {
},
};
- const loginFailureMessage = mount(
+ render(
,
@@ -308,7 +361,11 @@ describe('LoginFailureMessage', () => {
const errorMessage = "We couldn't sign you in.As test.com user, You must login with your test.com Google account.";
const url = 'http://localhost:18000/dashboard/?tpa_hint=google-auth2';
- expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(errorMessage);
- expect(loginFailureMessage.find('#login-failure-alert').find('a').props().href).toEqual(url);
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toContain(errorMessage);
+
+ expect(screen.getByRole('link', { name: 'Google account' }).getAttribute('href')).toBe(url);
});
});
diff --git a/src/login/tests/LoginPage.test.jsx b/src/login/tests/LoginPage.test.jsx
index 1a5c7e9e14..cffbea42fa 100644
--- a/src/login/tests/LoginPage.test.jsx
+++ b/src/login/tests/LoginPage.test.jsx
@@ -4,9 +4,11 @@ import { Provider } from 'react-redux';
import { getConfig, mergeConfig } from '@edx/frontend-platform';
import { sendPageEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
-import { mount } from 'enzyme';
+import {
+ fireEvent, render, screen, waitFor,
+} from '@testing-library/react';
+import { act } from 'react-dom/test-utils';
import { MemoryRouter } from 'react-router-dom';
-import renderer from 'react-test-renderer';
import configureStore from 'redux-mock-store';
import { COMPLETE_STATE, LOGIN_PAGE, PENDING_STATE } from '../../data/constants';
@@ -14,7 +16,6 @@ import {
loginRemovePasswordResetBanner, loginRequest, loginRequestFailure, loginRequestReset, setLoginFormData,
} from '../data/actions';
import { INTERNAL_SERVER_ERROR } from '../data/constants';
-import LoginFailureMessage from '../LoginFailure';
import LoginPage from '../LoginPage';
jest.mock('@edx/frontend-platform/analytics', () => ({
@@ -25,7 +26,6 @@ jest.mock('@edx/frontend-platform/auth', () => ({
getAuthService: jest.fn(),
}));
-const IntlLoginFailureMessage = injectIntl(LoginFailureMessage);
const IntlLoginPage = injectIntl(LoginPage);
const mockStore = configureStore();
@@ -97,67 +97,108 @@ describe('LoginPage', () => {
it('should submit form for valid input', () => {
store.dispatch = jest.fn(store.dispatch);
- const loginPage = mount(reduxWrapper());
- loginPage.find('input#emailOrUsername').simulate('change', { target: { value: 'test@example.com' } });
- loginPage.find('input#password').simulate('change', { target: { value: 'password' } });
- loginPage.find('button.btn-brand').simulate('click');
+ render(reduxWrapper());
+
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#emailOrUsername' },
+ ), { target: { value: 'test@example.com' } });
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#password' },
+ ), { target: { value: 'password' } });
+
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
expect(store.dispatch).toHaveBeenCalledWith(loginRequest({ email_or_username: 'test@example.com', password: 'password' }));
});
it('should not dispatch loginRequest on empty form submission', () => {
store.dispatch = jest.fn(store.dispatch);
- const loginPage = mount(reduxWrapper());
+ render(reduxWrapper());
- loginPage.find('button.btn-brand').simulate('click');
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
expect(store.dispatch).not.toHaveBeenCalledWith(loginRequest({}));
});
// ******** test login form validations ********
it('should match state on empty form submission', () => {
- const errorState = { emailOrUsername: 'Enter your username or email', password: 'Enter your password' };
store.dispatch = jest.fn(store.dispatch);
- const loginPage = (mount(reduxWrapper())).find('LoginPage');
- loginPage.find('button.btn-brand').simulate('click');
+ render(reduxWrapper());
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
- // Check that loginRequestFailure was dispatched and state is updated
- expect(loginPage.state('errors')).toEqual(errorState);
+ expect(screen.getByText('Enter your username or email')).toBeDefined();
expect(store.dispatch).toHaveBeenCalledWith(loginRequestFailure({ errorCode: 'invalid-form' }));
});
it('should match state for invalid email (less than 3 characters), on form submission', () => {
- const errorState = { emailOrUsername: 'Username or email must have at least 3 characters.', password: '' };
store.dispatch = jest.fn(store.dispatch);
- const loginPage = (mount(reduxWrapper())).find('LoginPage');
+ render(reduxWrapper());
+
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#password' },
+ ), { target: { value: 'test' } });
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#emailOrUsername' },
+ ), { target: { value: 'te' } });
- loginPage.find('input#password').simulate('change', { target: { value: 'test', name: 'password' } });
- loginPage.find('input#emailOrUsername').simulate('change', { target: { value: 'te', name: 'email' } });
- loginPage.find('button.btn-brand').simulate('click');
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
- expect(loginPage.state('errors')).toEqual(errorState);
+ expect(screen.getByText('Username or email must have at least 3 characters.')).toBeDefined();
});
- it('should reset field related error messages on onFocus event', () => {
- const errorState = { emailOrUsername: '', password: '' };
+ it('should reset field related error messages on onFocus event', async () => {
store.dispatch = jest.fn(store.dispatch);
- const loginPage = (mount(reduxWrapper())).find('LoginPage');
- loginPage.find('button.btn-brand').simulate('click');
+ render(reduxWrapper());
+
+ await act(async () => {
+ // clicking submit button with empty fields to make the errors appear
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
+
+ // focusing the fields to verify that the errors are cleared
+ fireEvent.focus(screen.getByText(
+ '',
+ { selector: '#password' },
+ ));
+ fireEvent.focus(screen.getByText(
+ '',
+ { selector: '#emailOrUsername' },
+ ));
+ });
- loginPage.find('input#emailOrUsername').simulate('focus');
- loginPage.find('input#password').simulate('focus');
- expect(loginPage.state('errors')).toEqual(errorState);
+ // verifying that the errors are cleared
+ await waitFor(() => {
+ expect(screen.queryByText('Enter your username or email')).toBeNull();
+ });
});
// ******** test form buttons and links ********
it('should match default button state', () => {
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('button[type="submit"] span').first().text()).toEqual('Sign in');
+ render(reduxWrapper());
+ expect(screen.getByText('Sign in')).toBeDefined();
});
it('should match pending button state', () => {
@@ -169,15 +210,20 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- const button = loginPage.find('button[type="submit"] span').first();
+ render(reduxWrapper());
- expect(button.find('.sr-only').text()).toEqual('pending');
+ expect(screen.getByText(
+ 'pending',
+ ).textContent).toEqual('pending');
});
it('should show forgot password link', () => {
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('a#forgot-password').text()).toEqual('Forgot password');
+ render(reduxWrapper());
+
+ expect(screen.getByText(
+ 'Forgot password',
+ { selector: '#forgot-password' },
+ ).textContent).toEqual('Forgot password');
});
it('should show single sign on provider button', () => {
@@ -198,8 +244,11 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find(`button#${ssoProvider.id}`).length).toEqual(1);
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: `#${ssoProvider.id}` },
+ )).toBeDefined();
mergeConfig({
DISABLE_ENTERPRISE_LOGIN: '',
@@ -207,8 +256,8 @@ describe('LoginPage', () => {
});
it('should not display institution login option when no secondary providers are present', () => {
- const root = mount(reduxWrapper());
- expect(root.text().includes('Use my university info')).toBe(false);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Use my university info')).toBeNull();
});
it('should not show sign-in header and enterprise login once user authenticated through SSO', () => {
@@ -230,9 +279,9 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Company or school credentials')).toBe(false);
- expect(loginPage.text().includes('Or sign in with:')).toBe(false);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Company or school credentials')).toBeNull();
+ expect(queryByText('Or sign in with:')).toBeNull();
});
it('should show sign-in header providers (ENABLE ENTERPRISE LOGIN)', () => {
@@ -253,10 +302,10 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Or sign in with:')).toBe(true);
- expect(loginPage.text().includes('Company or school credentials')).toBe(true);
- expect(loginPage.text().includes('Institution/campus credentials')).toBe(false);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Or sign in with:')).toBeDefined();
+ expect(queryByText('Company or school credentials')).toBeDefined();
+ expect(queryByText('Institution/campus credentials')).toBeDefined();
});
it('should show sign-in header with providers (DISABLE ENTERPRISE LOGIN)', () => {
@@ -277,10 +326,10 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Or sign in with:')).toBe(true);
- expect(loginPage.text().includes('Company or school credentials')).toBe(false);
- expect(loginPage.text().includes('Institution/campus credentials')).toBe(false);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Or sign in with:')).toBeDefined();
+ expect(queryByText('Company or school credentials')).toBeNull();
+ expect(queryByText('Institution/campus credentials')).toBeNull();
mergeConfig({
DISABLE_ENTERPRISE_LOGIN: '',
@@ -302,10 +351,10 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Or sign in with:')).toBe(false);
- expect(loginPage.text().includes('Company or school credentials')).toBe(false);
- expect(loginPage.text().includes('Institution/campus credentials')).toBe(false);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Or sign in with:')).toBeNull();
+ expect(queryByText('Company or school credentials')).toBeNull();
+ expect(queryByText('Institution/campus credentials')).toBeNull();
});
it('should not show sign-in header without Providers and secondary Providers (DISABLE ENTERPRISE LOGIN)', () => {
@@ -323,10 +372,10 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Or sign in with:')).toBe(false);
- expect(loginPage.text().includes('Company or school credentials')).toBe(false);
- expect(loginPage.text().includes('Institution/campus credentials')).toBe(false);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Or sign in with:')).toBeNull();
+ expect(queryByText('Company or school credentials')).toBeNull();
+ expect(queryByText('Institution/campus credentials')).toBeNull();
mergeConfig({
DISABLE_ENTERPRISE_LOGIN: '',
@@ -351,9 +400,9 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Or sign in with:')).toBe(true);
- expect(loginPage.text().includes('Institution/campus credentials')).toBe(true);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Or sign in with:')).toBeDefined();
+ expect(queryByText('Institution/campus credentials')).toBeDefined();
mergeConfig({
DISABLE_ENTERPRISE_LOGIN: '',
@@ -381,10 +430,10 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.text().includes('Or sign in with:')).toBe(true);
- expect(loginPage.text().includes('Company or school credentials')).toBe(false);
- expect(loginPage.text().includes('Institution/campus credentials')).toBe(true);
+ const { queryByText } = render(reduxWrapper());
+ expect(queryByText('Or sign in with:')).toBeDefined();
+ expect(queryByText('Company or school credentials')).toBeNull();
+ expect(queryByText('Institution/campus credentials')).toBeDefined();
mergeConfig({
DISABLE_ENTERPRISE_LOGIN: '',
@@ -403,8 +452,11 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('#login-failure-alert').first().text()).toEqual(`We couldn't sign you in.${errorMessage}`);
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toEqual(`We couldn't sign you in.${errorMessage}`);
});
it('should match account activation message', () => {
@@ -415,8 +467,11 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: '?account_activation_status=success' };
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('div#account-activation-message').text()).toEqual(activationMessage);
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: '#account-activation-message' },
+ ).textContent).toEqual(activationMessage);
});
it('should match third party auth alert', () => {
@@ -436,8 +491,11 @@ describe('LoginPage', () => {
+ 'linked '}${ getConfig().SITE_NAME } account. To link your accounts, sign in now using your ${
getConfig().SITE_NAME } password.`;
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('#tpa-alert').find('p').text()).toEqual(expectedMessage);
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: '#tpa-alert' },
+ ).textContent).toEqual(expectedMessage);
});
it('should show tpa authentication fails error message', () => {
@@ -453,8 +511,11 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('#login-failure-alert').find('p').text()).toContain('An error occurred');
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toContain('An error occurred');
});
it('should match invalid login form error message', () => {
@@ -467,8 +528,11 @@ describe('LoginPage', () => {
},
});
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('#login-failure-alert p').first().text()).toEqual(errorMessage);
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: '#login-failure-alert' },
+ ).textContent).toContain(errorMessage);
});
// ******** test redirection ********
@@ -488,7 +552,7 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL };
- renderer.create(reduxWrapper());
+ render(reduxWrapper());
expect(window.location.href).toBe(dashboardUrl);
});
@@ -515,7 +579,7 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL };
- renderer.create(reduxWrapper());
+ render(reduxWrapper());
expect(window.location.href).toBe(getConfig().LMS_BASE_URL + authCompleteUrl);
});
@@ -542,9 +606,12 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL };
- const loginPage = mount(reduxWrapper());
+ render(reduxWrapper());
- loginPage.find('button#oa2-apple-id').simulate('click');
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '#oa2-apple-id' },
+ ));
expect(window.location.href).toBe(getConfig().LMS_BASE_URL + loginUrl);
mergeConfig({
@@ -570,9 +637,15 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: `?next=/dashboard&tpa_hint=${ssoProvider.id}` };
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find(`button#${ssoProvider.id}`).find('span').text()).toEqual(ssoProvider.name);
- expect(loginPage.find(`button#${ssoProvider.id}`).hasClass(`btn-tpa btn-${ssoProvider.id}`)).toEqual(true);
+ render(reduxWrapper());
+ expect(screen.getByText(
+ '',
+ { selector: `#${ssoProvider.id}` },
+ ).textContent).toEqual(ssoProvider.name);
+ expect(screen.getByText(
+ '',
+ { selector: `.btn-${ssoProvider.id}` },
+ )).toBeTruthy();
});
it('should render tpa button for tpa_hint id matching one of the secondary providers', () => {
@@ -593,7 +666,7 @@ describe('LoginPage', () => {
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: `?next=/dashboard&tpa_hint=${secondaryProviders.id}` };
secondaryProviders.iconImage = null;
- mount(reduxWrapper());
+ render(reduxWrapper());
expect(window.location.href).toEqual(getConfig().LMS_BASE_URL + secondaryProviders.loginUrl);
});
@@ -617,8 +690,8 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: '?next=/dashboard&tpa_hint=invalid' };
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find(`button#${ssoProvider.id}`).find('span#provider-name').text()).toEqual(`${ssoProvider.name}`);
+ const { container } = render(reduxWrapper());
+ expect(container.querySelector(`#${ssoProvider.id}`).querySelector('#provider-name').textContent).toEqual(`${ssoProvider.name}`);
mergeConfig({
DISABLE_ENTERPRISE_LOGIN: '',
@@ -641,8 +714,10 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: `?tpa_hint=${ssoProvider.id}` };
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('button#other-ways-to-sign-in').text()).toEqual('Show me other ways to sign in or register');
+ render(reduxWrapper());
+ expect(screen.getByText(
+ 'Show me other ways to sign in or register',
+ ).textContent).toBeDefined();
});
it('should render other ways to sign in button when public account creation disabled', () => {
@@ -664,35 +739,48 @@ describe('LoginPage', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: `?tpa_hint=${ssoProvider.id}` };
- const loginPage = mount(reduxWrapper());
- expect(loginPage.find('button#other-ways-to-sign-in').text()).toEqual('Show me other ways to sign in');
+ render(reduxWrapper());
+ expect(screen.getByText(
+ 'Show me other ways to sign in',
+ ).textContent).toBeDefined();
});
// ******** miscellaneous tests ********
it('should send page event when login page is rendered', () => {
- mount(reduxWrapper());
+ render(reduxWrapper());
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'login');
});
- it('tests that form is only scrollable on form submission', () => {
- const loginPage = mount(reduxWrapper());
+ it('tests that form is in invalid state when it is submission', () => {
+ store = mockStore({
+ ...initialState,
+ login: {
+ ...initialState.login,
+ loginError: { errorCode: 'invalid-form' },
+ },
+ });
- loginPage.find('input#password').simulate('change', { target: { value: 'test', name: 'password' } });
- loginPage.find('button.btn-brand').simulate('click');
+ render(reduxWrapper());
- expect(loginPage.find()).toBeTruthy();
- expect(loginPage.find('LoginPage').state('isSubmitted')).toEqual(true);
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#password' },
+ ), { target: { value: 'password', name: 'password' } });
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
+
+ expect(screen.getByText('Please fill in the fields below.')).toBeTruthy();
});
it('should reset login form errors', () => {
- const errorState = { emailOrUsername: '', password: '' };
store.dispatch = jest.fn(store.dispatch);
- const loginPage = (mount(reduxWrapper())).find('LoginPage');
+ render(reduxWrapper());
expect(store.dispatch).toHaveBeenCalledWith(loginRequestReset());
- expect(loginPage.state('errors')).toEqual(errorState);
});
// persists form data tests
@@ -705,11 +793,20 @@ describe('LoginPage', () => {
},
};
store.dispatch = jest.fn(store.dispatch);
- const loginPage = mount(reduxWrapper());
-
- loginPage.find('input#emailOrUsername').simulate('change', { target: { value: '' } });
- loginPage.find('input#password').simulate('change', { target: { value: '' } });
- loginPage.find('button.btn-brand').simulate('click');
+ render(reduxWrapper());
+
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#emailOrUsername' },
+ ), { target: { value: '' } });
+ fireEvent.change(screen.getByText(
+ '',
+ { selector: '#password' },
+ ), { target: { value: '' } });
+ fireEvent.click(screen.getByText(
+ '',
+ { selector: '.btn-brand' },
+ ));
expect(store.dispatch).toHaveBeenCalledWith(setLoginFormData(formData));
});
@@ -717,17 +814,22 @@ describe('LoginPage', () => {
it('should set form data in redux store on onBlur', () => {
store.dispatch = jest.fn(store.dispatch);
- const loginPage = mount(reduxWrapper());
- loginPage.find('input#emailOrUsername').simulate('blur');
-
+ render(reduxWrapper());
+ fireEvent.blur(screen.getByText(
+ '',
+ { selector: '#emailOrUsername' },
+ ));
expect(store.dispatch).toHaveBeenCalledWith(setLoginFormData({ emailOrUsername: '' }));
});
it('should clear form field errors in redux store on onFocus', () => {
store.dispatch = jest.fn(store.dispatch);
- const loginPage = mount(reduxWrapper());
- loginPage.find('input#emailOrUsername').simulate('focus');
+ render(reduxWrapper());
+ fireEvent.focus(screen.getByText(
+ '',
+ { selector: '#emailOrUsername' },
+ ));
expect(store.dispatch).toHaveBeenCalledWith(setLoginFormData({
errors: {
@@ -736,19 +838,28 @@ describe('LoginPage', () => {
}));
});
- it('should update form fields state if updated in redux store', () => {
- const nextProps = {
- loginFormData: {
- emailOrUsername: 'john_doe',
- password: 'password1',
+ it('should update form fields state if updated in redux store', async () => {
+ const { rerender } = render(reduxWrapper());
+
+ store = mockStore({
+ ...initialState,
+ login: {
+ ...initialState.login,
+ loginFormData: {
+ emailOrUsername: 'john_doe',
+ password: 'password1',
+ },
},
- };
+ });
- const loginPage = mount(reduxWrapper());
- loginPage.find('LoginPage').instance().shouldComponentUpdate(nextProps);
+ rerender((
+
+
+
+
+ ));
- expect(loginPage.find('LoginPage').state('emailOrUsername')).toEqual('john_doe');
- expect(loginPage.find('LoginPage').state('password')).toEqual('password1');
+ expect(screen.getByDisplayValue('password1')).toBeDefined();
});
it('should update reset password value when unmount called', () => {
@@ -761,8 +872,8 @@ describe('LoginPage', () => {
});
store.dispatch = jest.fn(store.dispatch);
- const loginPage = mount(reduxWrapper());
- loginPage.unmount();
+ const { unmount } = render(reduxWrapper());
+ unmount();
expect(store.dispatch).toHaveBeenCalledWith(loginRemovePasswordResetBanner());
});