@@ -5,7 +5,14 @@ import type { Event } from '@sentry/types';
55import { sentryTest } from '../../../../utils/fixtures' ;
66import { getFirstSentryEnvelopeRequest , shouldSkipTracingTest } from '../../../../utils/helpers' ;
77
8- sentryTest ( 'should capture a LCP vital with element details.' , async ( { browserName, getLocalTestUrl, page } ) => {
8+ /*
9+ Because we "serve" the html test page as a static file, all requests for the image
10+ are considered 3rd party requests. So the LCP value we obtain for the image is also
11+ considered a 3rd party LCP value, meaning `renderTime` is only set if we also
12+ return the `Timing-Allow-Origin` header.
13+ */
14+
15+ sentryTest ( 'captures LCP vitals with element details.' , async ( { browserName, getLocalTestUrl, page } ) => {
916 if ( shouldSkipTracingTest ( ) || browserName !== 'chromium' ) {
1017 sentryTest . skip ( ) ;
1118 }
@@ -16,17 +23,50 @@ sentryTest('should capture a LCP vital with element details.', async ({ browserN
1623 } ) ;
1724
1825 const url = await getLocalTestUrl ( { testDir : __dirname } ) ;
19- const [ eventData ] = await Promise . all ( [
20- getFirstSentryEnvelopeRequest < Event > ( page ) ,
21- page . goto ( url ) ,
22- page . locator ( 'button' ) . click ( ) ,
23- ] ) ;
26+ const [ eventData ] = await Promise . all ( [ getFirstSentryEnvelopeRequest < Event > ( page ) , page . goto ( url ) ] ) ;
2427
2528 expect ( eventData . measurements ) . toBeDefined ( ) ;
2629 expect ( eventData . measurements ?. lcp ?. value ) . toBeDefined ( ) ;
2730
28- // XXX: This should be body > img, but it can be flakey as sometimes it will report
29- // the button as LCP.
3031 expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.element' ] . startsWith ( 'body >' ) ) . toBe ( true ) ;
3132 expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.size' ] ) . toBeGreaterThan ( 0 ) ;
33+ expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.loadTime' ] ) . toBeGreaterThan ( 0 ) ;
34+
35+ // renderTime is 0 because we don't return the `Timing-Allow-Origin` header
36+ // and the image is loaded from a 3rd party origin
37+ expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.renderTime' ] ) . toBe ( 0 ) ;
38+
39+ // The LCP value should be the loadTime because the renderTime is not set
40+ expect ( eventData . measurements ?. lcp ?. value ) . toBeCloseTo ( eventData . contexts ?. trace ?. data ?. [ 'lcp.loadTime' ] ) ;
3241} ) ;
42+
43+ sentryTest (
44+ 'captures LCP renderTime when returning Timing-Allow-Origin header.' ,
45+ async ( { browserName, getLocalTestUrl, page } ) => {
46+ if ( shouldSkipTracingTest ( ) || browserName !== 'chromium' ) {
47+ sentryTest . skip ( ) ;
48+ }
49+
50+ page . route ( '**' , route => route . continue ( ) ) ;
51+ page . route ( '**/my/image.png' , async ( route : Route ) => {
52+ return route . fulfill ( {
53+ path : `${ __dirname } /assets/sentry-logo-600x179.png` ,
54+ headers : { 'Timing-Allow-Origin' : '*' } ,
55+ } ) ;
56+ } ) ;
57+
58+ const url = await getLocalTestUrl ( { testDir : __dirname } ) ;
59+ const [ eventData ] = await Promise . all ( [ getFirstSentryEnvelopeRequest < Event > ( page ) , page . goto ( url ) ] ) ;
60+
61+ expect ( eventData . measurements ) . toBeDefined ( ) ;
62+ expect ( eventData . measurements ?. lcp ?. value ) . toBeDefined ( ) ;
63+
64+ expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.element' ] . startsWith ( 'body >' ) ) . toBe ( true ) ;
65+ expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.size' ] ) . toBeGreaterThan ( 0 ) ;
66+ expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.loadTime' ] ) . toBeGreaterThan ( 0 ) ;
67+ expect ( eventData . contexts ?. trace ?. data ?. [ 'lcp.renderTime' ] ) . toBeGreaterThan ( 0 ) ;
68+
69+ // The LCP value should be the renderTime because the renderTime is set
70+ expect ( eventData . measurements ?. lcp ?. value ) . toBeCloseTo ( eventData . contexts ?. trace ?. data ?. [ 'lcp.renderTime' ] ) ;
71+ } ,
72+ ) ;
0 commit comments