55 * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66 */
77import React from 'react'
8- import { screen } from '@testing-library/react'
9- // import userEvent from '@testing-library/user-event'
10-
11- import OfflineBoundary from '../../components/offline-boundary/index '
8+ import { screen , act } from '@testing-library/react'
9+ import userEvent from '@testing-library/user-event'
10+ import { ChakraProvider } from '@chakra-ui/react'
11+ import theme from '../../theme '
1212import { renderWithRouter } from '../../utils/test-utils'
1313
14- // class ChunkLoadError extends Error {
15- // constructor(...params) {
16- // // Pass remaining arguments (including vendor specific ones) to parent constructor
17- // super(...params)
18- // this.name = 'ChunkLoadError'
19- // }
20- // }
14+ import OfflineBoundary , { UnwrappedOfflineBoundary } from '../../components/offline-boundary/index'
15+
16+ // Custom render function that combines Router and Chakra contexts
17+ const renderWithRouterAndChakra = ( component ) => {
18+ const ComponentWithChakra = ( ) => < ChakraProvider value = { theme } > { component } </ ChakraProvider >
19+ return renderWithRouter ( < ComponentWithChakra /> )
20+ }
21+
22+ class ChunkLoadError extends Error {
23+ constructor ( ...params ) {
24+ // Pass remaining arguments (including vendor specific ones) to parent constructor
25+ super ( ...params )
26+ this . name = 'ChunkLoadError'
27+ }
28+ }
2129
2230describe ( 'The OfflineBoundary' , ( ) => {
2331 beforeEach ( ( ) => {
@@ -31,7 +39,7 @@ describe('The OfflineBoundary', () => {
3139 } )
3240
3341 test ( 'should render its children' , ( ) => {
34- renderWithRouter (
42+ renderWithRouterAndChakra (
3543 < OfflineBoundary isOnline = { true } >
3644 < div id = "child" > child</ div >
3745 </ OfflineBoundary >
@@ -40,84 +48,74 @@ describe('The OfflineBoundary', () => {
4048 expect ( screen . getByText ( / c h i l d / i) ) . toBeInTheDocument ( )
4149 } )
4250
43- // TODO: Fix flaky/broken test
44- // eslint-disable-next-line jest/no-commented-out-tests
45- // test('should render the error splash when a child throws a chunk load error', () => {
46- // const ThrowingComponent = () => {
47- // throw new ChunkLoadError()
48- // }
49- // renderWithRouter(
50- // <OfflineBoundary isOnline={true}>
51- // <div>
52- // <ThrowingComponent />
53- // <div id="child">child</div>
54- // </div>
55- // </OfflineBoundary>
56- // )
57-
58- // expect(screen.getByRole('img', {name: /offline cloud/i})).toBeInTheDocument()
59- // expect(
60- // screen.getByRole('heading', {name: /you are currently offline/i})
61- // ).toBeInTheDocument()
62- // expect(screen.queryByText(/child/i)).not.toBeInTheDocument()
63- // })
64-
65- // TODO: Fix flaky/broken test
66- // eslint-disable-next-line jest/no-commented-out-tests
67- // test('should re-throw errors that are not chunk load errors', () => {
68- // const ThrowingComponent = () => {
69- // throw new Error('Anything else')
70- // }
71- // expect(() => {
72- // renderWithRouter(
73- // <OfflineBoundary isOnline={true}>
74- // <div>
75- // <ThrowingComponent />
76- // <div id="child">child</div>
77- // </div>
78- // </OfflineBoundary>
79- // )
80- // }).toThrow()
81- // })
82-
83- // TODO: Fix flaky/broken test
84- // eslint-disable-next-line jest/no-commented-out-tests
85- // test('should attempt to reload the page when the user clicks retry', () => {
86- // let firstRender = true
87- // const ThrowingOnceComponent = () => {
88- // if (firstRender) {
89- // firstRender = false
90- // throw new ChunkLoadError()
91- // } else {
92- // return <div id="child">child</div>
93- // }
94- // }
95- // renderWithRouter(
96- // <OfflineBoundary isOnline={true}>
97- // <ThrowingOnceComponent />
98- // </OfflineBoundary>
99- // )
100-
101- // expect(screen.getByRole('img', {name: /offline cloud/i})).toBeInTheDocument()
102- // expect(
103- // screen.getByRole('heading', {name: /you are currently offline/i})
104- // ).toBeInTheDocument()
105- // expect(screen.queryByText(/child/i)).not.toBeInTheDocument()
106-
107- // userEvent.click(screen.getByRole('button', {name: /retry connection/i}))
108- // expect(screen.getByText(/child/i)).toBeInTheDocument()
109- // expect(screen.queryByRole('img', {name: /offline cloud/i})).not.toBeInTheDocument()
110- // expect(
111- // screen.queryByRole('heading', {name: /you are currently offline/i})
112- // ).not.toBeInTheDocument()
113- // })
114-
115- // TODO: Fix flaky/broken test
116- // eslint-disable-next-line jest/no-commented-out-tests
117- // test('should derive state from a chunk load error', () => {
118- // const derived = UnwrappedOfflineBoundary.getDerivedStateFromError(
119- // new ChunkLoadError('test')
120- // )
121- // expect(derived).toEqual({chunkLoadError: true})
122- // })
51+ test ( 'should render the error splash when a child throws a chunk load error' , ( ) => {
52+ const ThrowingComponent = ( ) => {
53+ throw new ChunkLoadError ( )
54+ }
55+ renderWithRouterAndChakra (
56+ < OfflineBoundary isOnline = { true } >
57+ < div >
58+ < ThrowingComponent />
59+ < div id = "child" > child</ div >
60+ </ div >
61+ </ OfflineBoundary >
62+ )
63+
64+ expect ( screen . getByRole ( 'img' , { hidden : true } ) ) . toBeInTheDocument ( )
65+ expect (
66+ screen . getByRole ( 'heading' , { name : / y o u a r e c u r r e n t l y o f f l i n e / i} )
67+ ) . toBeInTheDocument ( )
68+ expect ( screen . queryByText ( / c h i l d / i) ) . not . toBeInTheDocument ( )
69+ } )
70+
71+ test ( 'should re-throw errors that are not chunk load errors' , ( ) => {
72+ const ThrowingComponent = ( ) => {
73+ throw new Error ( 'Anything else' )
74+ }
75+ expect ( ( ) => {
76+ renderWithRouterAndChakra (
77+ < OfflineBoundary isOnline = { true } >
78+ < div >
79+ < ThrowingComponent />
80+ < div id = "child" > child</ div >
81+ </ div >
82+ </ OfflineBoundary >
83+ )
84+ } ) . toThrow ( )
85+ } )
86+
87+ test ( 'should call clearError when retry button is clicked' , async ( ) => {
88+ const user = userEvent . setup ( )
89+ const ThrowingComponent = ( ) => {
90+ throw new ChunkLoadError ( )
91+ }
92+ const clearErrorSpy = jest . spyOn ( UnwrappedOfflineBoundary . prototype , 'clearError' )
93+
94+ renderWithRouterAndChakra (
95+ < OfflineBoundary isOnline = { true } >
96+ < ThrowingComponent />
97+ </ OfflineBoundary >
98+ )
99+
100+ expect ( screen . getByRole ( 'img' , { hidden : true } ) ) . toBeInTheDocument ( )
101+ expect (
102+ screen . getByRole ( 'heading' , { name : / y o u a r e c u r r e n t l y o f f l i n e / i} )
103+ ) . toBeInTheDocument ( )
104+
105+ const retryButton = screen . getByRole ( 'button' , { name : / r e t r y c o n n e c t i o n / i} )
106+ await act ( async ( ) => {
107+ await user . click ( retryButton )
108+ } )
109+
110+ expect ( clearErrorSpy ) . toHaveBeenCalled ( )
111+
112+ clearErrorSpy . mockRestore ( )
113+ } )
114+
115+ test ( 'should derive state from a chunk load error' , ( ) => {
116+ const derived = UnwrappedOfflineBoundary . getDerivedStateFromError (
117+ new ChunkLoadError ( 'test' )
118+ )
119+ expect ( derived ) . toEqual ( { chunkLoadError : true } )
120+ } )
123121} )
0 commit comments