-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathserver-components.test.ts
More file actions
125 lines (104 loc) · 4.84 KB
/
server-components.test.ts
File metadata and controls
125 lines (104 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { expect, test } from '@playwright/test';
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';
test('Sends a transaction for a request to app router', async ({ page }) => {
const serverComponentTransactionPromise = waitForTransaction('nextjs-app-dir', transactionEvent => {
return (
transactionEvent?.transaction === 'GET /server-component/parameter/[...parameters]' &&
transactionEvent.contexts?.trace?.data?.['http.target'].startsWith('/server-component/parameter/1337/42')
);
});
await page.goto('/server-component/parameter/1337/42');
const transactionEvent = await serverComponentTransactionPromise;
expect(transactionEvent.contexts?.trace).toEqual({
data: expect.objectContaining({
'sentry.op': 'http.server',
'sentry.origin': 'auto',
'sentry.sample_rate': 1,
'sentry.source': 'route',
'http.method': 'GET',
'http.response.status_code': 200,
'http.route': '/server-component/parameter/[...parameters]',
'http.status_code': 200,
'http.target': '/server-component/parameter/1337/42',
'otel.kind': 'SERVER',
}),
op: 'http.server',
origin: 'auto',
span_id: expect.stringMatching(/[a-f0-9]{16}/),
status: 'ok',
trace_id: expect.stringMatching(/[a-f0-9]{32}/),
});
expect(transactionEvent.request).toEqual({
cookies: {},
headers: expect.objectContaining({
'user-agent': expect.any(String),
}),
});
// The transaction should not contain any spans with the same name as the transaction
// e.g. "GET /server-component/parameter/[...parameters]"
expect(
transactionEvent.spans?.filter(span => {
return span.description === transactionEvent.transaction;
}),
).toHaveLength(0);
});
test('Should not set an error status on an app router transaction when it redirects', async ({ page }) => {
const serverComponentTransactionPromise = waitForTransaction('nextjs-app-dir', async transactionEvent => {
return transactionEvent?.transaction === 'GET /server-component/redirect';
});
await page.goto('/server-component/redirect');
const transactionEvent = await serverComponentTransactionPromise;
expect(transactionEvent.contexts?.trace?.status).not.toBe('internal_error');
});
test('Should set a "not_found" status on a server component span when notFound() is called and the request span should have status ok', async ({
page,
}) => {
const serverComponentTransactionPromise = waitForTransaction('nextjs-app-dir', async transactionEvent => {
return transactionEvent?.transaction === 'GET /server-component/not-found';
});
await page.goto('/server-component/not-found');
const transactionEvent = await serverComponentTransactionPromise;
// Transaction should have status ok, because the http status is ok, but the server component span should be not_found
expect(transactionEvent.contexts?.trace?.status).toBe('ok');
expect(transactionEvent.spans).toContainEqual(
expect.objectContaining({
description: 'Page Server Component (/server-component/not-found)',
op: 'function.nextjs',
status: 'not_found',
data: expect.objectContaining({
'sentry.nextjs.function.type': 'Page',
'sentry.nextjs.function.route': '/server-component/not-found',
}),
}),
);
});
test('Should capture an error and transaction for a app router page', async ({ page }) => {
const transactionEventPromise = waitForTransaction('nextjs-app-dir', async transactionEvent => {
return transactionEvent?.transaction === 'GET /server-component/faulty';
});
const errorEventPromise = waitForError('nextjs-app-dir', errorEvent => {
return errorEvent?.exception?.values?.[0]?.value === 'I am a faulty server component';
});
await page.goto('/server-component/faulty');
const transactionEvent = await transactionEventPromise;
const errorEvent = await errorEventPromise;
// Error event should have the right transaction name
expect(errorEvent.transaction).toBe(`Page Server Component (/server-component/faulty)`);
// Transaction should have status ok, because the http status is ok, but the server component span should be internal_error
expect(transactionEvent.contexts?.trace?.status).toBe('ok');
expect(transactionEvent.spans).toContainEqual(
expect.objectContaining({
description: 'Page Server Component (/server-component/faulty)',
op: 'function.nextjs',
status: 'internal_error',
data: expect.objectContaining({
'sentry.nextjs.function.type': 'Page',
'sentry.nextjs.function.route': '/server-component/faulty',
}),
}),
);
expect(errorEvent.tags?.['my-isolated-tag']).toBe(true);
expect(errorEvent.tags?.['my-global-scope-isolated-tag']).not.toBeDefined();
expect(transactionEvent.tags?.['my-isolated-tag']).toBe(true);
expect(transactionEvent.tags?.['my-global-scope-isolated-tag']).not.toBeDefined();
});