Skip to content

Commit 680188f

Browse files
committed
add deno e2e test app
1 parent 10ceb8a commit 680188f

8 files changed

Lines changed: 485 additions & 13 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"imports": {
3+
"@sentry/deno": "npm:@sentry/deno",
4+
"@sentry/core": "npm:@sentry/core",
5+
"@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0",
6+
"ai": "npm:ai@^3.0.0",
7+
"ai/test": "npm:ai@^3.0.0/test",
8+
"zod": "npm:zod@^3.22.4"
9+
},
10+
"nodeModulesDir": "manual"
11+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "deno-streamed-app",
3+
"version": "1.0.0",
4+
"private": true,
5+
"scripts": {
6+
"start": "deno run --allow-net --allow-env --allow-read src/app.ts",
7+
"test": "playwright test",
8+
"clean": "npx rimraf node_modules pnpm-lock.yaml",
9+
"test:build": "pnpm install",
10+
"test:assert": "pnpm test"
11+
},
12+
"dependencies": {
13+
"@sentry/deno": "latest || *",
14+
"@opentelemetry/api": "^1.9.0",
15+
"ai": "^3.0.0",
16+
"zod": "^3.22.4"
17+
},
18+
"devDependencies": {
19+
"@playwright/test": "~1.56.0",
20+
"@sentry-internal/test-utils": "link:../../../test-utils"
21+
},
22+
"volta": {
23+
"extends": "../../package.json"
24+
}
25+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { getPlaywrightConfig } from '@sentry-internal/test-utils';
2+
3+
const config = getPlaywrightConfig({
4+
startCommand: `pnpm start`,
5+
port: 3030,
6+
});
7+
8+
export default config;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { trace } from '@opentelemetry/api';
2+
3+
// Simulate a pre-existing OTel provider (like Supabase Edge Runtime registers
4+
// before user code runs). Without trace.disable() in Sentry's setup, this would
5+
// cause setGlobalTracerProvider to be a no-op, silently dropping all OTel spans.
6+
const fakeProvider = {
7+
getTracer: () => ({
8+
startSpan: () => ({ end: () => {}, setAttributes: () => {} }),
9+
startActiveSpan: (_name: string, fn: Function) => fn({ end: () => {}, setAttributes: () => {} }),
10+
}),
11+
};
12+
trace.setGlobalTracerProvider(fakeProvider as any);
13+
14+
// Sentry.init() must call trace.disable() to clear the fake provider above
15+
import * as Sentry from '@sentry/deno';
16+
import { generateText } from 'ai';
17+
import { MockLanguageModelV1 } from 'ai/test';
18+
import { z } from 'zod';
19+
20+
Sentry.init({
21+
environment: 'qa',
22+
dsn: Deno.env.get('E2E_TEST_DSN'),
23+
debug: !!Deno.env.get('DEBUG'),
24+
tunnel: 'http://localhost:3031/',
25+
traceLifecycle: 'stream',
26+
tracesSampleRate: 1,
27+
sendDefaultPii: true,
28+
enableLogs: true,
29+
});
30+
31+
const port = 3030;
32+
33+
Deno.serve({ port }, async (req: Request) => {
34+
const url = new URL(req.url);
35+
36+
if (url.pathname === '/test-success') {
37+
return new Response(JSON.stringify({ version: 'v1' }), {
38+
headers: { 'Content-Type': 'application/json' },
39+
});
40+
}
41+
42+
// Test Sentry.startSpan — uses Sentry's internal pipeline
43+
if (url.pathname === '/test-sentry-span') {
44+
Sentry.startSpan({ name: 'test-sentry-span' }, () => {
45+
// noop
46+
});
47+
return new Response(JSON.stringify({ status: 'ok' }), {
48+
headers: { 'Content-Type': 'application/json' },
49+
});
50+
}
51+
52+
// Test interop: OTel span inside a Sentry span
53+
if (url.pathname === '/test-interop') {
54+
Sentry.startSpan({ name: 'sentry-parent' }, () => {
55+
const tracer = trace.getTracer('test-tracer');
56+
const span = tracer.startSpan('otel-child');
57+
span.end();
58+
});
59+
return new Response(JSON.stringify({ status: 'ok' }), {
60+
headers: { 'Content-Type': 'application/json' },
61+
});
62+
}
63+
64+
// Test outbound fetch instrumentation
65+
if (url.pathname === '/test-outgoing-fetch') {
66+
const response = await Sentry.startSpan({ name: 'test-outgoing-fetch' }, async () => {
67+
const res = await fetch('http://localhost:3030/test-success');
68+
return res.json();
69+
});
70+
return new Response(JSON.stringify(response), {
71+
headers: { 'Content-Type': 'application/json' },
72+
});
73+
}
74+
75+
return new Response('Not found', { status: 404 });
76+
});
77+
78+
console.log(`Deno test app listening on port ${port}`);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { startEventProxyServer } from '@sentry-internal/test-utils';
2+
3+
startEventProxyServer({
4+
port: 3031,
5+
proxyServerName: 'deno-streamed',
6+
});

0 commit comments

Comments
 (0)