@@ -4,8 +4,7 @@ import axios, { AxiosError } from 'axios';
44const SENTRY_TEST_ORG_SLUG = 'sentry-sdks' ;
55const SENTRY_TEST_PROJECT = 'sentry-javascript-e2e-tests' ;
66
7- const EVENT_POLLING_TIMEOUT = 45000 ;
8- const EVENT_POLLING_RETRY_INTERVAL = 1000 ;
7+ const EVENT_POLLING_TIMEOUT = 30_000 ;
98
109const authToken = process . env . E2E_TEST_AUTH_TOKEN ;
1110
@@ -18,30 +17,150 @@ test('Sends an exception to Sentry', async ({ page }) => {
1817 const exceptionIdHandle = await page . waitForFunction ( ( ) => window . capturedExceptionId ) ;
1918 const exceptionEventId = await exceptionIdHandle . jsonValue ( ) ;
2019
21- let lastErrorResponse : AxiosError | undefined ;
20+ await expect
21+ . poll (
22+ async ( ) => {
23+ try {
24+ const response = await axios . get (
25+ `https://sentry.io/api/0/projects/${ SENTRY_TEST_ORG_SLUG } /${ SENTRY_TEST_PROJECT } /events/${ exceptionEventId } /` ,
26+ { headers : { Authorization : `Bearer ${ authToken } ` } } ,
27+ ) ;
28+ return response . status ;
29+ } catch ( e ) {
30+ if ( e instanceof AxiosError && e . response ) {
31+ if ( e . response . status !== 404 ) {
32+ throw e ;
33+ } else {
34+ return e . response . status ;
35+ }
36+ } else {
37+ throw e ;
38+ }
39+ }
40+ } ,
41+ {
42+ timeout : EVENT_POLLING_TIMEOUT ,
43+ } ,
44+ )
45+ . toBe ( 200 ) ;
46+ } ) ;
47+
48+ test ( 'Sends a pageload transaction to Sentry' , async ( { page } ) => {
49+ await page . goto ( '/' ) ;
2250
23- const timeout = setTimeout ( ( ) => {
24- if ( lastErrorResponse ?. response ?. status ) {
25- throw new Error (
26- `Timeout reached while polling event. Last received status code: ${ lastErrorResponse . response . status } ` ,
27- ) ;
51+ const recordedTransactionsHandle = await page . waitForFunction ( ( ) => {
52+ if ( window . recordedTransactions && window . recordedTransactions ?. length >= 1 ) {
53+ return window . recordedTransactions ;
2854 } else {
29- throw new Error ( 'Timeout reached while polling event.' ) ;
55+ return undefined ;
3056 }
31- } , EVENT_POLLING_TIMEOUT ) ;
32-
33- while ( true ) {
34- try {
35- const response = await axios . get (
36- `https://sentry.io/api/0/projects/${ SENTRY_TEST_ORG_SLUG } /${ SENTRY_TEST_PROJECT } /events/${ exceptionEventId } /` ,
37- { headers : { Authorization : `Bearer ${ authToken } ` } } ,
38- ) ;
39- clearTimeout ( timeout ) ;
40- expect ( response ?. status ) . toBe ( 200 ) ;
41- break ;
42- } catch ( e ) {
43- lastErrorResponse = e ;
44- await new Promise ( resolve => setTimeout ( resolve , EVENT_POLLING_RETRY_INTERVAL ) ) ;
57+ } ) ;
58+ const recordedTransactionEventIds = await recordedTransactionsHandle . jsonValue ( ) ;
59+
60+ if ( recordedTransactionEventIds === undefined ) {
61+ throw new Error ( "Application didn't record any transaction event IDs." ) ;
62+ }
63+
64+ let hadPageLoadTransaction = false ;
65+
66+ await Promise . all (
67+ recordedTransactionEventIds . map ( async transactionEventId => {
68+ await expect
69+ . poll (
70+ async ( ) => {
71+ try {
72+ const response = await axios . get (
73+ `https://sentry.io/api/0/projects/${ SENTRY_TEST_ORG_SLUG } /${ SENTRY_TEST_PROJECT } /events/${ transactionEventId } /` ,
74+ { headers : { Authorization : `Bearer ${ authToken } ` } } ,
75+ ) ;
76+
77+ if ( response . data . contexts . trace . op === 'pageload' ) {
78+ hadPageLoadTransaction = true ;
79+ }
80+
81+ return response . status ;
82+ } catch ( e ) {
83+ if ( e instanceof AxiosError && e . response ) {
84+ if ( e . response . status !== 404 ) {
85+ throw e ;
86+ } else {
87+ return e . response . status ;
88+ }
89+ } else {
90+ throw e ;
91+ }
92+ }
93+ } ,
94+ {
95+ timeout : EVENT_POLLING_TIMEOUT ,
96+ } ,
97+ )
98+ . toBe ( 200 ) ;
99+ } ) ,
100+ ) ;
101+
102+ expect ( hadPageLoadTransaction ) . toBe ( true ) ;
103+ } ) ;
104+
105+ test ( 'Sends a navigation transaction to Sentry' , async ( { page } ) => {
106+ await page . goto ( '/' ) ;
107+
108+ // Give pageload transaction time to finish
109+ page . waitForTimeout ( 4000 ) ;
110+
111+ const linkElement = page . locator ( 'id=navigation' ) ;
112+ await linkElement . click ( ) ;
113+
114+ const recordedTransactionsHandle = await page . waitForFunction ( ( ) => {
115+ if ( window . recordedTransactions && window . recordedTransactions ?. length >= 2 ) {
116+ return window . recordedTransactions ;
117+ } else {
118+ return undefined ;
45119 }
120+ } ) ;
121+ const recordedTransactionEventIds = await recordedTransactionsHandle . jsonValue ( ) ;
122+
123+ if ( recordedTransactionEventIds === undefined ) {
124+ throw new Error ( "Application didn't record any transaction event IDs." ) ;
46125 }
126+
127+ let hadPageNavigationTransaction = false ;
128+
129+ await Promise . all (
130+ recordedTransactionEventIds . map ( async transactionEventId => {
131+ await expect
132+ . poll (
133+ async ( ) => {
134+ try {
135+ const response = await axios . get (
136+ `https://sentry.io/api/0/projects/${ SENTRY_TEST_ORG_SLUG } /${ SENTRY_TEST_PROJECT } /events/${ transactionEventId } /` ,
137+ { headers : { Authorization : `Bearer ${ authToken } ` } } ,
138+ ) ;
139+
140+ if ( response . data . contexts . trace . op === 'navigation' ) {
141+ hadPageNavigationTransaction = true ;
142+ }
143+
144+ return response . status ;
145+ } catch ( e ) {
146+ if ( e instanceof AxiosError && e . response ) {
147+ if ( e . response . status !== 404 ) {
148+ throw e ;
149+ } else {
150+ return e . response . status ;
151+ }
152+ } else {
153+ throw e ;
154+ }
155+ }
156+ } ,
157+ {
158+ timeout : EVENT_POLLING_TIMEOUT ,
159+ } ,
160+ )
161+ . toBe ( 200 ) ;
162+ } ) ,
163+ ) ;
164+
165+ expect ( hadPageNavigationTransaction ) . toBe ( true ) ;
47166} ) ;
0 commit comments