-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
dom_hitbox.cy.js
169 lines (135 loc) · 5.01 KB
/
dom_hitbox.cy.js
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
const { clickCommandLog } = require('../../support/utils')
const { _ } = Cypress
// https://github.com/cypress-io/cypress/pull/5299/files
// TODO(webkit): fix+unskip for experimental webkit
describe('rect highlight', { browser: '!webkit' }, () => {
beforeEach(() => {
cy.visit('/fixtures/dom.html')
})
it('highlight elements are properly positioned', () => {
cy.$$('button:first').css({ boxSizing: 'content-box' })
getAndPin('button:first')
ensureCorrectHighlightPositions('button:first')
})
it('highlight elements properly positioned for content-box', () => {
getAndPin('button.content-box:first')
ensureCorrectHighlightPositions()
})
it('highlight inline elements', () => {
cy.$$('<span>foo</span>').prependTo(cy.$$('body'))
getAndPin('span:first')
ensureCorrectHighlightPositions('span:first')
})
it('highlight elements with css transform', () => {
cy.$$('button:first').css({ transform: 'scale(1.5) rotate(45deg)' })
getAndPin('button:first')
ensureCorrectHighlightPositions('button:first')
})
it('highlight elements with css transform on parent', () => {
cy.$$('<div id="parent">parent<div id="child">child</div></div>').css({
transform: 'scale(1.5) rotate(45deg) translate(100px, 20px)',
height: 40,
width: 60,
})
.prependTo(cy.$$('body'))
getAndPin('#child')
// TODO: assert covers element bounding-box
ensureCorrectHighlightPositions(null)
})
it('correct target position during click', () => {
clickAndPin('#button')
ensureCorrectHighlightPositions('#button')
ensureCorrectTargetPosition('#button')
})
it('correct target position during click with offset coords', () => {
clickAndPin('#button', 5, 10)
ensureCorrectHighlightPositions('#button')
ensureCorrectTargetPosition('#button')
})
// https://github.com/cypress-io/cypress/issues/7762
it('highlights above z-index elements', () => {
cy.$$('<div id="absolute-el"></div>').css({
position: 'absolute',
zIndex: 1000,
top: 0,
left: 0,
height: 50,
width: 50,
padding: 20,
margin: 20,
backgroundColor: 'salmon',
}).appendTo(cy.$$('body'))
getAndPin('#absolute-el')
ensureCorrectHighlightPositions('#absolute-el')
})
})
const ensureCorrectTargetPosition = (sel) => {
return cy.wrap(null, { timeout: 4000 }).should(() => {
const target = cy.$$('div[data-highlight-hitbox]')[0].getBoundingClientRect()
const dims = {
left: target.left + target.width / 2,
right: target.left + target.width / 2,
top: target.top + target.height / 2,
bottom: target.top + target.height / 2,
width: 1,
height: 1,
}
expectToBeInside(dims, cy.$$(sel)[0].getBoundingClientRect(), 'border-box to match selector bounding-box')
})
}
const ensureCorrectHighlightPositions = (sel) => {
return cy.wrap(null, { timeout: 4000 }).should(() => {
const els = {
content: cy.$$('div[data-layer=Content]'),
padding: cy.$$('div[data-layer=Padding]'),
border: cy.$$('div[data-layer=Border]'),
}
const dims = _.mapValues(els, ($el) => {
return $el[0].getBoundingClientRect()
})
const doc = els.content[0].ownerDocument
const contentHighlightCenter = [dims.content.x + dims.content.width / 2, dims.content.y + dims.content.height / 2]
const highlightedEl = doc.elementFromPoint(...contentHighlightCenter)
expect(highlightedEl).eq(els.content[0])
expectToBeInside(dims.content, dims.padding, 'content to be inside padding')
expectToBeInside(dims.padding, dims.border, 'padding to be inside border')
if (sel) {
// assert converting bounding-box of element
expectToBeEqual(dims.border, cy.$$(sel)[0].getBoundingClientRect(), 'border-box to match selector bounding-box')
}
})
}
const getAndPin = (sel) => {
cy.get(sel)
clickCommandLog(sel, 'message-text')
}
const clickAndPin = (sel, ...args) => {
cy.get(sel).click(...args)
clickCommandLog('click')
}
const expectToBeEqual = (rect1, rect2, mes = 'rect to be equal to rect') => {
try {
expect(rect1.width, 'width').to.be.closeTo(rect2.width, 1)
expect(rect1.height, 'height').to.be.closeTo(rect2.height, 1)
expect(rect1.top, 'top').to.be.closeTo(rect2.top, 1)
expect(rect1.left, 'left').to.be.closeTo(rect2.left, 1)
expect(rect1.right, 'right').to.be.closeTo(rect2.right, 1)
expect(rect1.bottom, 'bottom').to.be.closeTo(rect2.bottom, 1)
} catch (e) {
e.message = `\nExpected ${mes}\n${e.message}`
throw e
}
}
const expectToBeInside = (rectInner, rectOuter, mes = 'rect to be inside rect') => {
try {
expect(rectInner.width, 'width').lte(rectOuter.width)
expect(rectInner.height, 'height').lte(rectOuter.height)
expect(rectInner.top, 'top').gte(rectOuter.top)
expect(rectInner.left, 'left').gte(rectOuter.left)
expect(rectInner.right, 'right').lte(rectOuter.right)
expect(rectInner.bottom, 'bottom').lte(rectOuter.bottom)
} catch (e) {
e.message = `\nExpected ${mes}\n${e.message}`
throw e
}
}