Skip to content

Commit 8771b8f

Browse files
authored
fix: use correct event interface (#977)
1 parent 0fb50d8 commit 8771b8f

File tree

6 files changed

+247
-1702
lines changed

6 files changed

+247
-1702
lines changed

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"eslint-plugin-markdown": "^1.0.0-beta.6",
4848
"eslint-plugin-vue-libs": "^2.1.0",
4949
"flow-bin": "^0.66.0",
50-
"jsdom": "^11.5.1",
50+
"jsdom": "^12.0.0",
5151
"jsdom-global": "^3.0.2",
5252
"karma": "^1.7.0",
5353
"karma-mocha": "^1.3.0",

Diff for: packages/test-utils/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"vue-template-compiler": "^2.x"
3838
},
3939
"dependencies": {
40+
"dom-event-types": "^1.0.0",
4041
"lodash": "^4.17.4"
4142
}
4243
}

Diff for: packages/test-utils/src/create-dom-event.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import eventTypes from 'dom-event-types'
2+
3+
const defaultEventType = {
4+
eventInterface: 'Event',
5+
cancelable: true,
6+
bubbles: true
7+
}
8+
9+
const modifiers = {
10+
enter: 13,
11+
tab: 9,
12+
delete: 46,
13+
esc: 27,
14+
space: 32,
15+
up: 38,
16+
down: 40,
17+
left: 37,
18+
right: 39,
19+
end: 35,
20+
home: 36,
21+
backspace: 8,
22+
insert: 45,
23+
pageup: 33,
24+
pagedown: 34
25+
}
26+
27+
export default function createDOMEvent (type, options) {
28+
const [eventType, modifier] = type.split('.')
29+
const {
30+
eventInterface,
31+
bubbles,
32+
cancelable
33+
} = eventTypes[eventType] || defaultEventType
34+
35+
if (typeof window.Event === 'function') {
36+
const SupportedEventInterface =
37+
typeof window[eventInterface] === 'function'
38+
? window[eventInterface]
39+
: window.Event
40+
41+
return new SupportedEventInterface(eventType, {
42+
bubbles,
43+
cancelable,
44+
...options,
45+
keyCode: modifiers[modifier]
46+
})
47+
}
48+
49+
// Fallback for IE10,11 - https://stackoverflow.com/questions/26596123
50+
const eventObject = document.createEvent('Event')
51+
52+
eventObject.initEvent(eventType, bubbles, cancelable)
53+
Object.keys(options || {}).forEach(key => {
54+
eventObject[key] = options[key]
55+
})
56+
eventObject.keyCode = modifiers[modifier]
57+
58+
return eventObject
59+
}

Diff for: packages/test-utils/src/wrapper.js

+3-45
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import createWrapper from './create-wrapper'
1515
import { orderWatchers } from './order-watchers'
1616
import { recursivelySetData } from './recursively-set-data'
1717
import { matches } from './matches'
18+
import createDOMEvent from './create-dom-event'
1819

1920
export default class Wrapper implements BaseWrapper {
2021
+vnode: VNode | null;
@@ -823,52 +824,9 @@ export default class Wrapper implements BaseWrapper {
823824
return
824825
}
825826

826-
const modifiers = {
827-
enter: 13,
828-
tab: 9,
829-
delete: 46,
830-
esc: 27,
831-
space: 32,
832-
up: 38,
833-
down: 40,
834-
left: 37,
835-
right: 39,
836-
end: 35,
837-
home: 36,
838-
backspace: 8,
839-
insert: 45,
840-
pageup: 33,
841-
pagedown: 34
842-
}
843-
844-
const event = type.split('.')
845-
846-
let eventObject
847-
848-
// Fallback for IE10,11 - https://stackoverflow.com/questions/26596123
849-
if (typeof window.Event === 'function') {
850-
eventObject = new window.Event(event[0], {
851-
bubbles: true,
852-
cancelable: true
853-
})
854-
} else {
855-
eventObject = document.createEvent('Event')
856-
eventObject.initEvent(event[0], true, true)
857-
}
858-
859-
if (options) {
860-
Object.keys(options).forEach(key => {
861-
// $FlowIgnore
862-
eventObject[key] = options[key]
863-
})
864-
}
865-
866-
if (event.length === 2) {
867-
// $FlowIgnore
868-
eventObject.keyCode = modifiers[event[1]]
869-
}
827+
const event = createDOMEvent(type, options)
828+
this.element.dispatchEvent(event)
870829

871-
this.element.dispatchEvent(eventObject)
872830
if (this.vnode) {
873831
orderWatchers(this.vm || this.vnode.context.$root)
874832
}

Diff for: test/specs/wrapper/trigger.spec.js

+36-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import ComponentWithEvents from '~resources/components/component-with-events.vue
22
import ComponentWithScopedSlots from '~resources/components/component-with-scoped-slots.vue'
33
import {
44
describeWithShallowAndMount,
5-
scopedSlotsSupported
5+
scopedSlotsSupported,
6+
isRunningPhantomJS
67
} from '~resources/utils'
78
import Vue from 'vue'
89
import { itDoNotRunIf } from 'conditional-specs'
@@ -92,7 +93,9 @@ describeWithShallowAndMount('trigger', mountingMethod => {
9293
propsData: { clickHandler }
9394
})
9495
const button = wrapper.find('.left-click')
95-
button.trigger('mousedown')
96+
button.trigger('mousedown', {
97+
button: 1
98+
})
9699
button.trigger('mousedown', {
97100
button: 0
98101
})
@@ -180,4 +183,35 @@ describeWithShallowAndMount('trigger', mountingMethod => {
180183
.with.property('message', message)
181184
})
182185
})
186+
187+
itDoNotRunIf(
188+
isRunningPhantomJS,
189+
'trigger should create events with correct interface', () => {
190+
let lastEvent
191+
const TestComponent = {
192+
template: `
193+
<div @click="updateLastEvent" />
194+
`,
195+
methods: {
196+
updateLastEvent (event) {
197+
lastEvent = event
198+
}
199+
}
200+
}
201+
202+
const wrapper = mountingMethod(TestComponent)
203+
204+
wrapper.trigger('click')
205+
expect(lastEvent).to.be.an.instanceof(window.MouseEvent)
206+
})
207+
208+
it('falls back to supported event if not supported by browser', () => {
209+
const TestComponent = {
210+
template: '<div />'
211+
}
212+
213+
const wrapper = mountingMethod(TestComponent)
214+
215+
wrapper.trigger('gamepadconnected')
216+
})
183217
})

0 commit comments

Comments
 (0)