1- import { addEventListener , DOM_EVENT } from '@datadog/browser-core'
2- import { mockRumConfiguration } from '../../test'
1+ import { DOM_EVENT } from '@datadog/browser-core'
32import { getScrollX , getScrollY } from './scroll'
43
54describe ( '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