diff --git a/cypress/e2e/login.cy.ts b/cypress/e2e/login.cy.ts index ecf44fe3..c884d136 100644 --- a/cypress/e2e/login.cy.ts +++ b/cypress/e2e/login.cy.ts @@ -401,6 +401,37 @@ describe('Login', () => { cy.get('#demo_plugin').contains('Demo Plugin').should('be.visible'); }); + it('can remove toasts with esc keydown when a plugin error occurs', () => { + cy.intercept('/settings.json', { + plugins: [ + { + name: 'demo_plugin', + src: '/plugins/main.js', + enable: true, + location: 'main', + }, + ], + 'ui-strings': 'res/default.json', + 'auth-provider': 'icat', + authUrl: 'http://localhost:8000', + autoLogin: true, + 'help-tour-steps': [], + }); + verifyResponse = verifySuccess; + loginResponse = loginSuccess; + cy.visit('/plugin1'); + + cy.contains( + 'Failed to load plugin demo_plugin from /plugins/main.js.' + ).should('exist'); + + cy.get('body').type('{esc}'); + + cy.contains( + 'Failed to load plugin demo_plugin from /plugins/main.js.' + ).should('not.exist'); + }); + it('should be able to switch authenticators and still be "auto logged in"', () => { verifyResponse = verifySuccess; loginResponse = loginSuccess; diff --git a/src/pageContainer.component.tsx b/src/pageContainer.component.tsx index b9006ebb..a562ee96 100644 --- a/src/pageContainer.component.tsx +++ b/src/pageContainer.component.tsx @@ -8,6 +8,7 @@ import Tour from './tour/tour.component'; import CookieConsent from './cookieConsent/cookieConsent.component'; import Footer from './footer/footer.component'; import { useMediaQuery } from '@mui/material'; +import { toastr } from 'react-redux-toastr'; const RootDiv = styled('div')(({ theme }) => ({ position: 'relative', @@ -19,6 +20,26 @@ const PageContainer = (): React.ReactElement => { const theme = useTheme(); const isViewportMdOrLarger = useMediaQuery(theme.breakpoints.up('md')); + React.useEffect(() => { + const clearToasts = (): void => { + toastr.clean(); + }; + + const handleKeyPress = (event: KeyboardEvent): void => { + if (event instanceof KeyboardEvent && event.key === 'Escape') { + clearToasts(); + } + }; + + // Add event listeners for keydown events + document.addEventListener('keydown', handleKeyPress); + + // Clean up the event listeners when component unmounts + return () => { + document.removeEventListener('keydown', handleKeyPress); + }; + }, []); + return ( diff --git a/src/pageContainer.test.tsx b/src/pageContainer.test.tsx index fec64ff2..f31320ac 100644 --- a/src/pageContainer.test.tsx +++ b/src/pageContainer.test.tsx @@ -9,10 +9,12 @@ import { MemoryRouter } from 'react-router-dom'; import PageContainer from './pageContainer.component'; import { StateType } from './state/state.types'; import { authState, initialState } from './state/reducers/scigateway.reducer'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { Provider } from 'react-redux'; import { ThemeProvider } from '@mui/material'; import { buildTheme } from './theming'; +import { toastr } from 'react-redux-toastr'; +import userEvent from '@testing-library/user-event'; jest.mock('@mui/material', () => ({ __esmodule: true, @@ -43,4 +45,22 @@ describe('PageContainer - Tests', () => { expect(asFragment()).toMatchSnapshot(); }); + + it('calls toastr.clean() when escape is clicked', async () => { + const cleanSpy = jest.spyOn(toastr, 'clean'); + render( + + + + + + + + ); + + const element = screen.getByLabelText('home-page'); + await userEvent.type(element, '{Escape}'); + expect(cleanSpy).toHaveBeenCalled(); + cleanSpy.mockRestore(); + }); });