11import { expect , test } from '@playwright/test' ;
2- import {
3- getSpanOp ,
4- waitForError ,
5- waitForRequest ,
6- waitForStreamedSpan ,
7- waitForStreamedSpans ,
8- } from '@sentry-internal/test-utils' ;
2+ import { waitForError , waitForRequest , waitForTransaction } from '@sentry-internal/test-utils' ;
93import { SDK_VERSION } from '@sentry/cloudflare' ;
104import { WebSocket } from 'ws' ;
115
@@ -15,21 +9,8 @@ test('Index page', async ({ baseURL }) => {
159 await expect ( result . text ( ) ) . resolves . toBe ( 'Hello World!' ) ;
1610} ) ;
1711
18- test ( 'Sends a streamed span for a basic request' , async ( { baseURL } ) => {
19- const spanPromise = waitForStreamedSpan ( 'cloudflare-workers-streaming' , span => {
20- return getSpanOp ( span ) === 'http.server' && span . is_segment ;
21- } ) ;
22-
23- await fetch ( baseURL ! ) ;
24-
25- const span = await spanPromise ;
26-
27- expect ( span . trace_id ) . toMatch ( / [ a - f 0 - 9 ] { 32 } / ) ;
28- expect ( span . status ) . toBe ( 'ok' ) ;
29- } ) ;
30-
3112test ( "worker's withSentry" , async ( { baseURL } ) => {
32- const eventWaiter = waitForError ( 'cloudflare-workers-streaming ' , event => {
13+ const eventWaiter = waitForError ( 'cloudflare-workers-static ' , event => {
3314 return event . exception ?. values ?. [ 0 ] ?. mechanism ?. type === 'auto.http.cloudflare' ;
3415 } ) ;
3516 const response = await fetch ( `${ baseURL } /throwException` ) ;
@@ -39,7 +20,7 @@ test("worker's withSentry", async ({ baseURL }) => {
3920} ) ;
4021
4122test ( 'RPC method which throws an exception to be logged to sentry' , async ( { baseURL } ) => {
42- const eventWaiter = waitForError ( 'cloudflare-workers-streaming ' , event => {
23+ const eventWaiter = waitForError ( 'cloudflare-workers-static ' , event => {
4324 return event . exception ?. values ?. [ 0 ] ?. mechanism ?. type === 'auto.faas.cloudflare.durable_object' ;
4425 } ) ;
4526 const response = await fetch ( `${ baseURL } /rpc/throwException` ) ;
@@ -49,7 +30,7 @@ test('RPC method which throws an exception to be logged to sentry', async ({ bas
4930} ) ;
5031
5132test ( "Request processed by DurableObject's fetch is recorded" , async ( { baseURL } ) => {
52- const eventWaiter = waitForError ( 'cloudflare-workers-streaming ' , event => {
33+ const eventWaiter = waitForError ( 'cloudflare-workers-static ' , event => {
5334 return event . exception ?. values ?. [ 0 ] ?. mechanism ?. type === 'auto.faas.cloudflare.durable_object' ;
5435 } ) ;
5536 const response = await fetch ( `${ baseURL } /pass-to-object/throwException` ) ;
@@ -59,7 +40,7 @@ test("Request processed by DurableObject's fetch is recorded", async ({ baseURL
5940} ) ;
6041
6142test ( 'Websocket.webSocketMessage' , async ( { baseURL } ) => {
62- const eventWaiter = waitForError ( 'cloudflare-workers-streaming ' , event => {
43+ const eventWaiter = waitForError ( 'cloudflare-workers-static ' , event => {
6344 return ! ! event . exception ?. values ?. [ 0 ] ;
6445 } ) ;
6546 const url = new URL ( '/pass-to-object/ws' , baseURL ) ;
@@ -75,7 +56,7 @@ test('Websocket.webSocketMessage', async ({ baseURL }) => {
7556} ) ;
7657
7758test ( 'Websocket.webSocketClose' , async ( { baseURL } ) => {
78- const eventWaiter = waitForError ( 'cloudflare-workers-streaming ' , event => {
59+ const eventWaiter = waitForError ( 'cloudflare-workers-static ' , event => {
7960 return ! ! event . exception ?. values ?. [ 0 ] ;
8061 } ) ;
8162 const url = new URL ( '/pass-to-object/ws' , baseURL ) ;
@@ -91,38 +72,37 @@ test('Websocket.webSocketClose', async ({ baseURL }) => {
9172} ) ;
9273
9374test ( 'sends user-agent header with SDK name and version in envelope requests' , async ( { baseURL } ) => {
94- const requestPromise = waitForRequest ( 'cloudflare-workers-streaming ' , ( ) => true ) ;
75+ const requestPromise = waitForRequest ( 'cloudflare-workers-static ' , ( ) => true ) ;
9576
9677 await fetch ( `${ baseURL } /throwException` ) ;
9778
9879 const request = await requestPromise ;
9980
100- expect ( request . rawProxyRequestHeaders ) . toMatchObject ( {
101- 'user-agent' : `sentry.javascript.cloudflare/${ SDK_VERSION } ` ,
102- } ) ;
81+ expect ( request . rawProxyRequestHeaders [ 'user-agent' ] ) . toBe ( `sentry.javascript.cloudflare/${ SDK_VERSION } ` ) ;
10382} ) ;
10483
105- test ( 'Storage operations create spans in Durable Object' , async ( { baseURL } ) => {
106- const spansPromise = waitForStreamedSpans ( 'cloudflare-workers-streaming ' , spans => {
107- return spans . some ( span => span . name === 'durable_object_storage_put ' && getSpanOp ( span ) === 'db' ) ;
84+ test ( 'Storage operations create spans in Durable Object transactions ' , async ( { baseURL } ) => {
85+ const transactionWaiter = waitForTransaction ( 'cloudflare-workers-static ' , event => {
86+ return event . spans ? .some ( span => span . op === 'db ' && span . description === 'durable_object_storage_put' ) ?? false ;
10887 } ) ;
10988
11089 const response = await fetch ( `${ baseURL } /pass-to-object/storage/put` ) ;
11190 expect ( response . status ) . toBe ( 200 ) ;
11291
113- const spans = await spansPromise ;
114- const putSpan = spans . find ( span => span . name === 'durable_object_storage_put' && getSpanOp ( span ) === 'db ') ;
92+ const transaction = await transactionWaiter ;
93+ const putSpan = transaction . spans ? .find ( span => span . description === 'durable_object_storage_put' ) ;
11594
11695 expect ( putSpan ) . toBeDefined ( ) ;
117- expect ( putSpan ?. attributes [ 'db.system.name' ] ?. value ) . toBe ( 'cloudflare.durable_object.storage' ) ;
118- expect ( putSpan ?. attributes [ 'db.operation.name' ] ?. value ) . toBe ( 'put' ) ;
96+ expect ( putSpan ?. op ) . toBe ( 'db' ) ;
97+ expect ( putSpan ?. data ?. [ 'db.system.name' ] ) . toBe ( 'cloudflare.durable_object.storage' ) ;
98+ expect ( putSpan ?. data ?. [ 'db.operation.name' ] ) . toBe ( 'put' ) ;
11999} ) ;
120100
121101test . describe ( 'Alarm instrumentation' , ( ) => {
122102 test . describe . configure ( { mode : 'serial' } ) ;
123103
124104 test ( 'captures error from alarm handler' , async ( { baseURL } ) => {
125- const errorWaiter = waitForError ( 'cloudflare-workers-streaming ' , event => {
105+ const errorWaiter = waitForError ( 'cloudflare-workers-static ' , event => {
126106 return event . exception ?. values ?. [ 0 ] ?. value === 'Alarm error captured by Sentry' ;
127107 } ) ;
128108
@@ -133,31 +113,31 @@ test.describe('Alarm instrumentation', () => {
133113 expect ( event . exception ?. values ?. [ 0 ] ?. mechanism ?. type ) . toBe ( 'auto.faas.cloudflare.durable_object' ) ;
134114 } ) ;
135115
136- test ( 'creates a streamed span for alarm with new trace linked to setAlarm' , async ( { baseURL } ) => {
137- const setAlarmSpanPromise = waitForStreamedSpan ( 'cloudflare-workers-streaming ' , span => {
138- return span . name === 'durable_object_storage_setAlarm' && span . is_segment === false ;
116+ test ( 'creates a transaction for alarm with new trace linked to setAlarm' , async ( { baseURL } ) => {
117+ const setAlarmTransactionWaiter = waitForTransaction ( 'cloudflare-workers-static ' , event => {
118+ return event . spans ?. some ( span => span . description ?. includes ( 'storage_setAlarm' ) ) ?? false ;
139119 } ) ;
140120
141- const alarmSpanPromise = waitForStreamedSpan ( 'cloudflare-workers-streaming ' , span => {
142- return span . name === 'alarm' && getSpanOp ( span ) === 'function' && span . is_segment ;
121+ const alarmTransactionWaiter = waitForTransaction ( 'cloudflare-workers-static ' , event => {
122+ return event . transaction === 'alarm' && event . contexts ?. trace ?. op === 'function' ;
143123 } ) ;
144124
145125 const response = await fetch ( `${ baseURL } /pass-to-object/setAlarm` ) ;
146126 expect ( response . status ) . toBe ( 200 ) ;
147127
148- const setAlarmSpan = await setAlarmSpanPromise ;
149- const alarmSpan = await alarmSpanPromise ;
128+ const setAlarmTransaction = await setAlarmTransactionWaiter ;
129+ const alarmTransaction = await alarmTransactionWaiter ;
150130
151- // Alarm creates a streamed span with correct attributes
152- expect ( getSpanOp ( alarmSpan ) ) . toBe ( 'function' ) ;
153- expect ( alarmSpan . attributes [ 'sentry.origin' ] ?. value ) . toBe ( 'auto.faas.cloudflare.durable_object' ) ;
131+ // Alarm creates a transaction with correct attributes
132+ expect ( alarmTransaction . contexts ?. trace ?. op ) . toBe ( 'function' ) ;
133+ expect ( alarmTransaction . contexts ?. trace ?. origin ) . toBe ( 'auto.faas.cloudflare.durable_object' ) ;
154134
155135 // Alarm starts a new trace (different trace ID from the request that called setAlarm)
156- expect ( alarmSpan . trace_id ) . not . toBe ( setAlarmSpan . trace_id ) ;
136+ expect ( alarmTransaction . contexts ?. trace ?. trace_id ) . not . toBe ( setAlarmTransaction . contexts ?. trace ? .trace_id ) ;
157137
158138 // Alarm links to the trace that called setAlarm via sentry.previous_trace attribute
159- const previousTrace = alarmSpan . attributes [ 'sentry.previous_trace' ] ?. value ;
139+ const previousTrace = alarmTransaction . contexts ?. trace ?. data ?. [ 'sentry.previous_trace' ] ;
160140 expect ( previousTrace ) . toBeDefined ( ) ;
161- expect ( previousTrace ) . toContain ( setAlarmSpan . trace_id ) ;
141+ expect ( previousTrace ) . toContain ( setAlarmTransaction . contexts ?. trace ? .trace_id ) ;
162142 } ) ;
163143} ) ;
0 commit comments