@@ -80,6 +80,58 @@ test.describe("POST beacon LoAF", () => {
8080 }
8181 } ) ;
8282
83+ test ( "Only the slowest LoAFs are collected" , async ( { page } ) => {
84+ const MAX_ENTRIES = 3 ;
85+ const loafSupported = await entryTypeSupported ( page , "long-animation-frame" ) ;
86+ const luxRequests = new RequestInterceptor ( page ) . createRequestMatcher ( "/store/" ) ;
87+ await page . goto (
88+ `/long-animation-frames.html?injectScript=LUX.maxAttributionEntries=${ MAX_ENTRIES } ;` ,
89+ {
90+ waitUntil : "networkidle" ,
91+ } ,
92+ ) ;
93+
94+ // Create a mixture of short and long LoAFs
95+ // Short
96+ await page . locator ( "#create-long-task" ) . click ( ) ;
97+ await page . locator ( "#create-long-task" ) . click ( ) ;
98+
99+ // Long
100+ await page . locator ( "#long-task-duration" ) . fill ( "100" ) ;
101+ await page . locator ( "#create-long-task" ) . click ( ) ;
102+
103+ // Short
104+ await page . locator ( "#long-task-duration" ) . fill ( "50" ) ;
105+ await page . locator ( "#create-long-task" ) . click ( ) ;
106+ await page . locator ( "#create-long-task" ) . click ( ) ;
107+
108+ // Long
109+ await page . locator ( "#long-task-duration" ) . fill ( "150" ) ;
110+ await page . locator ( "#create-long-task" ) . click ( ) ;
111+ await page . locator ( "#create-long-task" ) . click ( ) ;
112+
113+ await luxRequests . waitForMatchingRequest ( ( ) => page . evaluate ( ( ) => LUX . send ( ) ) ) ;
114+ const b = luxRequests . get ( 0 ) ! . postDataJSON ( ) as BeaconPayload ;
115+
116+ if ( loafSupported ) {
117+ const loaf = b . loaf ! ;
118+
119+ expect ( loaf . entries . length ) . toEqual ( MAX_ENTRIES ) ;
120+
121+ // The entries should all be the longer LoAFs. Note the total duration is the value from the
122+ // #long-task-duration input, plus a hard-coded 50ms long task in external-long.task.js.
123+ expect ( loaf . entries [ 0 ] . duration ) . toBeGreaterThanOrEqual ( 150 ) ;
124+ expect ( loaf . entries [ 1 ] . duration ) . toBeGreaterThanOrEqual ( 150 ) ;
125+ expect ( loaf . entries [ 2 ] . duration ) . toBeGreaterThanOrEqual ( 100 ) ;
126+
127+ // The entries should be ordered by start time
128+ expect ( loaf . entries [ 0 ] . startTime ) . toBeLessThanOrEqual ( loaf . entries [ 1 ] . startTime ) ;
129+ expect ( loaf . entries [ 1 ] . startTime ) . toBeLessThanOrEqual ( loaf . entries [ 2 ] . startTime ) ;
130+ } else {
131+ expect ( b . loaf ) . toBeUndefined ( ) ;
132+ }
133+ } ) ;
134+
83135 test ( "LoAFs are collected as INP attribution" , async ( { page } ) => {
84136 const luxRequests = new RequestInterceptor ( page ) . createRequestMatcher ( "/store/" ) ;
85137 await page . goto ( "/long-animation-frames.html" , { waitUntil : "networkidle" } ) ;
0 commit comments