Skip to content

Commit cbe84cb

Browse files
JPeer264claude
andcommitted
test(cloudflare): Assert Workers AI gen_ai spans in the send-to-sentry E2E test
Call a Workers AI model from the deployed Worker and check that the gen_ai.chat span reaches Sentry with its input and output messages. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 5420b4c commit cbe84cb

4 files changed

Lines changed: 35 additions & 2 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
interface Env {
22
E2E_TEST_DSN: string;
3+
AI: Ai;
34
}

‎dev-packages/e2e-tests/test-applications/cloudflare-workers-send-to-sentry/src/index.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as Sentry from '@sentry/cloudflare';
22

33
export default {
4-
async fetch(request) {
4+
async fetch(request, env) {
55
const url = new URL(request.url);
66
// The handler runs inside the request span the Vite plugin's `withSentry` wrapper starts, so
77
// this is the `http.server` span.
@@ -14,6 +14,10 @@ export default {
1414
}
1515
case '/test-unhandled-error':
1616
throw new Error('E2E test unhandled error');
17+
case '/test-workers-ai': {
18+
await env.AI.run('@cf/meta/llama-3.2-1b-instruct', { prompt: 'Say hi', max_tokens: 5 });
19+
return Response.json({ traceId: spanContext?.traceId });
20+
}
1721
case '/test-span':
1822
return Response.json({ spanId: spanContext?.spanId, traceId: spanContext?.traceId });
1923
default:

‎dev-packages/e2e-tests/test-applications/cloudflare-workers-send-to-sentry/tests/send-to-sentry.test.ts‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { randomBytes } from 'node:crypto';
22
import { expect, test } from '@playwright/test';
3-
import { EVENT_POLLING_OPTIONS, findErrorInTrace, findSpanInTrace, traceTarget } from '@sentry-internal/test-utils/cli';
3+
import {
4+
EVENT_POLLING_OPTIONS,
5+
fetchSpanAttributes,
6+
findErrorInTrace,
7+
findSpanInTrace,
8+
traceTarget,
9+
} from '@sentry-internal/test-utils/cli';
410

511
// Set by global-setup.mjs once the worker for this run is deployed.
612
const workerUrl = process.env.E2E_TEST_WORKER_URL;
@@ -43,3 +49,24 @@ test('Sends a request span to Sentry', async () => {
4349
.poll(() => findSpanInTrace(traceId, 'http.server'), EVENT_POLLING_OPTIONS)
4450
.toMatchObject({ event_id: spanId });
4551
});
52+
53+
test('Sends a Workers AI gen_ai span to Sentry', async () => {
54+
const response = await fetch(`${workerUrl}/test-workers-ai`);
55+
expect(response.status).toBe(200);
56+
const { traceId } = await response.json();
57+
58+
console.log(`Polling for gen_ai.chat span: sentry trace view ${traceTarget(traceId)}`);
59+
60+
let spanId: string | undefined;
61+
await expect
62+
.poll(() => (spanId = findSpanInTrace(traceId, 'gen_ai.chat')?.event_id), EVENT_POLLING_OPTIONS)
63+
.toBeDefined();
64+
65+
// Sentry stores `gen_ai.response.text` as `gen_ai.output.messages`.
66+
await expect
67+
.poll(() => fetchSpanAttributes(traceId, spanId!), EVENT_POLLING_OPTIONS)
68+
.toMatchObject({
69+
'gen_ai.input.messages': expect.stringContaining('Say hi'),
70+
'gen_ai.output.messages': expect.stringContaining('"role":"assistant"'),
71+
});
72+
});

‎dev-packages/e2e-tests/test-applications/cloudflare-workers-send-to-sentry/wrangler.jsonc‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"compatibility_date": "2026-05-20",
77
"compatibility_flags": ["nodejs_compat"],
88
"workers_dev": true,
9+
"ai": { "binding": "AI" },
910
// Workers Logs keep the invocations of the last 7 days, so a failed CI run can still be inspected.
1011
"observability": { "enabled": true },
1112
}

0 commit comments

Comments
 (0)