Skip to content

Commit 3310e9c

Browse files
✅ fix flaky test (#3902)
1 parent d621bf2 commit 3310e9c

File tree

1 file changed

+42
-39
lines changed

1 file changed

+42
-39
lines changed
Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,44 @@
1-
import { addEventListener, DOM_EVENT } from '@datadog/browser-core'
2-
import { mockRumConfiguration } from '../../test'
1+
import { DOM_EVENT } from '@datadog/browser-core'
32
import { getScrollX, getScrollY } from './scroll'
43

54
describe('scroll', () => {
6-
let shouldWaitForWindowScrollEvent: boolean
7-
const configuration = mockRumConfiguration()
8-
const addVerticalScrollBar = () => {
9-
document.body.style.setProperty('margin-bottom', '5000px')
10-
}
5+
let testDidScroll: boolean
116

127
beforeEach(() => {
13-
shouldWaitForWindowScrollEvent = false
8+
document.body.style.setProperty('margin-bottom', '5000px')
9+
testDidScroll = false
1410
})
1511

16-
afterEach((done) => {
12+
afterEach(async () => {
1713
document.body.style.removeProperty('margin-bottom')
1814
window.scrollTo(0, 0)
1915

20-
// Those tests are triggering asynchronous scroll events that might impact tests run after them.
21-
// To avoid that, we wait for the next scroll event before continuing to the next one.
22-
// Those events don't seem to be triggered consistently on safari though, so stop waiting after a while.
23-
if (shouldWaitForWindowScrollEvent) {
24-
const STOP_WAITING_FOR_SCROLL = 2000
25-
const { stop: removeScrollListener } = addEventListener(
26-
configuration,
27-
window,
28-
DOM_EVENT.SCROLL,
29-
() => {
30-
clearTimeout(timeout)
31-
done()
32-
},
33-
{
34-
passive: true,
35-
once: true,
36-
capture: true,
37-
}
38-
)
39-
const timeout = setTimeout(() => {
40-
removeScrollListener()
41-
done()
42-
}, STOP_WAITING_FOR_SCROLL)
43-
} else {
44-
done()
45-
}
16+
// Those tests are triggering asynchronous events that might impact tests run after them. To
17+
// avoid that, we wait for the events before continuing to the next test.
18+
await Promise.all([
19+
window.visualViewport &&
20+
waitForEvents(
21+
window.visualViewport,
22+
DOM_EVENT.RESIZE,
23+
2 // We add then remove the scrollbar, so the resize event is triggered twice
24+
),
25+
testDidScroll && waitForEvents(window, DOM_EVENT.SCROLL, 1),
26+
])
4627
})
4728

4829
describe('getScrollX/Y', () => {
49-
it('normalized scroll matches initial behaviour', () => {
50-
addVerticalScrollBar()
30+
it('normalized scroll matches initial behavior', () => {
5131
expect(getScrollX()).toBe(0)
5232
expect(getScrollY()).toBe(0)
5333
expect(getScrollX()).toBe(window.scrollX || window.pageXOffset)
5434
expect(getScrollY()).toBe(window.scrollY || window.pageYOffset)
5535
})
5636

5737
it('normalized scroll updates when scrolled', () => {
58-
addVerticalScrollBar()
5938
const SCROLL_DOWN_PX = 100
6039

6140
window.scrollTo(0, SCROLL_DOWN_PX)
62-
shouldWaitForWindowScrollEvent = true
41+
testDidScroll = true
6342

6443
expect(getScrollX()).toBe(0)
6544
expect(getScrollY()).toBe(100)
@@ -68,3 +47,27 @@ describe('scroll', () => {
6847
})
6948
})
7049
})
50+
51+
function waitForEvents(target: EventTarget, eventName: string, count: number) {
52+
return new Promise<void>((resolve) => {
53+
let counter = 0
54+
55+
function listener() {
56+
counter++
57+
if (counter === count) {
58+
done()
59+
}
60+
}
61+
62+
function done() {
63+
target.removeEventListener(eventName, listener)
64+
resolve()
65+
}
66+
67+
target.addEventListener(eventName, listener)
68+
69+
// In some cases, events are not triggered consistently. This have been observed in Safari. To
70+
// avoid waiting forever, we use a timeout.
71+
setTimeout(done, 1000)
72+
})
73+
}

0 commit comments

Comments
 (0)