Skip to content

Commit 373a1ed

Browse files
committed
Merge branch 'develop' into sig/profiling-manual-mode
# Conflicts: # packages/browser/src/profiling/UIProfiler.ts
2 parents 9373335 + 5a5e091 commit 373a1ed

File tree

55 files changed

+1652
-63
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1652
-63
lines changed

.size-limit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ module.exports = [
240240
import: createImport('init'),
241241
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
242242
gzip: true,
243-
limit: '158 KB',
243+
limit: '160 KB',
244244
},
245245
{
246246
name: '@sentry/node - without tracing',

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Unreleased
44

5-
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
5+
- fix(node): Fix Spotlight configuration precedence to match specification (#18195)
66

77
## 10.25.0
88

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
release: '1.0.0',
8+
environment: 'test',
9+
integrations: integrations => {
10+
return integrations.filter(integration => integration.name !== 'BrowserSession');
11+
},
12+
beforeSendMetric: metric => {
13+
if (metric.name === 'test.counter') {
14+
return {
15+
...metric,
16+
attributes: {
17+
...metric.attributes,
18+
modified: 'by-beforeSendMetric',
19+
original: undefined,
20+
},
21+
};
22+
}
23+
return metric;
24+
},
25+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Store captured metrics from the afterCaptureMetric event
2+
window.capturedMetrics = [];
3+
4+
const client = Sentry.getClient();
5+
6+
client.on('afterCaptureMetric', metric => {
7+
window.capturedMetrics.push(metric);
8+
});
9+
10+
// Capture metrics - these should be processed by beforeSendMetric
11+
Sentry.metrics.count('test.counter', 1, { attributes: { endpoint: '/api/test', original: 'value' } });
12+
Sentry.metrics.gauge('test.gauge', 42, { unit: 'millisecond', attributes: { server: 'test-1' } });
13+
14+
Sentry.flush();
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { expect } from '@playwright/test';
2+
import { sentryTest } from '../../../../utils/fixtures';
3+
4+
sentryTest(
5+
'should emit afterCaptureMetric event with processed metric from beforeSendMetric',
6+
async ({ getLocalTestUrl, page }) => {
7+
const bundle = process.env.PW_BUNDLE || '';
8+
if (bundle.startsWith('bundle') || bundle.startsWith('loader')) {
9+
sentryTest.skip();
10+
}
11+
12+
const url = await getLocalTestUrl({ testDir: __dirname });
13+
await page.goto(url);
14+
15+
await page.waitForFunction(() => {
16+
return (window as any).capturedMetrics.length >= 2;
17+
});
18+
19+
const capturedMetrics = await page.evaluate(() => {
20+
return (window as any).capturedMetrics;
21+
});
22+
23+
expect(capturedMetrics).toHaveLength(2);
24+
25+
// Verify the counter metric was modified by beforeSendMetric
26+
expect(capturedMetrics[0]).toMatchObject({
27+
name: 'test.counter',
28+
type: 'counter',
29+
value: 1,
30+
attributes: {
31+
endpoint: '/api/test',
32+
modified: 'by-beforeSendMetric',
33+
'sentry.release': '1.0.0',
34+
'sentry.environment': 'test',
35+
'sentry.sdk.name': 'sentry.javascript.browser',
36+
},
37+
});
38+
39+
// Verify the 'original' attribute was removed by beforeSendMetric
40+
expect(capturedMetrics[0].attributes.original).toBeUndefined();
41+
42+
// Verify the gauge metric was not modified (no beforeSendMetric processing)
43+
expect(capturedMetrics[1]).toMatchObject({
44+
name: 'test.gauge',
45+
type: 'gauge',
46+
unit: 'millisecond',
47+
value: 42,
48+
attributes: {
49+
server: 'test-1',
50+
'sentry.release': '1.0.0',
51+
'sentry.environment': 'test',
52+
'sentry.sdk.name': 'sentry.javascript.browser',
53+
},
54+
});
55+
56+
expect(capturedMetrics[0].attributes['sentry.sdk.version']).toBeDefined();
57+
expect(capturedMetrics[1].attributes['sentry.sdk.version']).toBeDefined();
58+
},
59+
);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
window.Replay = Sentry.replayIntegration({
5+
flushMinDelay: 200,
6+
flushMaxDelay: 200,
7+
// Try to set to 60s - should be capped at 50s
8+
minReplayDuration: 60000,
9+
});
10+
11+
Sentry.init({
12+
dsn: 'https://[email protected]/1337',
13+
sampleRate: 0,
14+
replaysSessionSampleRate: 1.0,
15+
replaysOnErrorSampleRate: 0.0,
16+
17+
integrations: [window.Replay],
18+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Replay - minReplayDuration Limit</title>
6+
</head>
7+
<body>
8+
<div id="content">
9+
<p>Testing that minReplayDuration is capped at 50s max</p>
10+
</div>
11+
</body>
12+
</html>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { expect } from '@playwright/test';
2+
import { sentryTest } from '../../../utils/fixtures';
3+
import { shouldSkipReplayTest } from '../../../utils/replayHelpers';
4+
5+
sentryTest('caps minReplayDuration to maximum of 50 seconds', async ({ getLocalTestUrl, page }) => {
6+
if (shouldSkipReplayTest()) {
7+
sentryTest.skip();
8+
}
9+
10+
const url = await getLocalTestUrl({ testDir: __dirname });
11+
12+
await page.goto(url);
13+
14+
const actualMinReplayDuration = await page.evaluate(() => {
15+
// @ts-expect-error - Replay is not typed on window
16+
const replayIntegration = window.Replay;
17+
const replay = replayIntegration._replay;
18+
return replay.getOptions().minReplayDuration;
19+
});
20+
21+
// Even though we configured it to 60s (60000ms), it should be capped to 50s
22+
expect(actualMinReplayDuration).toBe(50_000);
23+
});

dev-packages/node-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@hono/node-server": "^1.19.4",
3232
"@langchain/anthropic": "^0.3.10",
3333
"@langchain/core": "^0.3.28",
34+
"@langchain/langgraph": "^0.2.32",
3435
"@nestjs/common": "^11",
3536
"@nestjs/core": "^11",
3637
"@nestjs/platform-express": "^11",

dev-packages/node-integration-tests/suites/tracing/google-genai/test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ describe('Google GenAI integration', () => {
204204
});
205205
});
206206

207+
const EXPECTED_AVAILABLE_TOOLS_JSON =
208+
'[{"name":"controlLight","parametersJsonSchema":{"type":"object","properties":{"brightness":{"type":"number"},"colorTemperature":{"type":"string"}},"required":["brightness","colorTemperature"]}}]';
209+
207210
const EXPECTED_TRANSACTION_TOOLS = {
208211
transaction: 'main',
209212
spans: expect.arrayContaining([
@@ -215,7 +218,7 @@ describe('Google GenAI integration', () => {
215218
'sentry.origin': 'auto.ai.google_genai',
216219
'gen_ai.system': 'google_genai',
217220
'gen_ai.request.model': 'gemini-2.0-flash-001',
218-
'gen_ai.request.available_tools': expect.any(String), // Should include tools
221+
'gen_ai.request.available_tools': EXPECTED_AVAILABLE_TOOLS_JSON,
219222
'gen_ai.request.messages': expect.any(String), // Should include contents
220223
'gen_ai.response.text': expect.any(String), // Should include response text
221224
'gen_ai.response.tool_calls': expect.any(String), // Should include tool calls
@@ -236,7 +239,7 @@ describe('Google GenAI integration', () => {
236239
'sentry.origin': 'auto.ai.google_genai',
237240
'gen_ai.system': 'google_genai',
238241
'gen_ai.request.model': 'gemini-2.0-flash-001',
239-
'gen_ai.request.available_tools': expect.any(String), // Should include tools
242+
'gen_ai.request.available_tools': EXPECTED_AVAILABLE_TOOLS_JSON,
240243
'gen_ai.request.messages': expect.any(String), // Should include contents
241244
'gen_ai.response.streaming': true,
242245
'gen_ai.response.text': expect.any(String), // Should include response text

0 commit comments

Comments
 (0)