Skip to content

Commit 58e6f4f

Browse files
committed
add test for distributed client-side API request
1 parent 86de9e0 commit 58e6f4f

File tree

2 files changed

+82
-45
lines changed

2 files changed

+82
-45
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script setup lang="ts">
2+
import { useFetch, useRoute } from '#imports';
3+
4+
const route = useRoute();
5+
const param = route.params.param as string;
6+
7+
const { data } = await useFetch(`/api/test-param/${param}`, {
8+
server: false, // Don't fetch during SSR
9+
});
10+
</script>
11+
12+
<template>
13+
<div>
14+
<p v-if="data">Server Data: {{ data }}</p>
15+
</div>
16+
</template>

dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.test.ts

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ test.describe('distributed tracing', () => {
1010
});
1111

1212
const serverTxnEventPromise = waitForTransaction('nuxt-4', txnEvent => {
13-
return txnEvent.transaction.includes('GET /test-param/');
13+
return txnEvent.transaction?.includes('GET /test-param/') ?? false;
1414
});
1515

1616
const [_, clientTxnEvent, serverTxnEvent] = await Promise.all([
@@ -67,66 +67,87 @@ test.describe('distributed tracing', () => {
6767
expect(serverTxnEvent.contexts?.trace?.trace_id).toBe(metaTraceId);
6868
});
6969

70-
test('capture a distributed server request with parametrization', async ({ page }) => {
70+
test('capture a distributed trace from a client-side API request with parametrized routes', async ({ page }) => {
7171
const clientTxnEventPromise = waitForTransaction('nuxt-4', txnEvent => {
72-
return txnEvent.transaction === '/test-param/:param()';
72+
return txnEvent.transaction === '/test-param/fetch-api/:param()';
7373
});
74-
7574
const ssrTxnEventPromise = waitForTransaction('nuxt-4', txnEvent => {
76-
return txnEvent.transaction.includes('GET /test-param/');
75+
return txnEvent.transaction?.includes('GET /test-param/fetch-api') ?? false;
7776
});
78-
7977
const serverReqTxnEventPromise = waitForTransaction('nuxt-4', txnEvent => {
80-
return txnEvent.transaction.includes('GET /api/test-param/');
78+
return txnEvent.transaction?.includes('GET /api/test-param/') ?? false;
8179
});
8280

83-
const [, clientTxnEvent, ssrTxnEvent, , , serverReqTxnEvent] = await Promise.all([
84-
page.goto(`/test-param/${PARAM}`),
81+
// Navigate to the page which will trigger an API call from the client-side
82+
await page.goto(`/test-param/fetch-api/${PARAM}`);
83+
84+
const [clientTxnEvent, ssrTxnEvent, serverReqTxnEvent] = await Promise.all([
8585
clientTxnEventPromise,
8686
ssrTxnEventPromise,
87-
expect(page.getByText(`Param: ${PARAM}`)).toBeVisible(),
88-
page.getByText('Fetch Server Data', { exact: true }).click(),
8987
serverReqTxnEventPromise,
9088
]);
9189

9290
const httpClientSpan = clientTxnEvent?.spans?.find(span => span.description === `GET /api/test-param/${PARAM}`);
9391

94-
expect(ssrTxnEvent).toMatchObject({
95-
transaction: `GET /test-param/${PARAM}`, // todo: parametrize (nitro)
96-
transaction_info: { source: 'url' },
97-
type: 'transaction',
98-
contexts: {
99-
trace: {
100-
op: 'http.server',
101-
origin: 'auto.http.otel.http',
102-
},
103-
},
104-
});
105-
106-
expect(httpClientSpan).toMatchObject({
107-
description: `GET /api/test-param/${PARAM}`, // todo: parametrize (nitro)
108-
parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent
109-
data: expect.objectContaining({
110-
'sentry.op': 'http.client',
111-
'sentry.origin': 'auto.http.browser',
112-
'http.request_method': 'GET',
92+
expect(clientTxnEvent).toEqual(
93+
expect.objectContaining({
94+
type: 'transaction',
95+
transaction: '/test-param/fetch-api/:param()', // parametrized route
96+
transaction_info: { source: 'route' },
97+
contexts: expect.objectContaining({
98+
trace: expect.objectContaining({
99+
op: 'pageload',
100+
origin: 'auto.pageload.vue',
101+
}),
102+
}),
113103
}),
114-
});
115-
116-
expect(serverReqTxnEvent).toMatchObject({
117-
transaction: `GET /api/test-param/${PARAM}`, // todo: parametrize (nitro)
118-
transaction_info: { source: 'url' },
119-
type: 'transaction',
120-
contexts: {
121-
trace: {
122-
op: 'http.server',
123-
origin: 'auto.http.otel.http',
124-
parent_span_id: httpClientSpan?.span_id, // http.client span is parent
125-
},
126-
},
127-
});
104+
);
105+
106+
expect(httpClientSpan).toBeDefined();
107+
expect(httpClientSpan).toEqual(
108+
expect.objectContaining({
109+
description: `GET /api/test-param/${PARAM}`, // fixme: parametrize
110+
parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent
111+
data: expect.objectContaining({
112+
url: `/api/test-param/${PARAM}`, // fixme: parametrize
113+
type: 'fetch',
114+
'sentry.op': 'http.client',
115+
'sentry.origin': 'auto.http.browser',
116+
'http.method': 'GET',
117+
}),
118+
}),
119+
);
120+
121+
expect(ssrTxnEvent).toEqual(
122+
expect.objectContaining({
123+
type: 'transaction',
124+
transaction: `GET /test-param/fetch-api/${PARAM}`, // fixme: parametrize (nitro)
125+
transaction_info: { source: 'url' },
126+
contexts: expect.objectContaining({
127+
trace: expect.objectContaining({
128+
op: 'http.server',
129+
origin: 'auto.http.otel.http',
130+
}),
131+
}),
132+
}),
133+
);
134+
135+
expect(serverReqTxnEvent).toEqual(
136+
expect.objectContaining({
137+
type: 'transaction',
138+
transaction: `GET /api/test-param/${PARAM}`,
139+
transaction_info: { source: 'url' },
140+
contexts: expect.objectContaining({
141+
trace: expect.objectContaining({
142+
op: 'http.server',
143+
origin: 'auto.http.otel.http',
144+
parent_span_id: httpClientSpan?.span_id, // http.client span is parent
145+
}),
146+
}),
147+
}),
148+
);
128149

129-
// All share the same trace_id
150+
// All 3 transactions and the http.client span should share the same trace_id
130151
expect(clientTxnEvent.contexts?.trace?.trace_id).toBeDefined();
131152
expect(clientTxnEvent.contexts?.trace?.trace_id).toBe(httpClientSpan?.trace_id);
132153
expect(clientTxnEvent.contexts?.trace?.trace_id).toBe(ssrTxnEvent.contexts?.trace?.trace_id);

0 commit comments

Comments
 (0)