@@ -4,8 +4,7 @@ import axios, { AxiosError } from 'axios';
4
4
const SENTRY_TEST_ORG_SLUG = 'sentry-sdks' ;
5
5
const SENTRY_TEST_PROJECT = 'sentry-javascript-e2e-tests' ;
6
6
7
- const EVENT_POLLING_TIMEOUT = 45000 ;
8
- const EVENT_POLLING_RETRY_INTERVAL = 1000 ;
7
+ const EVENT_POLLING_TIMEOUT = 30_000 ;
9
8
10
9
const authToken = process . env . E2E_TEST_AUTH_TOKEN ;
11
10
@@ -18,30 +17,150 @@ test('Sends an exception to Sentry', async ({ page }) => {
18
17
const exceptionIdHandle = await page . waitForFunction ( ( ) => window . capturedExceptionId ) ;
19
18
const exceptionEventId = await exceptionIdHandle . jsonValue ( ) ;
20
19
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 ( '/' ) ;
22
50
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 ;
28
54
} else {
29
- throw new Error ( 'Timeout reached while polling event.' ) ;
55
+ return undefined ;
30
56
}
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 ;
45
119
}
120
+ } ) ;
121
+ const recordedTransactionEventIds = await recordedTransactionsHandle . jsonValue ( ) ;
122
+
123
+ if ( recordedTransactionEventIds === undefined ) {
124
+ throw new Error ( "Application didn't record any transaction event IDs." ) ;
46
125
}
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 ) ;
47
166
} ) ;
0 commit comments