1
1
import type { Route } from '@playwright/test' ;
2
2
import { expect } from '@playwright/test' ;
3
- import type { Event } from '@sentry/core' ;
3
+ import { type Event , SEMANTIC_ATTRIBUTE_SENTRY_OP , SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core' ;
4
4
5
5
import { sentryTest } from '../../../../utils/fixtures' ;
6
6
import { getFirstSentryEnvelopeRequest , shouldSkipTracingTest } from '../../../../utils/helpers' ;
7
7
8
- sentryTest ( 'should add resource spans to pageload transaction' , async ( { getLocalTestUrl, page } ) => {
8
+ sentryTest ( 'should add resource spans to pageload transaction' , async ( { getLocalTestUrl, page, browserName } ) => {
9
9
if ( shouldSkipTracingTest ( ) ) {
10
10
sentryTest . skip ( ) ;
11
11
}
12
12
13
+ const isWebkitRun = browserName === 'webkit' ;
14
+
13
15
// Intercepting asset requests to avoid network-related flakiness and random retries (on Firefox).
14
16
await page . route ( 'https://example.com/path/to/image.svg' , ( route : Route ) =>
15
- route . fulfill ( { path : `${ __dirname } /assets/image.svg` } ) ,
17
+ route . fulfill ( {
18
+ path : `${ __dirname } /assets/image.svg` ,
19
+ headers : {
20
+ 'Timing-Allow-Origin' : '*' ,
21
+ 'Content-Type' : 'image/svg+xml' ,
22
+ } ,
23
+ } ) ,
16
24
) ;
17
25
await page . route ( 'https://example.com/path/to/script.js' , ( route : Route ) =>
18
- route . fulfill ( { path : `${ __dirname } /assets/script.js` } ) ,
26
+ route . fulfill ( {
27
+ path : `${ __dirname } /assets/script.js` ,
28
+ headers : {
29
+ 'Timing-Allow-Origin' : '*' ,
30
+ 'Content-Type' : 'application/javascript' ,
31
+ } ,
32
+ } ) ,
19
33
) ;
20
34
await page . route ( 'https://example.com/path/to/style.css' , ( route : Route ) =>
21
- route . fulfill ( { path : `${ __dirname } /assets/style.css` } ) ,
35
+ route . fulfill ( {
36
+ path : `${ __dirname } /assets/style.css` ,
37
+ headers : {
38
+ 'Timing-Allow-Origin' : '*' ,
39
+ 'Content-Type' : 'text/css' ,
40
+ } ,
41
+ } ) ,
22
42
) ;
23
43
24
44
const url = await getLocalTestUrl ( { testDir : __dirname } ) ;
@@ -27,11 +47,14 @@ sentryTest('should add resource spans to pageload transaction', async ({ getLoca
27
47
const resourceSpans = eventData . spans ?. filter ( ( { op } ) => op ?. startsWith ( 'resource' ) ) ;
28
48
29
49
const scriptSpans = resourceSpans ?. filter ( ( { op } ) => op === 'resource.script' ) ;
30
- const linkSpans = resourceSpans ?. filter ( ( { op } ) => op === 'resource.link' ) ;
31
- const imgSpans = resourceSpans ?. filter ( ( { op } ) => op === 'resource.img' ) ;
50
+ const linkSpan = resourceSpans ?. filter ( ( { op } ) => op === 'resource.link' ) [ 0 ] ;
51
+ const imgSpan = resourceSpans ?. filter ( ( { op } ) => op === 'resource.img' ) [ 0 ] ;
52
+
53
+ const spanId = eventData . contexts ?. trace ?. span_id ;
54
+ const traceId = eventData . contexts ?. trace ?. trace_id ;
32
55
33
- expect ( imgSpans ) . toHaveLength ( 1 ) ;
34
- expect ( linkSpans ) . toHaveLength ( 1 ) ;
56
+ expect ( spanId ) . toBeDefined ( ) ;
57
+ expect ( traceId ) . toBeDefined ( ) ;
35
58
36
59
const hasCdnBundle = ( process . env . PW_BUNDLE || '' ) . startsWith ( 'bundle' ) ;
37
60
@@ -41,11 +64,90 @@ sentryTest('should add resource spans to pageload transaction', async ({ getLoca
41
64
}
42
65
43
66
expect ( scriptSpans ?. map ( ( { description } ) => description ) . sort ( ) ) . toEqual ( expectedScripts ) ;
67
+ expect ( scriptSpans ?. map ( ( { parent_span_id } ) => parent_span_id ) ) . toEqual ( expectedScripts . map ( ( ) => spanId ) ) ;
44
68
45
- const spanId = eventData . contexts ?. trace ?. span_id ;
69
+ const customScriptSpan = scriptSpans ?. find (
70
+ ( { description } ) => description === 'https://example.com/path/to/script.js' ,
71
+ ) ;
46
72
47
- expect ( spanId ) . toBeDefined ( ) ;
48
- expect ( imgSpans ?. [ 0 ] . parent_span_id ) . toBe ( spanId ) ;
49
- expect ( linkSpans ?. [ 0 ] . parent_span_id ) . toBe ( spanId ) ;
50
- expect ( scriptSpans ?. map ( ( { parent_span_id } ) => parent_span_id ) ) . toEqual ( expectedScripts . map ( ( ) => spanId ) ) ;
73
+ expect ( imgSpan ) . toEqual ( {
74
+ data : {
75
+ 'http.decoded_response_content_length' : expect . any ( Number ) ,
76
+ 'http.response_content_length' : expect . any ( Number ) ,
77
+ 'http.response_transfer_size' : expect . any ( Number ) ,
78
+ 'network.protocol.name' : '' ,
79
+ 'network.protocol.version' : 'unknown' ,
80
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'resource.img' ,
81
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.resource.browser.metrics' ,
82
+ 'server.address' : 'example.com' ,
83
+ 'url.same_origin' : false ,
84
+ 'url.scheme' : 'https' ,
85
+ ...( ! isWebkitRun && {
86
+ 'resource.render_blocking_status' : 'non-blocking' ,
87
+ 'http.response_delivery_type' : '' ,
88
+ } ) ,
89
+ } ,
90
+ description : 'https://example.com/path/to/image.svg' ,
91
+ op : 'resource.img' ,
92
+ origin : 'auto.resource.browser.metrics' ,
93
+ parent_span_id : spanId ,
94
+ span_id : expect . stringMatching ( / ^ [ a - f 0 - 9 ] { 16 } $ / ) ,
95
+ start_timestamp : expect . any ( Number ) ,
96
+ timestamp : expect . any ( Number ) ,
97
+ trace_id : traceId ,
98
+ } ) ;
99
+
100
+ expect ( linkSpan ) . toEqual ( {
101
+ data : {
102
+ 'http.decoded_response_content_length' : expect . any ( Number ) ,
103
+ 'http.response_content_length' : expect . any ( Number ) ,
104
+ 'http.response_transfer_size' : expect . any ( Number ) ,
105
+ 'network.protocol.name' : '' ,
106
+ 'network.protocol.version' : 'unknown' ,
107
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'resource.link' ,
108
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.resource.browser.metrics' ,
109
+ 'server.address' : 'example.com' ,
110
+ 'url.same_origin' : false ,
111
+ 'url.scheme' : 'https' ,
112
+ ...( ! isWebkitRun && {
113
+ 'resource.render_blocking_status' : 'non-blocking' ,
114
+ 'http.response_delivery_type' : '' ,
115
+ } ) ,
116
+ } ,
117
+ description : 'https://example.com/path/to/style.css' ,
118
+ op : 'resource.link' ,
119
+ origin : 'auto.resource.browser.metrics' ,
120
+ parent_span_id : spanId ,
121
+ span_id : expect . stringMatching ( / ^ [ a - f 0 - 9 ] { 16 } $ / ) ,
122
+ start_timestamp : expect . any ( Number ) ,
123
+ timestamp : expect . any ( Number ) ,
124
+ trace_id : traceId ,
125
+ } ) ;
126
+
127
+ expect ( customScriptSpan ) . toEqual ( {
128
+ data : {
129
+ 'http.decoded_response_content_length' : expect . any ( Number ) ,
130
+ 'http.response_content_length' : expect . any ( Number ) ,
131
+ 'http.response_transfer_size' : expect . any ( Number ) ,
132
+ 'network.protocol.name' : '' ,
133
+ 'network.protocol.version' : 'unknown' ,
134
+ 'sentry.op' : 'resource.script' ,
135
+ 'sentry.origin' : 'auto.resource.browser.metrics' ,
136
+ 'server.address' : 'example.com' ,
137
+ 'url.same_origin' : false ,
138
+ 'url.scheme' : 'https' ,
139
+ ...( ! isWebkitRun && {
140
+ 'resource.render_blocking_status' : 'non-blocking' ,
141
+ 'http.response_delivery_type' : '' ,
142
+ } ) ,
143
+ } ,
144
+ description : 'https://example.com/path/to/script.js' ,
145
+ op : 'resource.script' ,
146
+ origin : 'auto.resource.browser.metrics' ,
147
+ parent_span_id : spanId ,
148
+ span_id : expect . stringMatching ( / ^ [ a - f 0 - 9 ] { 16 } $ / ) ,
149
+ start_timestamp : expect . any ( Number ) ,
150
+ timestamp : expect . any ( Number ) ,
151
+ trace_id : traceId ,
152
+ } ) ;
51
153
} ) ;
0 commit comments