Skip to content

Commit 944a0b7

Browse files
committed
fix mouse.ts and related.
1 parent 85e49a0 commit 944a0b7

File tree

3 files changed

+71
-28
lines changed

3 files changed

+71
-28
lines changed

packages/driver/src/cy/keyboard.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ export type KeyEventType =
114114
| 'textInput'
115115
| 'beforeinput'
116116

117+
export type ModifiersEventOptions = {
118+
altKey: boolean
119+
ctrlKey: boolean
120+
metaKey: boolean
121+
shiftKey: boolean
122+
}
123+
117124
const toModifiersEventOptions = (modifiers: KeyboardModifiers) => {
118125
return {
119126
altKey: modifiers.alt,

packages/driver/src/cy/mouse.ts

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// @ts-nocheck
21
import $ from 'jquery'
32
import _ from 'lodash'
43
import $dom from '../dom'
54
import $elements from '../dom/elements'
6-
import $Keyboard from './keyboard'
5+
import $Keyboard, { ModifiersEventOptions } from './keyboard'
76
import $selection from '../dom/selection'
87
import debugFn from 'debug'
98

@@ -16,7 +15,7 @@ const debug = debugFn('cypress:driver:mouse')
1615
* @property {Document} doc
1716
*/
1817

19-
const getLastHoveredEl = (state) => {
18+
const getLastHoveredEl = (state): HTMLElement | null => {
2019
let lastHoveredEl = state('mouseLastHoveredEl')
2120
const lastHoveredElAttached = lastHoveredEl && $elements.isAttachedEl(lastHoveredEl)
2221

@@ -42,6 +41,12 @@ const getMouseCoords = (state) => {
4241
return state('mouseCoords')
4342
}
4443

44+
type DefaultMouseOptions = ModifiersEventOptions & CoordsEventOptions & {
45+
view: Window
46+
composed: boolean
47+
relatedTarget: HTMLElement | null
48+
}
49+
4550
export const create = (state, keyboard, focused, Cypress) => {
4651
const isFirefox = Cypress.browser.family === 'firefox'
4752

@@ -65,7 +70,7 @@ export const create = (state, keyboard, focused, Cypress) => {
6570

6671
return sendPointerEvent(el, evtOptions, 'pointerup', true, true)
6772
}
68-
const sendPointerdown = (el, evtOptions) => {
73+
const sendPointerdown = (el, evtOptions): {} | SentEvent => {
6974
if (isFirefox && el.disabled) {
7075
return {}
7176
}
@@ -75,7 +80,7 @@ export const create = (state, keyboard, focused, Cypress) => {
7580
const sendPointermove = (el, evtOptions) => {
7681
return sendPointerEvent(el, evtOptions, 'pointermove', true, true)
7782
}
78-
const sendPointerover = (el, evtOptions) => {
83+
const sendPointerover = (el, evtOptions: DefaultMouseOptions) => {
7984
return sendPointerEvent(el, evtOptions, 'pointerover', true, true)
8085
}
8186
const sendPointerenter = (el, evtOptions) => {
@@ -95,7 +100,7 @@ export const create = (state, keyboard, focused, Cypress) => {
95100

96101
return sendMouseEvent(el, evtOptions, 'mouseup', true, true)
97102
}
98-
const sendMousedown = (el, evtOptions) => {
103+
const sendMousedown = (el, evtOptions): {} | SentEvent => {
99104
if (isFirefox && el.disabled) {
100105
return {}
101106
}
@@ -105,7 +110,7 @@ export const create = (state, keyboard, focused, Cypress) => {
105110
const sendMousemove = (el, evtOptions) => {
106111
return sendMouseEvent(el, evtOptions, 'mousemove', true, true)
107112
}
108-
const sendMouseover = (el, evtOptions) => {
113+
const sendMouseover = (el, evtOptions: DefaultMouseOptions) => {
109114
return sendMouseEvent(el, evtOptions, 'mouseover', true, true)
110115
}
111116
const sendMouseenter = (el, evtOptions) => {
@@ -117,7 +122,7 @@ export const create = (state, keyboard, focused, Cypress) => {
117122
const sendMouseout = (el, evtOptions) => {
118123
return sendMouseEvent(el, evtOptions, 'mouseout', true, true)
119124
}
120-
const sendClick = (el, evtOptions, opts = {}) => {
125+
const sendClick = (el, evtOptions, opts: { force?: boolean } = {}) => {
121126
// send the click event if firefox and force (needed for force check checkbox)
122127
if (!opts.force && isFirefox && el.disabled) {
123128
return {}
@@ -154,7 +159,7 @@ export const create = (state, keyboard, focused, Cypress) => {
154159
return !_.isEqual(xy(fromElViewport), xy(coords))
155160
}
156161

157-
const shouldMoveCursorToEndAfterMousedown = (el) => {
162+
const shouldMoveCursorToEndAfterMousedown = (el: HTMLElement) => {
158163
const _debug = debug.extend(':shouldMoveCursorToEnd')
159164

160165
_debug('shouldMoveToEnd?', el)
@@ -182,7 +187,7 @@ export const create = (state, keyboard, focused, Cypress) => {
182187
}
183188

184189
const mouse = {
185-
_getDefaultMouseOptions (x, y, win) {
190+
_getDefaultMouseOptions (x, y, win): DefaultMouseOptions {
186191
const _activeModifiers = keyboard.getActiveModifiers()
187192
const modifiersEventOptions = $Keyboard.toModifiersEventOptions(_activeModifiers)
188193
const coordsEventOptions = toCoordsEventOptions(x, y, win)
@@ -201,7 +206,7 @@ export const create = (state, keyboard, focused, Cypress) => {
201206
* @param {Coords} coords
202207
* @param {HTMLElement} forceEl
203208
*/
204-
move (fromElViewport, forceEl) {
209+
move (fromElViewport, forceEl?) {
205210
debug('mouse.move', fromElViewport)
206211

207212
const lastHoveredEl = getLastHoveredEl(state)
@@ -259,16 +264,21 @@ export const create = (state, keyboard, focused, Cypress) => {
259264
skipped: formatReasonNotFired('Already on Coordinates'),
260265
}
261266
}
267+
268+
type EventFunc =
269+
| (() => { skipped: string })
270+
| (() => SentEvent)
271+
262272
let pointerout = _.noop
263273
let pointerleave = _.noop
264-
let pointerover = notFired
274+
let pointerover: EventFunc = notFired
265275
let pointerenter = _.noop
266276
let mouseout = _.noop
267277
let mouseleave = _.noop
268-
let mouseover = notFired
278+
let mouseover: EventFunc = notFired
269279
let mouseenter = _.noop
270-
let pointermove = notFired
271-
let mousemove = notFired
280+
let pointermove: EventFunc = notFired
281+
let mousemove: EventFunc = notFired
272282

273283
const lastHoveredEl = getLastHoveredEl(state)
274284

@@ -285,9 +295,9 @@ export const create = (state, keyboard, focused, Cypress) => {
285295
sendMouseout(lastHoveredEl, _.extend({}, defaultMouseOptions, { relatedTarget: el }))
286296
}
287297

288-
let curParent = lastHoveredEl
298+
let curParent: Node | null = lastHoveredEl
289299

290-
const elsToSendMouseleave = []
300+
const elsToSendMouseleave: Node[] = []
291301

292302
while (curParent && curParent.ownerDocument && curParent !== commonAncestor) {
293303
elsToSendMouseleave.push(curParent)
@@ -317,8 +327,8 @@ export const create = (state, keyboard, focused, Cypress) => {
317327
return sendPointerover(el, _.extend({}, defaultPointerOptions, { relatedTarget: lastHoveredEl }))
318328
}
319329

320-
let curParent = el
321-
const elsToSendMouseenter = []
330+
let curParent: Node | null = el
331+
const elsToSendMouseenter: Node[] = []
322332

323333
while (curParent && curParent.ownerDocument && curParent !== commonAncestor) {
324334
elsToSendMouseenter.push(curParent)
@@ -349,7 +359,8 @@ export const create = (state, keyboard, focused, Cypress) => {
349359
return sendMousemove(el, defaultMouseOptions)
350360
}
351361

352-
const events = []
362+
// TODO: make `type` below more specific.
363+
const events: Array<ReturnType<EventFunc> & { type: string }> = []
353364

354365
pointerout()
355366
pointerleave()
@@ -419,7 +430,7 @@ export const create = (state, keyboard, focused, Cypress) => {
419430
let pointerdown = sendPointerdown(
420431
el,
421432
pointerEvtOptions,
422-
)
433+
) as Partial<SentEvent>
423434

424435
const pointerdownPrevented = pointerdown.preventedDefault
425436
const elIsDetached = $elements.isDetachedEl(el)
@@ -461,7 +472,7 @@ export const create = (state, keyboard, focused, Cypress) => {
461472
// el we just send pointerdown
462473
const el = mouseDownPhase.targetEl
463474

464-
if (mouseDownPhase.events.pointerdown.preventedDefault || mouseDownPhase.events.mousedown.preventedDefault || !$elements.isAttachedEl(el)) {
475+
if (mouseDownPhase.events.pointerdown.preventedDefault || (mouseDownPhase.events.mousedown as Partial<SentEvent>).preventedDefault || !$elements.isAttachedEl(el)) {
465476
return mouseDownPhase
466477
}
467478

@@ -488,6 +499,8 @@ export const create = (state, keyboard, focused, Cypress) => {
488499

489500
if (shouldMoveCursorToEndAfterMousedown(el)) {
490501
debug('moveSelectionToEnd due to click', el)
502+
// It's a curried function, so the 2 arguments are valid.
503+
// @ts-ignore
491504
$selection.moveSelectionToEnd(el, { onlyIfEmptySelection: true })
492505
}
493506

@@ -532,7 +545,7 @@ export const create = (state, keyboard, focused, Cypress) => {
532545

533546
const mouseDownPhase = mouse.down(fromElViewport, forceEl, pointerEvtOptionsExtend, mouseEvtOptionsExtend)
534547

535-
const skipMouseupEvent = mouseDownPhase.events.pointerdown.skipped || mouseDownPhase.events.pointerdown.preventedDefault
548+
const skipMouseupEvent = mouseDownPhase.events.pointerdown.preventedDefault
536549

537550
const mouseUpPhase = mouse.up(fromElViewport, forceEl, skipMouseupEvent, pointerEvtOptionsExtend, mouseEvtOptionsExtend)
538551

@@ -638,7 +651,7 @@ export const create = (state, keyboard, focused, Cypress) => {
638651
return { click }
639652
},
640653

641-
_contextmenuEvent (fromElViewport, forceEl, mouseEvtOptionsExtend) {
654+
_contextmenuEvent (fromElViewport, forceEl, mouseEvtOptionsExtend?) {
642655
const el = forceEl || mouse.moveToCoords(fromElViewport)
643656

644657
const win = $dom.getWindowByElement(el)
@@ -695,7 +708,7 @@ export const create = (state, keyboard, focused, Cypress) => {
695708

696709
const contextmenuEvent = mouse._contextmenuEvent(fromElViewport, forceEl)
697710

698-
const skipMouseupEvent = mouseDownPhase.events.pointerdown.skipped || mouseDownPhase.events.pointerdown.preventedDefault
711+
const skipMouseupEvent = mouseDownPhase.events.pointerdown.preventedDefault
699712
const mouseUpPhase = mouse.up(fromElViewport, forceEl, skipMouseupEvent, pointerEvtOptionsExtend, mouseEvtOptionsExtend)
700713

701714
const clickEvents = _.extend({}, mouseDownPhase.events, mouseUpPhase.events)
@@ -709,7 +722,14 @@ export const create = (state, keyboard, focused, Cypress) => {
709722

710723
const { stopPropagation } = window.MouseEvent.prototype
711724

712-
const sendEvent = (evtName, el, evtOptions, bubbles = false, cancelable = false, Constructor, composed = false) => {
725+
type SentEvent = {
726+
stoppedPropagation: boolean
727+
preventedDefault: boolean
728+
el: HTMLElement
729+
modifiers: string
730+
}
731+
732+
const sendEvent = (evtName, el, evtOptions, bubbles = false, cancelable = false, Constructor, composed = false): SentEvent => {
713733
evtOptions = _.extend({}, evtOptions, { bubbles, cancelable })
714734
const _eventModifiers = $Keyboard.fromModifierEventOptions(evtOptions)
715735
const modifiers = $Keyboard.modifiersToString(_eventModifiers)
@@ -720,6 +740,9 @@ const sendEvent = (evtName, el, evtOptions, bubbles = false, cancelable = false,
720740
evt.stopPropagation = function (...args) {
721741
evt._hasStoppedPropagation = true
722742

743+
// stopPropagation doesn't have argument. So, we cannot type-safely pass the second argument.
744+
// But we're passing it just in case.
745+
// @ts-ignore
723746
return stopPropagation.apply(this, ...args)
724747
}
725748
}
@@ -740,6 +763,19 @@ const formatReasonNotFired = (reason) => {
740763
return `⚠️ not fired (${reason})`
741764
}
742765

766+
type CoordsEventOptions = {
767+
x: number
768+
y: number
769+
clientX: number
770+
clientY: number
771+
screenX: number
772+
screenY: number
773+
pageX: number
774+
pageY: number
775+
layerX: number
776+
layerY: number
777+
}
778+
743779
const toCoordsEventOptions = (x, y, win) => {
744780
// these are the coords from the element's window,
745781
// ignoring scroll position

packages/driver/src/dom/elements/detached.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ export const isAttached = function ($el) {
4444
})
4545
}
4646

47-
export const isDetachedEl = (el: HTMLElement) => {
47+
export const isDetachedEl = (el: HTMLElement | JQuery<any>) => {
4848
return !isAttachedEl(el)
4949
}
5050

51-
export const isAttachedEl = function (el: HTMLElement) {
51+
export const isAttachedEl = function (el: HTMLElement | JQuery<any>) {
5252
return isAttached($(el))
5353
}

0 commit comments

Comments
 (0)