@@ -166,11 +166,22 @@ function setupGlobalFocusEvents(element?: HTMLElement | null) {
166166 // However, we need to detect other cases when a focus event occurs without
167167 // a preceding user event (e.g. screen reader focus). Overriding the focus
168168 // method on HTMLElement.prototype is a bit hacky, but works.
169+ // defineProperty (not assignment) so this works even if `focus` is currently
170+ // a getter-only accessor — e.g. when @testing-library/user-event's setup()
171+ // has instrumented it. Plain assignment throws in that case.
169172 let focus = windowObject . HTMLElement . prototype . focus ;
170- windowObject . HTMLElement . prototype . focus = function ( ) {
171- hasEventBeforeFocus = true ;
172- focus . apply ( this , arguments as unknown as [ options ?: FocusOptions | undefined ] ) ;
173- } ;
173+ try {
174+ Object . defineProperty ( windowObject . HTMLElement . prototype , 'focus' , {
175+ configurable : true ,
176+ writable : true ,
177+ value : function ( ) {
178+ hasEventBeforeFocus = true ;
179+ focus . apply ( this , arguments as unknown as [ options ?: FocusOptions | undefined ] ) ;
180+ }
181+ } ) ;
182+ } catch {
183+ // Non-configurable accessor: can't wrap. Other listeners still cover most cases.
184+ }
174185
175186 documentObject . addEventListener ( 'keydown' , handleKeyboardEvent , true ) ;
176187 documentObject . addEventListener ( 'keyup' , handleKeyboardEvent , true ) ;
@@ -212,7 +223,15 @@ const tearDownWindowFocusTracking = (element, loadListener?: () => void) => {
212223 if ( ! hasSetupGlobalListeners . has ( windowObject ) ) {
213224 return ;
214225 }
215- windowObject . HTMLElement . prototype . focus = hasSetupGlobalListeners . get ( windowObject ) ! . focus ;
226+ try {
227+ Object . defineProperty ( windowObject . HTMLElement . prototype , 'focus' , {
228+ configurable : true ,
229+ writable : true ,
230+ value : hasSetupGlobalListeners . get ( windowObject ) ! . focus
231+ } ) ;
232+ } catch {
233+ // See setupGlobalFocusEvents.
234+ }
216235
217236 documentObject . removeEventListener ( 'keydown' , handleKeyboardEvent , true ) ;
218237 documentObject . removeEventListener ( 'keyup' , handleKeyboardEvent , true ) ;
0 commit comments