forked from hotwired/stimulus
/
dom_test_case.ts
79 lines (65 loc) · 2.37 KB
/
dom_test_case.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { TestCase } from "./test_case"
interface TriggerEventOptions {
bubbles?: boolean,
setDefaultPrevented?: boolean
}
const defaultTriggerEventOptions: TriggerEventOptions = {
bubbles: true,
setDefaultPrevented: true
}
export class DOMTestCase extends TestCase {
fixtureSelector: string = "#qunit-fixture"
fixtureHTML: string = ""
async runTest(testName: string) {
await this.renderFixture()
await super.runTest(testName)
}
async renderFixture(fixtureHTML = this.fixtureHTML) {
this.fixtureElement.innerHTML = fixtureHTML
return this.nextFrame
}
get fixtureElement(): Element {
const element = document.querySelector(this.fixtureSelector)
if (element) {
return element
} else {
throw new Error(`missing fixture element "${this.fixtureSelector}"`)
}
}
async triggerEvent(selectorOrTarget: string | EventTarget, type: string, options: TriggerEventOptions = {}) {
const { bubbles, setDefaultPrevented } = { ...defaultTriggerEventOptions, ...options }
const eventTarget = typeof selectorOrTarget == "string" ? this.findElement(selectorOrTarget) : selectorOrTarget
const event = document.createEvent("Events")
event.initEvent(type, bubbles, true)
// IE <= 11 does not set `defaultPrevented` when `preventDefault()` is called on synthetic events
if (setDefaultPrevented) {
event.preventDefault = function() {
Object.defineProperty(this, "defaultPrevented", { get: () => true, configurable: true })
}
}
eventTarget.dispatchEvent(event)
await this.nextFrame
return event
}
async triggerKeyboardEvent(selectorOrTarget: string | EventTarget, type: string, options: KeyboardEventInit = {}) {
const eventTarget = typeof selectorOrTarget == "string" ? this.findElement(selectorOrTarget) : selectorOrTarget
const event = new KeyboardEvent(type, options);
eventTarget.dispatchEvent(event)
await this.nextFrame
return event
}
findElement(selector: string) {
const element = this.fixtureElement.querySelector(selector)
if (element) {
return element
} else {
throw new Error(`couldn't find element "${selector}"`)
}
}
findElements(...selectors: string[]) {
return selectors.map(selector => this.findElement(selector))
}
get nextFrame(): Promise<any> {
return new Promise(resolve => requestAnimationFrame(resolve))
}
}