8000 test(e2e): Fix node E2E test app (#11682) · mcous/sentry-javascript@c45f82a · GitHub
[go: up one dir, main page]

Skip to content

Commit c45f82a

Browse files
authored
test(e2e): Fix node E2E test app (getsentry#11682)
While looking into how we send trace context for error events (today: We only send `trace_id`, `span_id` and `parent_span_id` for errors, while we send everything for transactions. In browser, we always send everything...) I noticed that we don't cover this well for express today. Digging into this, I figured the tests was actually pretty broken, because we didn't have the right import order, so instrumentation was not fully correct 😬 so I split the node-express E2E tests into multiple files, added a test to check the error event shape, and fixed the app setup.
1 parent d943cce commit c45f82a

File tree

5 files changed

+281
-231
lines changed

5 files changed

+281
-231
lines changed

dev-packages/e2e-tests/test-applications/node-express-app/src/app.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
import * as Sentry from '@sentry/node';
2-
import { TRPCError, initTRPC } from '@trpc/server';
3-
import * as trpcExpress from '@trpc/server/adapters/express';
4-
import express from 'express';
5-
import { z } from 'zod';
62

73
declare global {
84
namespace globalThis {
@@ -19,6 +15,11 @@ Sentry.init({
1915
tracesSampleRate: 1,
2016
});
2117

18+
import { TRPCError, initTRPC } from '@trpc/server';
19+
import * as trpcExpress from '@trpc/server/adapters/express';
20+
import express from 'express';
21+
import { z } from 'zod';
22+
2223
const app = express();
2324
const port = 3030;
2425

@@ -52,6 +53,10 @@ app.get('/test-error', async function (req, res) {
5253
res.send({ exceptionId });
5354
});
5455

56+
app.get('/test-exception/:id', function (req, _res) {
57+
throw new Error(`This is an exception with id ${req.params.id}`);
58+
});
59+
5560
app.get('/test-local-variables-uncaught', function (req, res) {
5661
const randomVariableToRecord = Math.random();
5762
throw new Error(`Uncaught Local Variable Error - ${JSON.stringify({ randomVariableToRecord })}`);
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForError } from '@sentry-internal/event-proxy-server';
3+
import axios, { AxiosError, AxiosResponse } from 'axios';
4+
5+
const authToken = process.env.E2E_TEST_AUTH_TOKEN;
6+
const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG;
7+
const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT;
8+
const EVENT_POLLING_TIMEOUT = 90_000;
9+
10+
test('Sends exception to Sentry', async ({ baseURL }) => {
11+
const { data } = await axios.get(`${baseURL}/test-error`);
12+
const { exceptionId } = data;
13+
14+
const url = `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${exceptionId}/`;
15+
16+
console.log(`Polling for error eventId: ${exceptionId}`);
17+
18+
await expect
19+
.poll(
20+
async () => {
21+
try {
22+
const response = await axios.get(url, { headers: { Authorization: `Bearer ${authToken}` } });
23+
24+
return response.status;
25+
} catch (e) {
26+
if (e instanceof AxiosError && e.response) {
27+
if (e.response.status !== 404) {
28+
throw e;
29+
} else {
30+
return e.response.status;
31+
}
32+
} else {
33+
throw e;
34+
}
35+
}
36+
},
37+
{ timeout: EVENT_POLLING_TIMEOUT },
38+
)
39+
.toBe(200);
40+
});
41+
42+
test('Sends correct error event', async ({ baseURL }) => {
43+
const errorEventPromise = waitForError('node-express-app', event => {
44+
return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123';
45+
});
46+
47+
try {
48+
await axios.get(`${baseURL}/test-exception/123`);
49+
} catch {
50+
// this results in an error, but we don't care - we want to check the error event
51+
}
52+
53+
const errorEvent = await errorEventPromise;
54+
55+
expect(errorEvent.exception?.values).toHaveLength(1);
56+
expect(errorEvent.exception?.values?.[0]?.value).toBe('This is an exception with id 123');
57+
58+
expect(errorEvent.request).toEqual({
59+
method: 'GET',
60+
cookies: {},
61+
headers: expect.any(Object),
62+
url: 'http://localhost:3030/test-exception/123',
63+
});
64+
65+
expect(errorEvent.transaction).toEqual('GET /test-exception/:id');
66+
67+
expect(errorEvent.contexts?.trace).toEqual({
68+
trace_id: expect.any(String),
69+
span_id: expect.any(String),
70+
});
71+
});
72+
73+
test('Should record caught exceptions with local variable', async ({ baseURL }) => {
74+
const { data } = await axios.get(`${baseURL}/test-local-variables-caught`);
75+
const { exceptionId } = data;
76+
77+
const url = `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${exceptionId}/json/`;
78+
79+
console.log(`Polling for error eventId: ${exceptionId}`);
80+
81+
let response: AxiosResponse;
82+
83+
await expect
84+
.poll(
85+
async () => {
86+
try {
87+
response = await axios.get(url, { headers: { Authorization: `Bearer ${authToken}` } });
88+
89+
return response.status;
90+
} catch (e) {
91+
if (e instanceof AxiosError && e.response) {
92+
if (e.response.status !== 404) {
93+
throw e;
94+
} else {
95+
return e.response.status;
96+
}
97+
} else {
98+
throw e;
99+
}
100+
}
101+
},
102+
{ timeout: EVENT_POLLING_TIMEOUT },
103+
)
104+
.toBe(200);
105+
106+
const frames = response!.data.exception.values[0].stacktrace.frames;
107+
108+
expect(frames[frames.length - 1].vars?.randomVariableToRecord).toBeDefined();
109+
});
110+
111+
test('Should record uncaught exceptions with local variable', async ({ baseURL }) => {
112+
const errorEventPromise = waitForError('node-express-app', errorEvent => {
113+
return !!errorEvent?.exception?.values?.[0]?.value?.includes('Uncaught Local Variable Error');
114+
});
115+
116+
await axios.get(`${baseURL}/test-local-variables-uncaught`).catch(() => {
117+
// noop
118+
});
119+
120+
const routehandlerError = await errorEventPromise;
121+
122+
const frames = routehandlerError!.exception!.values![0]!.stacktrace!.frames!;
123+
124+
expect(frames[frames.length - 1].vars?.randomVariableToRecord).toBeDefined();
125+
});

dev-packages/e2e-tests/test-applications/node-express-app/tests/server.test.ts

Lines changed: 0 additions & 227 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0