Skip to content

test(e2e): Add node-openai-send-to-sentry test app - #24824

Merged
RulaKhaled merged 6 commits into
developfrom
test/openai-send-to-sentry-e2e
Oct 13, 2026
Merged

RulaKhaled merged 6 commits into
developfrom
test/openai-send-to-sentry-e2e

Conversation

@RulaKhaled

@RulaKhaled RulaKhaled commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

An e2e app that uses the OpenAI integration the way a user does and sends the data to a real Sentry project, per #24747.

The app. A plain Sentry.init on an express app, preloaded with node --import, no tunnel. The stock openai client talks to OpenRouter. Five routes make one real request each: a chat completion, a streamed chat completion, a forced tool call, a Responses API call, and an embeddings call.

The tests. Each one reads the request's gen_ai span back through the Sentry API, like the other *-send-to-sentry apps, and checks op, origin, status, model, token usage, and that the prompts and answers arrived. The checks use the attribute names ingest stores, which differ from what the SDK sends (sentry.origin is stored as origin, gen_ai.response.text as gen_ai.output.messages). Ingest does not store gen_ai.response.tool_calls under that name, so the tool-call test checks the finish reason instead. openai is pinned to 7.5.0, the version the v7 integration suite uses, and a (latest) variant runs the same tests against openai@latest. Both are optional, like the other send-to-sentry apps.

Closes #24747

🤖 Generated with Claude Code

An e2e app that uses the OpenAI integration the way a user does and sends
the data to a real Sentry project. A plain Sentry.init on an express app,
no tunnel, and the stock openai client making real chat, streaming,
tool-call, Responses API and embeddings requests through OpenRouter. The
tests read the gen_ai spans back through the Sentry API, like the other
*-send-to-sentry apps, and check op, name, origin, status, token usage,
finish reasons and the recorded prompts and answers. A latest variant runs
the same suite against openai@latest.

The attribute checks use the stored names, which differ from what the SDK
sends: sentry.origin is stored as origin, sentry.op as span.op,
gen_ai.response.text as gen_ai.output.messages, and integers come back as
strings. gen_ai.response.tool_calls is not stored under that name at all,
so the tool-call test relies on the finish reason.

Closes #24747

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 29.82 kB - -
@sentry/browser - with treeshaking flags 27.95 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.86 kB - -
@sentry/browser (incl. Tracing) 51.88 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 51.9 kB - -
@sentry/browser (incl. Tracing, Profiling) 54.83 kB - -
@sentry/browser (incl. Tracing, Replay) 91.63 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.49 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 96.34 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 109.32 kB - -
@sentry/browser (incl. Feedback) 47.34 kB - -
@sentry/browser (incl. sendFeedback) 34.87 kB - -
@sentry/browser (incl. FeedbackAsync) 39.98 kB - -
@sentry/browser (incl. Metrics) 30.84 kB - -
@sentry/browser (incl. Logs) 31.13 kB - -
@sentry/browser (incl. Metrics & Logs) 31.77 kB - -
@sentry/react 31.65 kB - -
@sentry/react (incl. Tracing) 54.21 kB - -
@sentry/vue 37.89 kB - -
@sentry/vue (incl. Tracing) 54.81 kB - -
@sentry/svelte 29.84 kB - -
@sentry/remix (Remix 3 client bundle) 56.91 kB - -
CDN Bundle 31.55 kB - -
CDN Bundle (incl. Tracing) 52.41 kB - -
CDN Bundle (incl. Logs, Metrics) 33.75 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 54.34 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 74.67 kB - -
CDN Bundle (incl. Tracing, Replay) 90.06 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 92 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 96.23 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 98.18 kB - -
CDN Bundle - uncompressed 92.91 kB - -
CDN Bundle (incl. Tracing) - uncompressed 155.53 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 99.45 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 161.48 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 229.48 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 275.7 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 281.63 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 289.4 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 295.33 kB - -
@sentry/nextjs (client) 56.62 kB - -
@sentry/sveltekit (client) 52.27 kB - -
@sentry/core/server 40.92 kB - -
@sentry/core/browser 13.74 kB - -
@sentry/node 151.89 kB +0.01% +12 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.77 kB - -
@sentry/node - without tracing 94.45 kB +0.01% +7 B 🔺
@sentry/node - without channel injection 130.09 kB +0.01% +2 B 🔺
@sentry/aws-serverless 102.62 kB +0.01% +4 B 🔺
@sentry/cloudflare (withSentry) - minified 210.2 kB - -
@sentry/cloudflare (withSentry) 521.15 kB - -
@sentry/nextjs/cloudflare (withSentry) - minified 227.87 kB - -

