diff --git a/src/_interop/dom-events.d.ts b/src/_interop/dom-events.d.ts deleted file mode 100644 index cb335782..00000000 --- a/src/_interop/dom-events.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -declare module '@testing-library/dom/dist/event-map.js' { - import {EventType} from '@testing-library/dom' - export const eventMap: { - [k in EventType]: { - EventType: EventInterface - defaultInit: EventInit - } - } -} - -type EventInterface = - | 'AnimationEvent' - | 'ClipboardEvent' - | 'CompositionEvent' - | 'DragEvent' - | 'Event' - | 'FocusEvent' - | 'InputEvent' - | 'KeyboardEvent' - | 'MouseEvent' - | 'PointerEvent' - | 'PopStateEvent' - | 'ProgressEvent' - | 'TouchEvent' - | 'TransitionEvent' - | 'UIEvent' diff --git a/src/_interop/dom-helpers.d.ts b/src/_interop/dom-helpers.d.ts deleted file mode 100644 index fd0b3f29..00000000 --- a/src/_interop/dom-helpers.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module '@testing-library/dom/dist/helpers.js' { - export function getWindowFromNode(node: Node): Window -} diff --git a/src/_interop/dtl.ts b/src/_interop/dtl.ts deleted file mode 100644 index 54ea3cee..00000000 --- a/src/_interop/dtl.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as named from '@testing-library/dom' - -export default named diff --git a/src/_interop/dtlEventMap.ts b/src/_interop/dtlEventMap.ts deleted file mode 100644 index 51f078c2..00000000 --- a/src/_interop/dtlEventMap.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as named from '@testing-library/dom/dist/event-map.js' - -export default named diff --git a/src/_interop/dtlHelpers.ts b/src/_interop/dtlHelpers.ts deleted file mode 100644 index fe76479a..00000000 --- a/src/_interop/dtlHelpers.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as named from '@testing-library/dom/dist/helpers.js' - -export default named diff --git a/src/event/createEvent.ts b/src/event/createEvent.ts index 5b163059..dc38aaa6 100644 --- a/src/event/createEvent.ts +++ b/src/event/createEvent.ts @@ -1,13 +1,30 @@ import {getWindow} from '../utils' -import {eventMap, eventMapKeys} from './eventMap' +import {eventMap} from './eventMap' import { type EventType, type EventTypeInit, type FixedDocumentEventMap, } from './types' -const eventInitializer = { +interface InterfaceMap { + ClipboardEvent: {type: ClipboardEvent; init: ClipboardEventInit} + InputEvent: {type: InputEvent; init: InputEventInit} + MouseEvent: {type: MouseEvent; init: MouseEventInit} + PointerEvent: {type: PointerEvent; init: PointerEventInit} + KeyboardEvent: {type: KeyboardEvent; init: KeyboardEventInit} +} +type InterfaceNames = typeof eventMap[keyof typeof eventMap]['EventType'] +type Interface = k extends keyof InterfaceMap + ? InterfaceMap[k] + : never + +const eventInitializer: { + [k in InterfaceNames]: Array< + (e: Interface['type'], i: Interface['init']) => void + > +} = { ClipboardEvent: [initClipboardEvent], + Event: [], InputEvent: [initUIEvent, initInputEvent], MouseEvent: [initUIEvent, initUIEventModififiers, initMouseEvent], PointerEvent: [ @@ -17,7 +34,7 @@ const eventInitializer = { initPointerEvent, ], KeyboardEvent: [initUIEvent, initUIEventModififiers, initKeyboardEvent], -} as Record void>> +} export function createEvent( type: K, @@ -25,10 +42,11 @@ export function createEvent( init?: EventTypeInit, ) { const window = getWindow(target) - const {EventType, defaultInit} = - eventMap[eventMapKeys[type] as keyof typeof eventMap] + const {EventType, defaultInit} = eventMap[type] const event = new (getEventConstructors(window)[EventType])(type, defaultInit) - eventInitializer[EventType]?.forEach(f => f(event, init ?? {})) + eventInitializer[EventType].forEach(f => + f(event as never, (init ?? {}) as never), + ) return event as FixedDocumentEventMap[K] } diff --git a/src/event/eventMap.ts b/src/event/eventMap.ts index 629ce939..a651b8b0 100644 --- a/src/event/eventMap.ts +++ b/src/event/eventMap.ts @@ -1,14 +1,15 @@ -import dtlEvents from '../_interop/dtlEventMap' import {EventType} from './types' export const eventMap = { - ...dtlEvents.eventMap, - - click: { + auxclick: { EventType: 'PointerEvent', defaultInit: {bubbles: true, cancelable: true, composed: true}, }, - auxclick: { + beforeinput: { + EventType: 'InputEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + click: { EventType: 'PointerEvent', defaultInit: {bubbles: true, cancelable: true, composed: true}, }, @@ -16,24 +17,115 @@ export const eventMap = { EventType: 'PointerEvent', defaultInit: {bubbles: true, cancelable: true, composed: true}, }, - beforeInput: { + copy: { + EventType: 'ClipboardEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + change: { + EventType: 'Event', + defaultInit: {bubbles: true, cancelable: false}, + }, + cut: { + EventType: 'ClipboardEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + dblclick: { + EventType: 'MouseEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + keydown: { + EventType: 'KeyboardEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + keypress: { + EventType: 'KeyboardEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + keyup: { + EventType: 'KeyboardEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + paste: { + EventType: 'ClipboardEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + input: { EventType: 'InputEvent', + defaultInit: {bubbles: true, cancelable: false, composed: true}, + }, + mousedown: { + EventType: 'MouseEvent', defaultInit: {bubbles: true, cancelable: true, composed: true}, }, + mouseenter: { + EventType: 'MouseEvent', + defaultInit: {bubbles: false, cancelable: false, composed: true}, + }, + mouseleave: { + EventType: 'MouseEvent', + defaultInit: {bubbles: false, cancelable: false, composed: true}, + }, + mousemove: { + EventType: 'MouseEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + mouseout: { + EventType: 'MouseEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + mouseover: { + EventType: 'MouseEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + mouseup: { + EventType: 'MouseEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + pointerover: { + EventType: 'PointerEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + pointerenter: { + EventType: 'PointerEvent', + defaultInit: {bubbles: false, cancelable: false}, + }, + pointerdown: { + EventType: 'PointerEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + pointermove: { + EventType: 'PointerEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + pointerup: { + EventType: 'PointerEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + pointercancel: { + EventType: 'PointerEvent', + defaultInit: {bubbles: true, cancelable: false, composed: true}, + }, + pointerout: { + EventType: 'PointerEvent', + defaultInit: {bubbles: true, cancelable: true, composed: true}, + }, + pointerleave: { + EventType: 'PointerEvent', + defaultInit: {bubbles: false, cancelable: false}, + }, + submit: { + EventType: 'Event', + defaultInit: {bubbles: true, cancelable: true}, + }, } as const -export const eventMapKeys: { - [k in keyof DocumentEventMap]?: keyof typeof eventMap -} = Object.fromEntries(Object.keys(eventMap).map(k => [k.toLowerCase(), k])) - function getEventClass(type: EventType) { - const k = eventMapKeys[type] - return k && eventMap[k].EventType + return eventMap[type].EventType } const mouseEvents = ['MouseEvent', 'PointerEvent'] export function isMouseEvent(type: EventType) { - return mouseEvents.includes(getEventClass(type) as string) + return mouseEvents.includes(getEventClass(type)) } export function isKeyboardEvent(type: EventType) { diff --git a/src/event/types.ts b/src/event/types.ts index 34bae61f..2f0cdd63 100644 --- a/src/event/types.ts +++ b/src/event/types.ts @@ -1,4 +1,6 @@ -export type EventType = keyof DocumentEventMap +import {eventMap} from './eventMap' + +export type EventType = keyof typeof eventMap export type EventTypeInit = SpecificEventInit< FixedDocumentEventMap[K] diff --git a/src/event/wrapEvent.ts b/src/event/wrapEvent.ts index 33ebf9bc..3f436ccf 100644 --- a/src/event/wrapEvent.ts +++ b/src/event/wrapEvent.ts @@ -1,6 +1,4 @@ -import dtl from '../_interop/dtl' - -const {getConfig} = dtl +import {getConfig} from '@testing-library/dom' export function wrapEvent(cb: () => R, _element: Element) { return getConfig().eventWrapper(cb) as unknown as R diff --git a/src/setup/wrapAsync.ts b/src/setup/wrapAsync.ts index 6f496653..83cda376 100644 --- a/src/setup/wrapAsync.ts +++ b/src/setup/wrapAsync.ts @@ -1,6 +1,4 @@ -import dtl from '../_interop/dtl' - -const {getConfig} = dtl +import {getConfig} from '@testing-library/dom' /** * Wrap an internal Promise diff --git a/src/utility/selectOptions.ts b/src/utility/selectOptions.ts index 730b4616..29d4f3ca 100644 --- a/src/utility/selectOptions.ts +++ b/src/utility/selectOptions.ts @@ -1,10 +1,8 @@ -import dtl from '../_interop/dtl' +import {getConfig} from '@testing-library/dom' import {hasPointerEvents, isDisabled, isElementType, wait} from '../utils' import {type Instance} from '../setup' import {focusElement} from '../event' -const {getConfig} = dtl - export async function selectOptions( this: Instance, select: Element, diff --git a/src/utils/misc/getWindow.ts b/src/utils/misc/getWindow.ts index a723667f..66da8fea 100644 --- a/src/utils/misc/getWindow.ts +++ b/src/utils/misc/getWindow.ts @@ -1,7 +1,22 @@ -import dtlHelpers from '../../_interop/dtlHelpers' +export function getWindow(node: Node) { + if (isDocument(node) && node.defaultView) { + return node.defaultView + } else if (node.ownerDocument?.defaultView) { + return node.ownerDocument.defaultView + } + throw new Error( + `Could not determine window of node. Node was ${describe(node)}`, + ) +} -const {getWindowFromNode} = dtlHelpers +function isDocument(node: Node): node is Document { + return node.nodeType === 9 +} -export function getWindow(node: Node) { - return getWindowFromNode(node) as Window & typeof globalThis +function describe(val: unknown) { + return typeof val === 'function' + ? `function ${val.name}` + : val === null + ? 'null' + : String(val) } diff --git a/tests/_helpers/dom-events.d.ts b/tests/_helpers/dom-events.d.ts deleted file mode 100644 index 18d4fbd1..00000000 --- a/tests/_helpers/dom-events.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module '@testing-library/dom/dist/event-map.js' { - import {EventType} from '@testing-library/dom' - export const eventMap: { - [k in EventType]: { - EventType: string - defaultInit: EventInit - } - } -} diff --git a/tests/_helpers/listeners.ts b/tests/_helpers/listeners.ts index 8b530139..e66e7022 100644 --- a/tests/_helpers/listeners.ts +++ b/tests/_helpers/listeners.ts @@ -1,4 +1,4 @@ -import {eventMapKeys} from '#src/event/eventMap' +import {eventMap} from '#src/event/eventMap' import {isElementType} from '#src/utils' import {MouseButton, MouseButtonFlip} from '#src/system/pointer/buttons' @@ -31,6 +31,15 @@ export function addEventListener( export type EventHandlers = {[k in keyof DocumentEventMap]?: EventListener} +const loggedEvents = [ + ...(Object.keys(eventMap) as Array), + 'focus', + 'focusin', + 'focusout', + 'blur', + 'select', +] as const + /** * Add listeners for logging events. */ @@ -50,9 +59,7 @@ export function addListeners( const generalListener = mocks.fn(eventHandler).mockName('eventListener') - for (const eventType of Object.keys(eventMapKeys) as Array< - keyof typeof eventMapKeys - >) { + for (const eventType of loggedEvents) { addEventListener(element, eventType, (...args) => { generalListener(...args) eventHandlers[eventType]?.(...args) diff --git a/tests/setup/index.ts b/tests/setup/index.ts index 4f51b7f1..3cdb36fa 100644 --- a/tests/setup/index.ts +++ b/tests/setup/index.ts @@ -1,11 +1,9 @@ import {getSpy} from './_mockApis' -import DOMTestingLibrary from '#src/_interop/dtl' +import {getConfig} from '@testing-library/dom' import userEvent from '#src' import {type Instance, type UserEventApi} from '#src/setup/setup' import {render} from '#testHelpers' -const {getConfig} = DOMTestingLibrary - type ApiDeclarations = { [api in keyof UserEventApi]: { args?: unknown[] diff --git a/tests/utils/misc/isVisible.ts b/tests/utils/misc/isVisible.ts index 61ca89e5..aa5e1b44 100644 --- a/tests/utils/misc/isVisible.ts +++ b/tests/utils/misc/isVisible.ts @@ -1,9 +1,7 @@ -import DOMTestingLibrary from '#src/_interop/dtl' +import {screen} from '@testing-library/dom' import {isVisible} from '#src/utils' import {setup} from '#testHelpers' -const {screen} = DOMTestingLibrary - test('check if element is visible', async () => { setup(`