From e1cee9792a95667e9a921f03595b937b997f4b2a Mon Sep 17 00:00:00 2001 From: GitHub Date: Thu, 13 Feb 2025 11:10:17 +1100 Subject: [PATCH] Add iframe support and fix nested act --- src/document/prepareDocument.ts | 3 ++- src/utils/focus/getActiveElement.ts | 5 +++++ tests/keyboard/index.ts | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/document/prepareDocument.ts b/src/document/prepareDocument.ts index c529e9f9..bdd0d330 100644 --- a/src/document/prepareDocument.ts +++ b/src/document/prepareDocument.ts @@ -47,7 +47,8 @@ export function prepareDocument(document: Document) { const initialValue = getInitialValue(el) if (initialValue !== undefined) { if (el.value !== initialValue) { - dispatchDOMEvent(el, 'change') + // a call to blur should already be wrapped in an act + el.dispatchEvent(new (document.defaultView ?? window).Event('change')) } clearInitialValue(el) } diff --git a/src/utils/focus/getActiveElement.ts b/src/utils/focus/getActiveElement.ts index b42f0c92..363f817e 100644 --- a/src/utils/focus/getActiveElement.ts +++ b/src/utils/focus/getActiveElement.ts @@ -10,6 +10,11 @@ export function getActiveElement( if (activeElementInShadowTree) { return activeElementInShadowTree } + } else if (activeElement?.tagName === 'IFRAME') { + let contentWindow = (activeElement as HTMLIFrameElement).contentWindow + if (contentWindow) { + return getActiveElement(contentWindow.document) + } } // Browser does not yield disabled elements as document.activeElement - jsdom does if (isDisabled(activeElement)) { diff --git a/tests/keyboard/index.ts b/tests/keyboard/index.ts index 898f4b6f..76451277 100644 --- a/tests/keyboard/index.ts +++ b/tests/keyboard/index.ts @@ -190,3 +190,26 @@ customElements.define( } }, ) + +test('typing on focused element with iframe', async () => { + let iframe: HTMLIFrameElement + let iframeButton: HTMLElement + const {user} = setup( + '
', + ) + iframe = document.createElement('iframe') + window.document.body.appendChild(iframe) + iframeButton = iframe.contentWindow!.document.createElement('button') + iframe.contentWindow!.document.body.appendChild(iframeButton) + let keydown = jest.fn() + let keyup = jest.fn() + iframeButton.addEventListener('keydown', keydown) + iframeButton.addEventListener('keyup', keyup) + + iframeButton.focus() + await user.keyboard('[Space]') + expect(keydown).toHaveBeenCalled() + expect(keyup).toHaveBeenCalled() + + iframe.remove() +})