Skip to content

Commit 8de88f4

Browse files
authored
fix: create MouseEvents per createEvent (#781)
1 parent e715c81 commit 8de88f4

18 files changed

+483
-513
lines changed

src/utils/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,5 @@ export * from './misc/wait'
3232
export * from './misc/hasPointerEvents'
3333
export * from './misc/hasFormSubmit'
3434

35-
export * from './pointer/fakeEvent'
3635
export * from './pointer/firePointerEvents'
3736
export * from './pointer/mouseButtons'

src/utils/pointer/dom-events.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
declare module '@testing-library/dom/dist/event-map' {
2+
export const eventMap: Record<string, unknown>
3+
}

src/utils/pointer/fakeEvent.ts

-100
This file was deleted.

src/utils/pointer/firePointerEvents.ts

+77-16
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import {fireEvent} from '@testing-library/dom'
1+
import {createEvent, fireEvent} from '@testing-library/dom'
2+
import {eventMap} from '@testing-library/dom/dist/event-map'
23
import type {pointerState} from '../../pointer/types'
34
import type {keyboardState} from '../../keyboard/types'
4-
import {
5-
FakeMouseEvent,
6-
FakePointerEvent,
7-
FakePointerEventInit,
8-
PointerCoords,
9-
} from './fakeEvent'
105
import {getMouseButton, getMouseButtons, MouseButton} from './mouseButtons'
116

127
export function firePointerEvent(
@@ -32,19 +27,14 @@ export function firePointerEvent(
3227
clickCount?: number
3328
},
3429
) {
35-
const Event =
36-
type === 'click' || type.startsWith('mouse')
37-
? FakeMouseEvent
38-
: FakePointerEvent
39-
40-
const init: FakePointerEventInit = {
30+
const init: MouseEventInit & PointerEventInit = {
4131
...coords,
4232
altKey: keyboardState.modifiers.alt,
4333
ctrlKey: keyboardState.modifiers.ctrl,
4434
metaKey: keyboardState.modifiers.meta,
4535
shiftKey: keyboardState.modifiers.shift,
4636
}
47-
if (Event === FakePointerEvent || type === 'click') {
37+
if (type === 'click' || type.startsWith('pointer')) {
4838
init.pointerId = pointerId
4939
init.pointerType = pointerType
5040
}
@@ -61,9 +51,80 @@ export function firePointerEvent(
6151
.map(p => p.keyDef.button ?? 0),
6252
)
6353
}
64-
if (['mousedown', 'mouseup', 'click'].includes(type)) {
54+
if (['mousedown', 'mouseup', 'click', 'dblclick'].includes(type)) {
6555
init.detail = clickCount
6656
}
6757

68-
return fireEvent(target, new Event(type, init))
58+
const eventKey = Object.keys(eventMap).find(k => k.toLowerCase() === type)
59+
const event = createEvent[eventKey as keyof typeof createEvent](target, init)
60+
61+
// see https://github.com/testing-library/react-testing-library/issues/268
62+
assignPositionInit(event as MouseEvent, init)
63+
assignPointerInit(event as PointerEvent, init)
64+
65+
return fireEvent(target, event)
66+
}
67+
68+
export interface PointerCoords {
69+
x?: number
70+
y?: number
71+
clientX?: number
72+
clientY?: number
73+
offsetX?: number
74+
offsetY?: number
75+
pageX?: number
76+
pageY?: number
77+
screenX?: number
78+
screenY?: number
79+
}
80+
81+
function assignProps(
82+
obj: MouseEvent | PointerEvent,
83+
props: MouseEventInit & PointerEventInit & PointerCoords,
84+
) {
85+
for (const [key, value] of Object.entries(props)) {
86+
Object.defineProperty(obj, key, {get: () => value})
87+
}
88+
}
89+
90+
function assignPositionInit(
91+
obj: MouseEvent | PointerEvent,
92+
{
93+
x,
94+
y,
95+
clientX,
96+
clientY,
97+
offsetX,
98+
offsetY,
99+
pageX,
100+
pageY,
101+
screenX,
102+
screenY,
103+
}: PointerCoords,
104+
) {
105+
assignProps(obj, {
106+
/* istanbul ignore start */
107+
x: x ?? clientX ?? 0,
108+
y: y ?? clientY ?? 0,
109+
clientX: x ?? clientX ?? 0,
110+
clientY: y ?? clientY ?? 0,
111+
offsetX: offsetX ?? 0,
112+
offsetY: offsetY ?? 0,
113+
pageX: pageX ?? 0,
114+
pageY: pageY ?? 0,
115+
screenX: screenX ?? 0,
116+
screenY: screenY ?? 0,
117+
/* istanbul ignore end */
118+
})
119+
}
120+
121+
function assignPointerInit(
122+
obj: MouseEvent | PointerEvent,
123+
{isPrimary, pointerId, pointerType}: PointerEventInit,
124+
) {
125+
assignProps(obj, {
126+
isPrimary,
127+
pointerId,
128+
pointerType,
129+
})
69130
}

tests/_helpers/utils.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable testing-library/no-node-access */
22
import {eventMap} from '@testing-library/dom/dist/event-map'
3-
import {isElementType} from '#src/utils'
3+
import {isElementType, MouseButton} from '#src/utils'
44
// this is pretty helpful:
55
// https://codesandbox.io/s/quizzical-worker-eo909
66

@@ -134,15 +134,22 @@ const eventLabelGetters = {
134134
.trim()
135135
},
136136
MouseEvent(event: MouseEvent) {
137-
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
138-
const mouseButtonMap: Record<number, string> = {
139-
0: 'Left',
140-
1: 'Middle',
141-
2: 'Right',
142-
3: 'Browser Back',
143-
4: 'Browser Forward',
137+
if (
138+
[
139+
'click',
140+
'dblclick',
141+
'mousedown',
142+
'mouseup',
143+
'pointerdown',
144+
'pointerup',
145+
].includes(event.type)
146+
) {
147+
const buttonName = Object.keys(MouseButton).find(
148+
k => MouseButton[k as keyof typeof MouseButton] === event.button,
149+
)
150+
// const buttonName = Object.keys(MouseButton).find(k => MouseButton[k as keyof typeof MouseButton] === event.button)
151+
return buttonName ?? `button${event.button}`
144152
}
145-
return `${mouseButtonMap[event.button]} (${event.button})`
146153
},
147154
} as const
148155

tests/clear.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ test('clears text', () => {
1515
input[value="hello"] - pointermove
1616
input[value="hello"] - mousemove
1717
input[value="hello"] - pointerdown
18-
input[value="hello"] - mousedown
18+
input[value="hello"] - mousedown: primary
1919
input[value="hello"] - focus
2020
input[value="hello"] - focusin
2121
input[value="hello"] - select
2222
input[value="hello"] - pointerup
23-
input[value="hello"] - mouseup
24-
input[value="hello"] - click
23+
input[value="hello"] - mouseup: primary
24+
input[value="hello"] - click: primary
2525
input[value="hello"] - select
2626
input[value="hello"] - select
2727
input[value="hello"] - keydown: Delete (46)
@@ -59,13 +59,13 @@ test('does not clear text on readonly inputs', () => {
5959
input[value="hello"] - pointermove
6060
input[value="hello"] - mousemove
6161
input[value="hello"] - pointerdown
62-
input[value="hello"] - mousedown
62+
input[value="hello"] - mousedown: primary
6363
input[value="hello"] - focus
6464
input[value="hello"] - focusin
6565
input[value="hello"] - select
6666
input[value="hello"] - pointerup
67-
input[value="hello"] - mouseup
68-
input[value="hello"] - click
67+
input[value="hello"] - mouseup: primary
68+
input[value="hello"] - click: primary
6969
input[value="hello"] - select
7070
input[value="hello"] - select
7171
input[value="hello"] - keydown: Delete (46)

0 commit comments

Comments
 (0)