1- import { expect , test } from '@playwright/test' ;
1+ import { expect , test , type Page } from '@playwright/test' ;
22import { waitForTransaction } from '@sentry-internal/test-utils' ;
33
44test . describe ( 'Rendering Modes with Cached HTML' , ( ) => {
@@ -47,9 +47,6 @@ test.describe('Rendering Modes with Cached HTML', () => {
4747 const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
4848 const serverTxnEvent2TraceId = serverTxnEvent2 . contexts ?. trace ?. trace_id ;
4949
50- console . log ( 'Server Transaction 1:' , serverTxnEvent1TraceId ) ;
51- console . log ( 'Server Transaction 2:' , serverTxnEvent2TraceId ) ;
52-
5350 await test . step ( 'Test distributed trace from 1. request' , ( ) => {
5451 expect ( baggageMetaTagContent1 ) . toContain ( `sentry-trace_id=${ serverTxnEvent1TraceId } ` ) ;
5552
@@ -74,156 +71,107 @@ test.describe('Rendering Modes with Cached HTML', () => {
7471 } ) ;
7572
7673 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' ) ;
15175 } ) ;
15276
15377 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+ } ) ;
17580
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+ } ) ;
17785
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+ } ) ;
179108
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+ } ) ;
183113
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+ ] ) ;
191120
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 ) ;
198124
199- const [ clientTxnEvent2 ] = await Promise . all ( [
200- clientTxnEventPromise2 ,
201- expect ( page . getByText ( `Pre-Rendered Page` , { exact : true } ) ) . toBeVisible ( ) ,
202- ] ) ;
125+ // === 2. Request ===
203126
204- const clientTxnEvent1TraceId = clientTxnEvent1 . contexts ?. trace ?. trace_id ;
205- const clientTxnEvent2TraceId = clientTxnEvent2 . contexts ?. trace ?. trace_id ;
127+ await page . goto ( routePath ) ;
206128
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+ } ) ;
209132
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+ } ) ;
214163
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+ } ) ;
222171
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 ) ;
228176 } ) ;
229- } ) ;
177+ }
0 commit comments