Skip to content

Commit 56868e8

Browse files
authored
test(e2e): Add behaviour test for Transactions in standard React E2E tests application (#5912)
1 parent 8ef9995 commit 56868e8

File tree

3 files changed

+144
-25
lines changed

3 files changed

+144
-25
lines changed

packages/e2e-tests/run.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const PUBLISH_PACKAGES_DOCKER_IMAGE_NAME = 'publish-packages';
1414
const publishScriptNodeVersion = process.env.E2E_TEST_PUBLISH_SCRIPT_NODE_VERSION;
1515

1616
const DEFAULT_BUILD_TIMEOUT_SECONDS = 60 * 5;
17-
const DEFAULT_TEST_TIMEOUT_SECONDS = 60;
17+
const DEFAULT_TEST_TIMEOUT_SECONDS = 60 * 2;
1818

1919
if (!process.env.E2E_TEST_AUTH_TOKEN) {
2020
console.log(

packages/e2e-tests/test-applications/standard-frontend-react/tests/behaviour-test.spec.ts

Lines changed: 142 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import axios, { AxiosError } from 'axios';
44
const SENTRY_TEST_ORG_SLUG = 'sentry-sdks';
55
const 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

109
const 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
});

packages/e2e-tests/test-applications/standard-frontend-react/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
"noEmit": true,
1717
"jsx": "react"
1818
},
19-
"include": ["src"]
19+
"include": ["src", "tests"]
2020
}

0 commit comments

Comments
 (0)