@@ -16,6 +16,7 @@ import {
1616 Integrations ,
1717 Scope ,
1818 showReportDialog ,
19+ WINDOW ,
1920 wrap ,
2021} from '../../src' ;
2122import { getDefaultBrowserClientOptions } from './helper/browser-client-options' ;
@@ -123,6 +124,65 @@ describe('SentryBrowser', () => {
123124 ) ;
124125 } ) ;
125126 } ) ;
127+
128+ describe ( 'onClose' , ( ) => {
129+ const dummyErrorHandler = jest . fn ( ) ;
130+ beforeEach ( ( ) => {
131+ // this prevents jest-environment-jsdom from failing the test
132+ // when an error in `onClose` is thrown
133+ // it does not prevent errors thrown directly inside the test,
134+ // so we don't have to worry about tests passing that should
135+ // otherwise fail
136+ // see: https://github.com/jestjs/jest/blob/main/packages/jest-environment-jsdom/src/index.ts#L95-L115
137+ WINDOW . addEventListener ( 'error' , dummyErrorHandler ) ;
138+ } ) ;
139+
140+ afterEach ( ( ) => {
141+ WINDOW . removeEventListener ( 'error' , dummyErrorHandler ) ;
142+ } ) ;
143+
144+ const waitForPostMessage = async ( message : string ) => {
145+ WINDOW . postMessage ( message , '*' ) ;
146+ await flush ( 10 ) ;
147+ } ;
148+
149+ it ( 'should call `onClose` when receiving `reportdialog_closed` MessageEvent' , async ( ) => {
150+ const onClose = jest . fn ( ) ;
151+ showReportDialog ( { onClose } ) ;
152+
153+ await waitForPostMessage ( 'reportdialog_closed' ) ;
154+ expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
155+
156+ // ensure the event handler has been removed so onClose is not called again
157+ await waitForPostMessage ( 'reportdialog_closed' ) ;
158+ expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
159+ } ) ;
160+
161+ it ( 'should call `onClose` only once even if it throws' , async ( ) => {
162+ const onClose = jest . fn ( ( ) => {
163+ throw new Error ( ) ;
164+ } ) ;
165+ showReportDialog ( { onClose } ) ;
166+
167+ await waitForPostMessage ( 'reportdialog_closed' ) ;
168+ expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
169+
170+ // ensure the event handler has been removed so onClose is not called again
171+ await waitForPostMessage ( 'reportdialog_closed' ) ;
172+ expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
173+ } ) ;
174+
175+ it ( 'should not call `onClose` for other MessageEvents' , async ( ) => {
176+ const onClose = jest . fn ( ) ;
177+ showReportDialog ( { onClose } ) ;
178+
179+ await waitForPostMessage ( 'some_message' ) ;
180+ expect ( onClose ) . not . toHaveBeenCalled ( ) ;
181+
182+ await waitForPostMessage ( 'reportdialog_closed' ) ;
183+ expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
184+ } ) ;
185+ } ) ;
126186 } ) ;
127187
128188 describe ( 'breadcrumbs' , ( ) => {
0 commit comments