View base workflow run

Over the minutes a send-to-sentry test polls, the API closes the odd
connection ("TypeError: terminated, other side closed"). An error thrown
inside expect.poll fails the test instead of letting it retry, which is
how the tool-call test failed on the first CI run while the other four
passed. Treat a network error during a lookup like a non-2xx answer: log
it and report "not there yet".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
RulaKhaled added a commit that referenced this pull request Oct 1, 2026
An e2e app that uses the Anthropic integration the way a user does and
sends the data to a real Sentry project, per #24748. Same shape as the
OpenAI one in #24824.

**Stacked on #24855.** The `latest` variant needs that fix; this PR
targets its branch and retargets to `develop` once it merges.

**The app.** A plain `Sentry.init` on an express app, preloaded with
`node --import`, no tunnel. The stock `@anthropic-ai/sdk` client talks
to OpenRouter's Anthropic-compatible endpoint. Four routes make one real
request each: a message, a streamed message, one through the
`messages.stream()` helper, and a forced tool use.

**The tests.** Each one reads the request's `gen_ai.chat` span back
through the Sentry API, like the other `*-send-to-sentry` apps, and
checks op, origin, status, model, token usage, and that the prompts and
answers arrived. The helper test also checks there is exactly one
`gen_ai.chat` span, which is what caught the duplicate fixed in #24855.
`@anthropic-ai/sdk` is pinned to 0.63.0, the version the integration
suite uses, and a `(latest)` variant runs the same tests against
`@anthropic-ai/sdk@latest`. Both are optional, like the other
send-to-sentry apps.

Closes #24748

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Jan Peer Stöcklmair <jan.peer@sentry.io>
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

👋 @nicohrubec, @andreiborza — Please review this PR when you get a chance!

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

👋 @andreiborza — Please review this PR when you get a chance!

RulaKhaled and others added 2 commits October 12, 2026 13:56
…AI app

Review follow-ups. Each test now waits until the request span holds
exactly one span with the expected op. A double-instrumented call used to
pass, because the lookup took the first match and the parent check only
looked for one id. The answer checks match the expected text instead of
checking for a string: the SDK records a missing answer as `[""]`, which
the typeof check accepted. Also adds a TODO to assert tool calls in
gen_ai.output.messages once the integration records them there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the app's own copy of the Sentry API helpers with
@sentry-internal/test-utils/cli, the way the cloudflare send-to-sentry
apps do it. The shared fetchSpanAttributes passes values through as the
API returns them, and the API returns int attributes as strings, so the
token count checks convert with Number(). Moving that conversion into
fetchSpanAttributes is left for a separate PR, since it changes the
helper for every app that uses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 74ed239. Configure here.

Every test now polls Sentry twice, once for the model span and once for
the request span, and each poll can take up to 180s. The 210s test
timeout could cut the second poll short, so raise it to 400s, the same
as the Anthropic app.

Also only require gen_ai.response.id on chat spans. The SDK records it
only when the response has an id, and OpenAI embeddings responses have
none. The embeddings test passed only because OpenRouter adds one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RulaKhaled
RulaKhaled requested a review from nicohrubec October 12, 2026 13:44

@nicohrubec nicohrubec left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for updating, lgtm

@RulaKhaled
RulaKhaled merged commit e0e5d65 into develop Oct 13, 2026
367 checks passed
@RulaKhaled
RulaKhaled deleted the test/openai-send-to-sentry-e2e branch October 13, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add realistic e2e test app for OpenAI

2 participants