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