1
- import { expect , test } from '@playwright/test' ;
1
+ import { expect , test , type Page } from '@playwright/test' ;
2
2
import { waitForTransaction } from '@sentry-internal/test-utils' ;
3
3
4
4
test . describe ( 'Rendering Modes with Cached HTML' , ( ) => {
@@ -47,9 +47,6 @@ test.describe('Rendering Modes with Cached HTML', () => {
47
47
const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
48
48
const serverTxnEvent2TraceId = serverTxnEvent2 . contexts ?. trace ?. trace_id ;
49
49
50
- console . log ( 'Server Transaction 1:' , serverTxnEvent1TraceId ) ;
51
- console . log ( 'Server Transaction 2:' , serverTxnEvent2TraceId ) ;
52
-
53
50
await test . step ( 'Test distributed trace from 1. request' , ( ) => {
54
51
expect ( baggageMetaTagContent1 ) . toContain ( `sentry-trace_id=${ serverTxnEvent1TraceId } ` ) ;
55
52
@@ -74,156 +71,107 @@ test.describe('Rendering Modes with Cached HTML', () => {
74
71
} ) ;
75
72
76
73
test ( 'exclude tracing meta tags on SWR-cached page' , async ( { page } ) => {
77
- // === 1. Request ===
78
- const clientTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
79
- return txnEvent . transaction === '/rendering-modes/swr-cached-page' ;
80
- } ) ;
81
-
82
- // Only the 1. request creates a server transaction
83
- const serverTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
84
- return txnEvent . transaction ?. includes ( 'GET /rendering-modes/swr-cached-page' ) ?? false ;
85
- } ) ;
86
-
87
- const [ _1 , clientTxnEvent1 , serverTxnEvent1 ] = await Promise . all ( [
88
- page . goto ( `/rendering-modes/swr-cached-page` ) ,
89
- clientTxnEventPromise1 ,
90
- serverTxnEventPromise1 ,
91
- expect ( page . getByText ( `SWR Cached Page` , { exact : true } ) ) . toBeVisible ( ) ,
92
- ] ) ;
93
-
94
- await test . step ( 'No baggage and sentry-trace meta tags are present on first request' , async ( ) => {
95
- expect ( await page . locator ( 'meta[name="baggage"]' ) . count ( ) ) . toBe ( 0 ) ;
96
- expect ( await page . locator ( 'meta[name="sentry-trace"]' ) . count ( ) ) . toBe ( 0 ) ;
97
- } ) ;
98
-
99
- // === 2. Request ===
100
-
101
- await page . goto ( `/rendering-modes/swr-cached-page` ) ;
102
-
103
- const clientTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
104
- return txnEvent . transaction === '/rendering-modes/swr-cached-page' ;
105
- } ) ;
106
-
107
- let serverTxnEvent2 = undefined ;
108
- const serverTxnEventPromise2 = Promise . race ( [
109
- waitForTransaction ( 'nuxt-4' , txnEvent => {
110
- return txnEvent . transaction ?. includes ( 'GET /rendering-modes/swr-cached-page' ) ?? false ;
111
- } ) ,
112
- new Promise ( ( _ , reject ) => setTimeout ( ( ) => reject ( new Error ( 'No second server transaction expected' ) ) , 2000 ) ) ,
113
- ] ) ;
114
-
115
- try {
116
- serverTxnEvent2 = await serverTxnEventPromise2 ;
117
- throw new Error ( 'Second server transaction should not have been sent' ) ;
118
- } catch ( error ) {
119
- expect ( error . message ) . toBe ( 'No second server transaction expected' ) ;
120
- }
121
-
122
- const [ clientTxnEvent2 ] = await Promise . all ( [
123
- clientTxnEventPromise2 ,
124
- expect ( page . getByText ( `SWR Cached Page` , { exact : true } ) ) . toBeVisible ( ) ,
125
- ] ) ;
126
-
127
- const clientTxnEvent1TraceId = clientTxnEvent1 . contexts ?. trace ?. trace_id ;
128
- const clientTxnEvent2TraceId = clientTxnEvent2 . contexts ?. trace ?. trace_id ;
129
-
130
- const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
131
- const serverTxnEvent2TraceId = serverTxnEvent2 ?. contexts ?. trace ?. trace_id ;
132
-
133
- await test . step ( 'No baggage and sentry-trace meta tags are present on first request' , async ( ) => {
134
- expect ( await page . locator ( 'meta[name="baggage"]' ) . count ( ) ) . toBe ( 0 ) ;
135
- expect ( await page . locator ( 'meta[name="sentry-trace"]' ) . count ( ) ) . toBe ( 0 ) ;
136
- } ) ;
137
-
138
- await test . step ( 'First Server Transaction and all Client Transactions are defined' , ( ) => {
139
- expect ( serverTxnEvent1TraceId ) . toBeDefined ( ) ;
140
- expect ( clientTxnEvent1TraceId ) . toBeDefined ( ) ;
141
- expect ( clientTxnEvent2TraceId ) . toBeDefined ( ) ;
142
- expect ( serverTxnEvent2 ) . toBeUndefined ( ) ;
143
- expect ( serverTxnEvent2TraceId ) . toBeUndefined ( ) ;
144
- } ) ;
145
-
146
- await test . step ( 'Trace is not distributed' , ( ) => {
147
- // Cannot create distributed trace as HTML Meta Tags are not added (SWR caching leads to multiple usages of the same server trace id)
148
- expect ( clientTxnEvent1TraceId ) . not . toBe ( clientTxnEvent2TraceId ) ;
149
- expect ( clientTxnEvent1TraceId ) . not . toBe ( serverTxnEvent1TraceId ) ;
150
- } ) ;
74
+ await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/swr-cached-page' , 'SWR Cached Page' ) ;
151
75
} ) ;
152
76
153
77
test ( 'exclude tracing meta tags on pre-rendered page' , async ( { page } ) => {
154
- // === 1. Request ===
155
- const clientTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
156
- return txnEvent . transaction === '/rendering-modes/pre-rendered-page' ;
157
- } ) ;
158
-
159
- // Only the 1. request creates a server transaction
160
- const serverTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
161
- return txnEvent . transaction ?. includes ( 'GET /rendering-modes/pre-rendered-page' ) ?? false ;
162
- } ) ;
163
-
164
- const [ _1 , clientTxnEvent1 , serverTxnEvent1 ] = await Promise . all ( [
165
- page . goto ( `/rendering-modes/pre-rendered-page` ) ,
166
- clientTxnEventPromise1 ,
167
- serverTxnEventPromise1 ,
168
- expect ( page . getByText ( `Pre-Rendered Page` , { exact : true } ) ) . toBeVisible ( ) ,
169
- ] ) ;
170
-
171
- await test . step ( 'No baggage and sentry-trace meta tags are present on first request' , async ( ) => {
172
- expect ( await page . locator ( 'meta[name="baggage"]' ) . count ( ) ) . toBe ( 0 ) ;
173
- expect ( await page . locator ( 'meta[name="sentry-trace"]' ) . count ( ) ) . toBe ( 0 ) ;
174
- } ) ;
78
+ await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/pre-rendered-page' , 'Pre-Rendered Page' ) ;
79
+ } ) ;
175
80
176
- // === 2. Request ===
81
+ test ( 'exclude tracing meta tags on SWR 1h cached page' , async ( { page } ) => {
82
+ await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/swr-1h-cached-page' , 'SWR 1h Cached Page' ) ;
83
+ } ) ;
84
+ } ) ;
177
85
178
- await page . goto ( `/rendering-modes/pre-rendered-page` ) ;
86
+ /**
87
+ * Tests that tracing meta-tags are excluded on cached pages (SWR, pre-rendered, etc.)
88
+ * This utility handles the common pattern of:
89
+ * 1. Making two requests to a cached page
90
+ * 2. Verifying no tracing meta-tags are present
91
+ * 3. Verifying only the first request creates a server transaction
92
+ * 4. Verifying traces are not distributed
93
+ *
94
+ * @param page - Playwright page object
95
+ * @param routePath - The route path to test (e.g., '/rendering-modes/swr-cached-page')
96
+ * @param expectedPageText - The text to verify is visible on the page (e.g., 'SWR Cached Page')
97
+ * @returns Object containing transaction events for additional custom assertions
98
+ */
99
+ export async function testExcludeTracingMetaTagsOnCachedPage (
100
+ page : Page ,
101
+ routePath : string ,
102
+ expectedPageText : string ,
103
+ ) : Promise < void > {
104
+ // === 1. Request ===
105
+ const clientTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
106
+ return txnEvent . transaction === routePath ;
107
+ } ) ;
179
108
180
- const clientTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
181
- return txnEvent . transaction === '/rendering-modes/pre-rendered-page' ;
182
- } ) ;
109
+ // Only the 1. request creates a server transaction
110
+ const serverTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
111
+ return txnEvent . transaction ?. includes ( `GET ${ routePath } ` ) ?? false ;
112
+ } ) ;
183
113
184
- let serverTxnEvent2 = undefined ;
185
- const serverTxnEventPromise2 = Promise . race ( [
186
- waitForTransaction ( 'nuxt-4' , txnEvent => {
187
- return txnEvent . transaction ?. includes ( 'GET /rendering-modes/pre-rendered-page' ) ?? false ;
188
- } ) ,
189
- new Promise ( ( _ , reject ) => setTimeout ( ( ) => reject ( new Error ( 'No second server transaction expected' ) ) , 2000 ) ) ,
190
- ] ) ;
114
+ const [ _1 , clientTxnEvent1 , serverTxnEvent1 ] = await Promise . all ( [
115
+ page . goto ( routePath ) ,
116
+ clientTxnEventPromise1 ,
117
+ serverTxnEventPromise1 ,
118
+ expect ( page . getByText ( expectedPageText , { exact : true } ) ) . toBeVisible ( ) ,
119
+ ] ) ;
191
120
192
- try {
193
- serverTxnEvent2 = await serverTxnEventPromise2 ;
194
- throw new Error ( 'Second server transaction should not have been sent' ) ;
195
- } catch ( error ) {
196
- expect ( error . message ) . toBe ( 'No second server transaction expected' ) ;
197
- }
121
+ // Verify no baggage and sentry-trace meta-tags are present on first request
122
+ expect ( await page . locator ( 'meta[name="baggage"]' ) . count ( ) ) . toBe ( 0 ) ;
123
+ expect ( await page . locator ( 'meta[name="sentry-trace"]' ) . count ( ) ) . toBe ( 0 ) ;
198
124
199
- const [ clientTxnEvent2 ] = await Promise . all ( [
200
- clientTxnEventPromise2 ,
201
- expect ( page . getByText ( `Pre-Rendered Page` , { exact : true } ) ) . toBeVisible ( ) ,
202
- ] ) ;
125
+ // === 2. Request ===
203
126
204
- const clientTxnEvent1TraceId = clientTxnEvent1 . contexts ?. trace ?. trace_id ;
205
- const clientTxnEvent2TraceId = clientTxnEvent2 . contexts ?. trace ?. trace_id ;
127
+ await page . goto ( routePath ) ;
206
128
207
- const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
208
- const serverTxnEvent2TraceId = serverTxnEvent2 ?. contexts ?. trace ?. trace_id ;
129
+ const clientTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
130
+ return txnEvent . transaction === routePath ;
131
+ } ) ;
209
132
210
- await test . step ( 'No baggage and sentry-trace meta tags are present on first request' , async ( ) => {
211
- expect ( await page . locator ( 'meta[name="baggage"]' ) . count ( ) ) . toBe ( 0 ) ;
212
- expect ( await page . locator ( 'meta[name="sentry-trace"]' ) . count ( ) ) . toBe ( 0 ) ;
213
- } ) ;
133
+ let serverTxnEvent2 = undefined ;
134
+ const serverTxnEventPromise2 = Promise . race ( [
135
+ waitForTransaction ( 'nuxt-4' , txnEvent => {
136
+ return txnEvent . transaction ?. includes ( `GET ${ routePath } ` ) ?? false ;
137
+ } ) ,
138
+ new Promise ( ( _ , reject ) => setTimeout ( ( ) => reject ( new Error ( 'No second server transaction expected' ) ) , 2000 ) ) ,
139
+ ] ) ;
140
+
141
+ try {
142
+ serverTxnEvent2 = await serverTxnEventPromise2 ;
143
+ throw new Error ( 'Second server transaction should not have been sent' ) ;
144
+ } catch ( error ) {
145
+ expect ( error . message ) . toBe ( 'No second server transaction expected' ) ;
146
+ }
147
+
148
+ const [ clientTxnEvent2 ] = await Promise . all ( [
149
+ clientTxnEventPromise2 ,
150
+ expect ( page . getByText ( expectedPageText , { exact : true } ) ) . toBeVisible ( ) ,
151
+ ] ) ;
152
+
153
+ const clientTxnEvent1TraceId = clientTxnEvent1 . contexts ?. trace ?. trace_id ;
154
+ const clientTxnEvent2TraceId = clientTxnEvent2 . contexts ?. trace ?. trace_id ;
155
+
156
+ const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
157
+ const serverTxnEvent2TraceId = serverTxnEvent2 ?. contexts ?. trace ?. trace_id ;
158
+
159
+ await test . step ( 'No baggage and sentry-trace meta-tags are present on second request' , async ( ) => {
160
+ expect ( await page . locator ( 'meta[name="baggage"]' ) . count ( ) ) . toBe ( 0 ) ;
161
+ expect ( await page . locator ( 'meta[name="sentry-trace"]' ) . count ( ) ) . toBe ( 0 ) ;
162
+ } ) ;
214
163
215
- await test . step ( 'First Server Transaction and all Client Transactions are defined' , ( ) => {
216
- expect ( serverTxnEvent1TraceId ) . toBeDefined ( ) ;
217
- expect ( clientTxnEvent1TraceId ) . toBeDefined ( ) ;
218
- expect ( clientTxnEvent2TraceId ) . toBeDefined ( ) ;
219
- expect ( serverTxnEvent2 ) . toBeUndefined ( ) ;
220
- expect ( serverTxnEvent2TraceId ) . toBeUndefined ( ) ;
221
- } ) ;
164
+ await test . step ( '1. Server Transaction and all Client Transactions are defined' , ( ) => {
165
+ expect ( serverTxnEvent1TraceId ) . toBeDefined ( ) ;
166
+ expect ( clientTxnEvent1TraceId ) . toBeDefined ( ) ;
167
+ expect ( clientTxnEvent2TraceId ) . toBeDefined ( ) ;
168
+ expect ( serverTxnEvent2 ) . toBeUndefined ( ) ;
169
+ expect ( serverTxnEvent2TraceId ) . toBeUndefined ( ) ;
170
+ } ) ;
222
171
223
- await test . step ( 'Trace is not distributed' , ( ) => {
224
- // Cannot create distributed trace as HTML Meta Tags are not added (pre-rendering leads to multiple usages of the same server trace id)
225
- expect ( clientTxnEvent1TraceId ) . not . toBe ( clientTxnEvent2TraceId ) ;
226
- expect ( clientTxnEvent1TraceId ) . not . toBe ( serverTxnEvent1TraceId ) ;
227
- } ) ;
172
+ await test . step ( 'Trace is not distributed' , ( ) => {
173
+ // Cannot create distributed trace as HTML Meta Tags are not added (caching leads to multiple usages of the same server trace id)
174
+ expect ( clientTxnEvent1TraceId ) . not . toBe ( clientTxnEvent2TraceId ) ;
175
+ expect ( clientTxnEvent1TraceId ) . not . toBe ( serverTxnEvent1TraceId ) ;
228
176
} ) ;
229
- } ) ;
177
+ }
0 commit comments