@@ -2,86 +2,115 @@ import { expect, test, type Page } from '@playwright/test';
22import { waitForTransaction } from '@sentry-internal/test-utils' ;
33
44test . describe ( 'Rendering Modes with Cached HTML' , ( ) => {
5+ test ( 'changes tracing meta tags with multiple requests on Client-Side only page' , async ( { page } ) => {
6+ await testChangingTracingMetaTagsOnISRPage ( page , '/rendering-modes/client-side-only-page' , 'Client Side Only Page' ) ;
7+ } ) ;
8+
59 test ( 'changes tracing meta tags with multiple requests on ISR-cached page' , async ( { page } ) => {
6- // === 1. Request ===
7- const clientTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
8- return txnEvent . transaction === '/rendering-modes/isr-cached-page' ;
9- } ) ;
10+ await testChangingTracingMetaTagsOnISRPage ( page , '/rendering-modes/isr-cached-page' , 'ISR Cached Page' ) ;
11+ } ) ;
1012
11- const serverTxnEventPromise1 = waitForTransaction ( 'nuxt-4 ', txnEvent => {
12- return txnEvent . transaction ?. includes ( 'GET /rendering-modes/isr-cached-page') ?? false ;
13- } ) ;
13+ test ( 'changes tracing meta tags with multiple requests on 1h ISR-cached page ', async ( { page } ) => {
14+ await testChangingTracingMetaTagsOnISRPage ( page , ' /rendering-modes/isr-1h- cached-page', 'ISR 1h Cached Page' ) ;
15+ } ) ;
1416
15- const [ _1 , clientTxnEvent1 , serverTxnEvent1 ] = await Promise . all ( [
16- page . goto ( `/rendering-modes/isr-cached-page` ) ,
17- clientTxnEventPromise1 ,
18- serverTxnEventPromise1 ,
19- expect ( page . getByText ( `ISR Cached Page` , { exact : true } ) ) . toBeVisible ( ) ,
20- ] ) ;
17+ test ( 'exclude tracing meta tags on SWR-cached page' , async ( { page } ) => {
18+ await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/swr-cached-page' , 'SWR Cached Page' ) ;
19+ } ) ;
2120
22- const baggageMetaTagContent1 = await page . locator ( 'meta[name="baggage"]' ) . getAttribute ( 'content' ) ;
23- const sentryTraceMetaTagContent1 = await page . locator ( 'meta[name="sentry-trace"]' ) . getAttribute ( 'content ') ;
24- const [ htmlMetaTraceId1 ] = sentryTraceMetaTagContent1 ?. split ( '-' ) || [ ] ;
21+ test ( 'exclude tracing meta tags on SWR 1h cached page' , async ( { page } ) => {
22+ await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/swr-1h-cached-page' , 'SWR 1h Cached Page ') ;
23+ } ) ;
2524
26- // === 2. Request ===
25+ test ( 'exclude tracing meta tags on pre-rendered page' , async ( { page } ) => {
26+ await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/pre-rendered-page' , 'Pre-Rendered Page' ) ;
27+ } ) ;
28+ } ) ;
2729
28- const clientTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
29- return txnEvent . transaction === '/rendering-modes/isr-cached-page' ;
30- } ) ;
30+ /**
31+ * Tests that tracing meta-tags change with multiple requests on ISR-cached pages
32+ * This utility handles the common pattern of:
33+ * 1. Making two requests to an ISR-cached page
34+ * 2. Verifying tracing meta-tags are present and change between requests
35+ * 3. Verifying distributed tracing works correctly for both requests
36+ * 4. Verifying trace IDs are different between requests
37+ *
38+ * @param page - Playwright page object
39+ * @param routePath - The route path to test (e.g., '/rendering-modes/isr-cached-page')
40+ * @param expectedPageText - The text to verify is visible on the page (e.g., 'ISR Cached Page')
41+ */
42+ export async function testChangingTracingMetaTagsOnISRPage (
43+ page : Page ,
44+ routePath : string ,
45+ expectedPageText : string ,
46+ ) : Promise < void > {
47+ // === 1. Request ===
48+ const clientTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
49+ return txnEvent . transaction === routePath ;
50+ } ) ;
3151
32- const serverTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
33- return txnEvent . transaction ?. includes ( ' GET /rendering-modes/isr-cached-page' ) ?? false ;
34- } ) ;
52+ const serverTxnEventPromise1 = waitForTransaction ( 'nuxt-4' , txnEvent => {
53+ return txnEvent . transaction ?. includes ( ` GET ${ routePath } ` ) ?? false ;
54+ } ) ;
3555
36- const [ _2 , clientTxnEvent2 , serverTxnEvent2 ] = await Promise . all ( [
37- page . goto ( `/rendering-modes/isr-cached-page` ) ,
38- clientTxnEventPromise2 ,
39- serverTxnEventPromise2 ,
40- expect ( page . getByText ( `ISR Cached Page` , { exact : true } ) ) . toBeVisible ( ) ,
41- ] ) ;
56+ const [ _1 , clientTxnEvent1 , serverTxnEvent1 ] = await Promise . all ( [
57+ page . goto ( routePath ) ,
58+ clientTxnEventPromise1 ,
59+ serverTxnEventPromise1 ,
60+ expect ( page . getByText ( expectedPageText , { exact : true } ) ) . toBeVisible ( ) ,
61+ ] ) ;
4262
43- const baggageMetaTagContent2 = await page . locator ( 'meta[name="baggage"]' ) . getAttribute ( 'content' ) ;
44- const sentryTraceMetaTagContent2 = await page . locator ( 'meta[name="sentry-trace"]' ) . getAttribute ( 'content' ) ;
45- const [ htmlMetaTraceId2 ] = sentryTraceMetaTagContent2 ?. split ( '-' ) || [ ] ;
63+ const baggageMetaTagContent1 = await page . locator ( 'meta[name="baggage"]' ) . getAttribute ( 'content' ) ;
64+ const sentryTraceMetaTagContent1 = await page . locator ( 'meta[name="sentry-trace"]' ) . getAttribute ( 'content' ) ;
65+ const [ htmlMetaTraceId1 ] = sentryTraceMetaTagContent1 ?. split ( '-' ) || [ ] ;
4666
47- const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
48- const serverTxnEvent2TraceId = serverTxnEvent2 . contexts ?. trace ?. trace_id ;
67+ // === 2. Request ===
4968
50- await test . step ( 'Test distributed trace from 1. request' , ( ) => {
51- expect ( baggageMetaTagContent1 ) . toContain ( `sentry-trace_id=${ serverTxnEvent1TraceId } ` ) ;
69+ const clientTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
70+ return txnEvent . transaction === routePath ;
71+ } ) ;
5272
53- expect ( clientTxnEvent1 . contexts ?. trace ?. trace_id ) . toBe ( serverTxnEvent1TraceId ) ;
54- expect ( clientTxnEvent1 . contexts ?. trace ?. parent_span_id ) . toBe ( serverTxnEvent1 . contexts ?. trace ?. span_id ) ;
55- expect ( serverTxnEvent1 . contexts ?. trace ?. trace_id ) . toBe ( htmlMetaTraceId1 ) ;
56- } ) ;
73+ const serverTxnEventPromise2 = waitForTransaction ( 'nuxt-4' , txnEvent => {
74+ return txnEvent . transaction ?. includes ( `GET ${ routePath } ` ) ?? false ;
75+ } ) ;
5776
58- await test . step ( 'Test distributed trace from 2. request' , ( ) => {
59- expect ( baggageMetaTagContent2 ) . toContain ( `sentry-trace_id=${ serverTxnEvent2TraceId } ` ) ;
77+ const [ _2 , clientTxnEvent2 , serverTxnEvent2 ] = await Promise . all ( [
78+ page . goto ( routePath ) ,
79+ clientTxnEventPromise2 ,
80+ serverTxnEventPromise2 ,
81+ expect ( page . getByText ( expectedPageText , { exact : true } ) ) . toBeVisible ( ) ,
82+ ] ) ;
6083
61- expect ( clientTxnEvent2 . contexts ?. trace ?. trace_id ) . toBe ( serverTxnEvent2TraceId ) ;
62- expect ( clientTxnEvent2 . contexts ?. trace ?. parent_span_id ) . toBe ( serverTxnEvent2 . contexts ?. trace ?. span_id ) ;
63- expect ( serverTxnEvent2 . contexts ?. trace ?. trace_id ) . toBe ( htmlMetaTraceId2 ) ;
64- } ) ;
84+ const baggageMetaTagContent2 = await page . locator ( 'meta[name="baggage"]' ) . getAttribute ( 'content' ) ;
85+ const sentryTraceMetaTagContent2 = await page . locator ( 'meta[name="sentry-trace"]' ) . getAttribute ( 'content' ) ;
86+ const [ htmlMetaTraceId2 ] = sentryTraceMetaTagContent2 ?. split ( '-' ) || [ ] ;
6587
66- await test . step ( 'Test that trace IDs from subsequent requests are different' , ( ) => {
67- // Different trace IDs for the server transactions
68- expect ( serverTxnEvent1TraceId ) . not . toBe ( serverTxnEvent2TraceId ) ;
69- expect ( serverTxnEvent1TraceId ) . not . toBe ( htmlMetaTraceId2 ) ;
70- } ) ;
71- } ) ;
88+ const serverTxnEvent1TraceId = serverTxnEvent1 . contexts ?. trace ?. trace_id ;
89+ const serverTxnEvent2TraceId = serverTxnEvent2 . contexts ?. trace ?. trace_id ;
7290
73- test ( 'exclude tracing meta tags on SWR-cached page' , async ( { page } ) => {
74- await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/swr-cached-page' , 'SWR Cached Page' ) ;
91+ await test . step ( 'Test distributed trace from 1. request' , ( ) => {
92+ expect ( baggageMetaTagContent1 ) . toContain ( `sentry-trace_id=${ serverTxnEvent1TraceId } ` ) ;
93+
94+ expect ( clientTxnEvent1 . contexts ?. trace ?. trace_id ) . toBe ( serverTxnEvent1TraceId ) ;
95+ expect ( clientTxnEvent1 . contexts ?. trace ?. parent_span_id ) . toBe ( serverTxnEvent1 . contexts ?. trace ?. span_id ) ;
96+ expect ( serverTxnEvent1 . contexts ?. trace ?. trace_id ) . toBe ( htmlMetaTraceId1 ) ;
7597 } ) ;
7698
77- test ( 'exclude tracing meta tags on pre-rendered page' , async ( { page } ) => {
78- await testExcludeTracingMetaTagsOnCachedPage ( page , '/rendering-modes/pre-rendered-page' , 'Pre-Rendered Page' ) ;
99+ await test . step ( 'Test distributed trace from 2. request' , ( ) => {
100+ expect ( baggageMetaTagContent2 ) . toContain ( `sentry-trace_id=${ serverTxnEvent2TraceId } ` ) ;
101+
102+ expect ( clientTxnEvent2 . contexts ?. trace ?. trace_id ) . toBe ( serverTxnEvent2TraceId ) ;
103+ expect ( clientTxnEvent2 . contexts ?. trace ?. parent_span_id ) . toBe ( serverTxnEvent2 . contexts ?. trace ?. span_id ) ;
104+ expect ( serverTxnEvent2 . contexts ?. trace ?. trace_id ) . toBe ( htmlMetaTraceId2 ) ;
79105 } ) ;
80106
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' ) ;
107+ await test . step ( 'Test that trace IDs from subsequent requests are different' , ( ) => {
108+ // Different trace IDs for the server transactions
109+ expect ( serverTxnEvent1TraceId ) . toBeDefined ( ) ;
110+ expect ( serverTxnEvent1TraceId ) . not . toBe ( serverTxnEvent2TraceId ) ;
111+ expect ( serverTxnEvent1TraceId ) . not . toBe ( htmlMetaTraceId2 ) ;
83112 } ) ;
84- } ) ;
113+ }
85114
86115/**
87116 * Tests that tracing meta-tags are excluded on cached pages (SWR, pre-rendered, etc.)
0 commit comments