diff --git a/src/common-components/tests/EmbeddedRegistrationRoute.test.jsx b/src/common-components/tests/EmbeddedRegistrationRoute.test.jsx index 38ccff6a..8f317c29 100644 --- a/src/common-components/tests/EmbeddedRegistrationRoute.test.jsx +++ b/src/common-components/tests/EmbeddedRegistrationRoute.test.jsx @@ -3,7 +3,7 @@ import React from 'react'; import { getConfig } from '@edx/frontend-platform'; -import { mount } from 'enzyme'; +import { render } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; import { REGISTER_EMBEDDED_PAGE } from '../../data/constants'; @@ -47,10 +47,13 @@ describe('EmbeddedRegistrationRoute', () => { let embeddedRegistrationPage = null; await act(async () => { - embeddedRegistrationPage = await mount(routerWrapper()); + const { container } = await render(routerWrapper()); + embeddedRegistrationPage = container; }); - expect(embeddedRegistrationPage.find('span').exists()).toBeFalsy(); + const spanElement = embeddedRegistrationPage.querySelector('span'); + + expect(spanElement).toBeNull(); }); it('should render embedded register page if host query param is available in the url (embedded)', async () => { @@ -63,10 +66,13 @@ describe('EmbeddedRegistrationRoute', () => { let embeddedRegistrationPage = null; await act(async () => { - embeddedRegistrationPage = await mount(routerWrapper()); + const { container } = await render(routerWrapper()); + embeddedRegistrationPage = container; }); - expect(embeddedRegistrationPage.find('span').exists()).toBeTruthy(); - expect(embeddedRegistrationPage.find('span').text()).toBe('Embedded Register Page'); + const spanElement = embeddedRegistrationPage.querySelector('span'); + + expect(spanElement).toBeTruthy(); + expect(spanElement.textContent).toBe('Embedded Register Page'); }); }); diff --git a/src/common-components/tests/FormField.test.jsx b/src/common-components/tests/FormField.test.jsx index 6f230e14..56c2d9d2 100644 --- a/src/common-components/tests/FormField.test.jsx +++ b/src/common-components/tests/FormField.test.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { Provider } from 'react-redux'; import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n'; -import { mount } from 'enzyme'; +import { fireEvent, render } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; import { MemoryRouter } from 'react-router-dom'; import configureStore from 'redux-mock-store'; @@ -21,11 +21,17 @@ describe('FormGroup', () => { }; it('should show help text on field focus', () => { - const formGroup = mount(); - expect(formGroup.find('.pgn-transition-replace-group').find('div#email-1').exists()).toBeFalsy(); + const { queryByText, getByLabelText } = render(); + const emailInput = getByLabelText('Email'); - formGroup.find('input#email').simulate('focus'); - expect(formGroup.find('.pgn-transition-replace-group').find('div#email-1').text()).toEqual('Email field help text'); + expect(queryByText('Email field help text')).toBeNull(); + + fireEvent.focus(emailInput); + + const helpText = queryByText('Email field help text'); + + expect(helpText).toBeTruthy(); + expect(helpText.textContent).toEqual('Email field help text'); }); }); @@ -60,25 +66,29 @@ describe('PasswordField', () => { }); it('should show/hide password on icon click', () => { - const passwordField = mount(reduxWrapper()); + const { getByLabelText } = render(reduxWrapper()); + const passwordInput = getByLabelText('Password'); - passwordField.find('button[aria-label="Show password"]').simulate('click'); - expect(passwordField.find('input').prop('type')).toEqual('text'); + const showPasswordButton = getByLabelText('Show password'); + fireEvent.click(showPasswordButton); + expect(passwordInput.type).toBe('text'); - passwordField.find('button[aria-label="Hide password"]').simulate('click'); - expect(passwordField.find('input').prop('type')).toEqual('password'); + const hidePasswordButton = getByLabelText('Hide password'); + fireEvent.click(hidePasswordButton); + expect(passwordInput.type).toBe('password'); }); it('should show password requirement tooltip on focus', async () => { - const passwordField = mount(reduxWrapper()); + const { getByLabelText } = render(reduxWrapper()); + const passwordInput = getByLabelText('Password'); jest.useFakeTimers(); await act(async () => { - passwordField.find('input').simulate('focus'); + fireEvent.focus(passwordInput); jest.runAllTimers(); }); - passwordField.update(); + const passwordRequirementTooltip = document.querySelector('#password-requirement-left'); - expect(passwordField.find('#password-requirement-left').exists()).toBeTruthy(); + expect(passwordRequirementTooltip).toBeTruthy(); }); it('should show all password requirement checks as failed', async () => { @@ -86,48 +96,66 @@ describe('PasswordField', () => { ...props, value: '', }; - + const { getByLabelText } = render(reduxWrapper()); + const passwordInput = getByLabelText('Password'); jest.useFakeTimers(); - const passwordField = mount(reduxWrapper()); await act(async () => { - passwordField.find('input').simulate('focus'); + fireEvent.focus(passwordInput); jest.runAllTimers(); }); - passwordField.update(); - expect(passwordField.find('#letter-check span').prop('className')).toEqual('pgn__icon mr-1 text-light-700'); - expect(passwordField.find('#number-check span').prop('className')).toEqual('pgn__icon mr-1 text-light-700'); - expect(passwordField.find('#characters-check span').prop('className')).toEqual('pgn__icon mr-1 text-light-700'); + const letterCheckIcon = document.querySelector('#letter-check span'); + const numberCheckIcon = document.querySelector('#number-check span'); + const charactersCheckIcon = document.querySelector('#characters-check span'); + + expect(letterCheckIcon).toBeTruthy(); + expect(letterCheckIcon.className).toContain('pgn__icon mr-1 text-light-700'); + + expect(numberCheckIcon).toBeTruthy(); + expect(numberCheckIcon.className).toContain('pgn__icon mr-1 text-light-700'); + + expect(charactersCheckIcon).toBeTruthy(); + expect(charactersCheckIcon.className).toContain('pgn__icon mr-1 text-light-700'); }); it('should update password requirement checks', async () => { - const passwordField = mount(reduxWrapper()); + const { getByLabelText } = render(reduxWrapper()); + const passwordInput = getByLabelText('Password'); jest.useFakeTimers(); await act(async () => { - passwordField.find('input').simulate('focus'); + fireEvent.focus(passwordInput); jest.runAllTimers(); }); - passwordField.update(); - expect(passwordField.find('#letter-check span').prop('className')).toEqual('pgn__icon text-success mr-1'); - expect(passwordField.find('#number-check span').prop('className')).toEqual('pgn__icon text-success mr-1'); - expect(passwordField.find('#characters-check span').prop('className')).toEqual('pgn__icon text-success mr-1'); + const letterCheckIcon = document.querySelector('#letter-check span'); + const numberCheckIcon = document.querySelector('#number-check span'); + const charactersCheckIcon = document.querySelector('#characters-check span'); + + expect(letterCheckIcon).toBeTruthy(); + expect(letterCheckIcon.className).toContain('pgn__icon text-success mr-1'); + + expect(numberCheckIcon).toBeTruthy(); + expect(numberCheckIcon.className).toContain('pgn__icon text-success mr-1'); + + expect(charactersCheckIcon).toBeTruthy(); + expect(charactersCheckIcon.className).toContain('pgn__icon text-success mr-1'); }); it('should not run validations when blur is fired on password icon click', () => { - const passwordField = mount(reduxWrapper()); + const { container, getByLabelText } = render(reduxWrapper()); + const passwordInput = container.querySelector('input[name="password"]'); - passwordField.find('button[aria-label="Show password"]').simulate('blur', { + const passwordIcon = getByLabelText('Show password'); + + fireEvent.blur(passwordInput, { target: { name: 'password', value: 'invalid', }, - relatedTarget: { - name: 'passwordIcon', - }, + relatedTarget: passwordIcon, }); - expect(passwordField.find('div[feedback-for="password"]').exists()).toBeFalsy(); + expect(container.querySelector('div[feedback-for="password"]')).toBeNull(); }); it('should call props handle blur if available', () => { @@ -135,9 +163,10 @@ describe('PasswordField', () => { ...props, handleBlur: jest.fn(), }; - const passwordField = mount(reduxWrapper()); + const { container } = render(reduxWrapper()); + const passwordInput = container.querySelector('input[name="password"]'); - passwordField.find('input#password').simulate('blur', { + fireEvent.blur(passwordInput, { target: { name: 'password', value: '', @@ -152,9 +181,10 @@ describe('PasswordField', () => { ...props, handleErrorChange: jest.fn(), }; - const passwordField = mount(reduxWrapper()); + const { container } = render(reduxWrapper()); + const passwordInput = container.querySelector('input[name="password"]'); - passwordField.find('input#password').simulate('blur', { + fireEvent.blur(passwordInput, { target: { name: 'password', value: '', @@ -174,9 +204,11 @@ describe('PasswordField', () => { handleErrorChange: jest.fn(), }; - const passwordField = mount(reduxWrapper()); + const { getByLabelText } = render(reduxWrapper()); - passwordField.find('button[aria-label="Show password"]').simulate('focus', { + const passwordIcon = getByLabelText('Show password'); + + fireEvent.focus(passwordIcon, { target: { name: 'passwordIcon', value: '', @@ -192,9 +224,11 @@ describe('PasswordField', () => { handleErrorChange: jest.fn(), }; - const passwordField = mount(reduxWrapper()); + const { getByLabelText } = render(reduxWrapper()); - passwordField.find('button[aria-label="Show password"]').simulate('focus', { + const passwordIcon = getByLabelText('Show password'); + + fireEvent.focus(passwordIcon, { target: { name: 'password', value: 'invalid', @@ -214,9 +248,9 @@ describe('PasswordField', () => { ...props, handleErrorChange: jest.fn(), }; - const passwordField = mount(reduxWrapper()); - - passwordField.find('button[aria-label="Show password"]').simulate('blur', { + const { getByLabelText } = render(reduxWrapper()); + const passwordField = getByLabelText('Password'); + fireEvent.blur(passwordField, { target: { name: 'password', value: 'password123', @@ -234,9 +268,11 @@ describe('PasswordField', () => { handleErrorChange: jest.fn(), handleBlur: jest.fn(), }; - const passwordField = mount(reduxWrapper()); + const { getByLabelText } = render(reduxWrapper()); - passwordField.find('button[aria-label="Show password"]').simulate('blur', { + const passwordIcon = getByLabelText('Show password'); + + fireEvent.blur(passwordIcon, { target: { name: 'passwordIcon', value: undefined, diff --git a/src/common-components/tests/UnAuthOnlyRoute.test.jsx b/src/common-components/tests/UnAuthOnlyRoute.test.jsx index 9625386e..c791ecf8 100644 --- a/src/common-components/tests/UnAuthOnlyRoute.test.jsx +++ b/src/common-components/tests/UnAuthOnlyRoute.test.jsx @@ -3,7 +3,7 @@ import React from 'react'; import { fetchAuthenticatedUser, getAuthenticatedUser } from '@edx/frontend-platform/auth'; -import { mount } from 'enzyme'; +import { render } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; import { UnAuthOnlyRoute } from '..'; @@ -55,7 +55,7 @@ describe('UnAuthOnlyRoute', () => { fetchAuthenticatedUser.mockReturnValueOnce(Promise.resolve(user)); await act(async () => { - await mount(routerWrapper()); + await render(routerWrapper()); }); expect(fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: true }); @@ -66,7 +66,7 @@ describe('UnAuthOnlyRoute', () => { fetchAuthenticatedUser.mockReturnValueOnce(Promise.resolve(null)); await act(async () => { - await mount(routerWrapper()); + await render(routerWrapper()); }); expect(fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: false });