From 2155d95499c9a371695e2cb700299766920286ac Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:39:23 +0100 Subject: [PATCH 1/2] fix(profiling): Add `platform` to envelope item header --- .../suites/profiling/manualMode/test.ts | 6 +++--- .../suites/profiling/test-utils.ts | 5 +++++ .../profiling/traceLifecycleMode_multiple-chunks/test.ts | 6 +++--- .../profiling/traceLifecycleMode_overlapping-spans/test.ts | 4 ++-- packages/browser/src/profiling/UIProfiler.ts | 2 +- packages/browser/test/profiling/UIProfiler.test.ts | 3 +++ 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts b/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts index 2e4358563aa2..96fabd095ae3 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts @@ -7,7 +7,7 @@ import { properFullEnvelopeRequestParser, shouldSkipTracingTest, } from '../../../utils/helpers'; -import { validateProfile, validateProfilePayloadMetadata } from '../test-utils'; +import { validateProfile, validateProfileItemHeader, validateProfilePayloadMetadata } from '../test-utils'; sentryTest( 'does not send profile envelope when document-policy is not set', @@ -48,7 +48,7 @@ sentryTest('sends profile_chunk envelopes in manual mode', async ({ page, getLoc const envelopeItemHeader = profileChunkEnvelopeItem[0]; const envelopeItemPayload1 = profileChunkEnvelopeItem[1]; - expect(envelopeItemHeader).toHaveProperty('type', 'profile_chunk'); + validateProfileItemHeader(envelopeItemHeader); expect(envelopeItemPayload1.profile).toBeDefined(); const profilerId1 = envelopeItemPayload1.profiler_id; @@ -71,7 +71,7 @@ sentryTest('sends profile_chunk envelopes in manual mode', async ({ page, getLoc const envelopeItemHeader2 = profileChunkEnvelopeItem2[0]; const envelopeItemPayload2 = profileChunkEnvelopeItem2[1]; - expect(envelopeItemHeader2).toHaveProperty('type', 'profile_chunk'); + validateProfileItemHeader(envelopeItemHeader2); expect(envelopeItemPayload2.profile).toBeDefined(); expect(envelopeItemPayload2.profiler_id).toBe(profilerId1); // same profiler id for the whole session diff --git a/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts b/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts index 39e6d2ca20b7..e1df4382a8dd 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts @@ -7,6 +7,11 @@ interface ValidateProfileOptions { isChunkFormat?: boolean; } +export function validateProfileItemHeader(header: Record): void { + expect(header).toHaveProperty('type', 'profile_chunk'); + expect(header).toHaveProperty('platform', 'javascript'); +} + /** * Validates the metadata of a profile chunk envelope. * https://develop.sentry.dev/sdk/telemetry/profiles/sample-format-v2/ diff --git a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts index 5afc23a3a75f..90fe2971c89f 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts @@ -7,7 +7,7 @@ import { properFullEnvelopeRequestParser, shouldSkipTracingTest, } from '../../../utils/helpers'; -import { validateProfile, validateProfilePayloadMetadata } from '../test-utils'; +import { validateProfile, validateProfileItemHeader, validateProfilePayloadMetadata } from '../test-utils'; sentryTest( 'does not send profile envelope when document-policy is not set', @@ -51,7 +51,7 @@ sentryTest( const envelopeItemHeader = profileChunkEnvelopeItem[0]; const envelopeItemPayload1 = profileChunkEnvelopeItem[1]; - expect(envelopeItemHeader).toHaveProperty('type', 'profile_chunk'); + validateProfileItemHeader(envelopeItemHeader); expect(envelopeItemPayload1.profile).toBeDefined(); validateProfilePayloadMetadata(envelopeItemPayload1); @@ -77,7 +77,7 @@ sentryTest( const envelopeItemHeader2 = profileChunkEnvelopeItem2[0]; const envelopeItemPayload2 = profileChunkEnvelopeItem2[1]; - expect(envelopeItemHeader2).toHaveProperty('type', 'profile_chunk'); + validateProfileItemHeader(envelopeItemHeader2); expect(envelopeItemPayload2.profile).toBeDefined(); validateProfilePayloadMetadata(envelopeItemPayload2); diff --git a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts index fa66a225b49b..f5264819ec1c 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts @@ -8,7 +8,7 @@ import { shouldSkipTracingTest, waitForTransactionRequestOnUrl, } from '../../../utils/helpers'; -import { validateProfile, validateProfilePayloadMetadata } from '../test-utils'; +import { validateProfile, validateProfileItemHeader, validateProfilePayloadMetadata } from '../test-utils'; sentryTest( 'does not send profile envelope when document-policy is not set', @@ -52,7 +52,7 @@ sentryTest( const envelopeItemHeader = profileChunkEnvelopeItem[0]; const envelopeItemPayload = profileChunkEnvelopeItem[1]; - expect(envelopeItemHeader).toHaveProperty('type', 'profile_chunk'); + validateProfileItemHeader(envelopeItemHeader); expect(envelopeItemPayload.profile).toBeDefined(); validateProfilePayloadMetadata(envelopeItemPayload); diff --git a/packages/browser/src/profiling/UIProfiler.ts b/packages/browser/src/profiling/UIProfiler.ts index 89edb4899a6a..932b442a4b6e 100644 --- a/packages/browser/src/profiling/UIProfiler.ts +++ b/packages/browser/src/profiling/UIProfiler.ts @@ -401,7 +401,7 @@ export class UIProfiler implements ContinuousProfiler { ...(sdkInfo && { sdk: sdkInfo }), ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }), }, - [[{ type: 'profile_chunk' }, chunk]], + [[{ type: 'profile_chunk', platform: 'javascript' }, chunk]], ); client.sendEnvelope(envelope).then(null, reason => { diff --git a/packages/browser/test/profiling/UIProfiler.test.ts b/packages/browser/test/profiling/UIProfiler.test.ts index 7fd583f513d8..b64ee35fc50e 100644 --- a/packages/browser/test/profiling/UIProfiler.test.ts +++ b/packages/browser/test/profiling/UIProfiler.test.ts @@ -106,6 +106,7 @@ describe('Browser Profiling v2 trace lifecycle', () => { const transactionEnvelopeHeader = send.mock.calls?.[0]?.[0]?.[1]?.[0]?.[0]; const profileChunkEnvelopeHeader = send.mock.calls?.[1]?.[0]?.[1]?.[0]?.[0]; expect(profileChunkEnvelopeHeader?.type).toBe('profile_chunk'); + expect(profileChunkEnvelopeHeader?.platform).toBe('javascript'); expect(transactionEnvelopeHeader?.type).toBe('transaction'); }); @@ -207,6 +208,7 @@ describe('Browser Profiling v2 trace lifecycle', () => { expect(mockConstructor.mock.calls.length).toBe(2); const firstChunkHeader = send.mock.calls?.[0]?.[0]?.[1]?.[0]?.[0]; expect(firstChunkHeader?.type).toBe('profile_chunk'); + expect(firstChunkHeader?.platform).toBe('javascript'); // Second chunk after another 60s vi.advanceTimersByTime(60_000); @@ -679,6 +681,7 @@ describe('Browser Profiling v2 manual lifecycle', () => { expect(send).toHaveBeenCalledTimes(1); const envelopeHeader = send.mock.calls?.[0]?.[0]?.[1]?.[0]?.[0]; expect(envelopeHeader?.type).toBe('profile_chunk'); + expect(envelopeHeader?.platform).toBe('javascript'); }); it('calling start and stop while profile session is running prints warnings', async () => { From 92696ae49869fac0d9ff787d1ac301d5eff63254 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 23 Jan 2026 13:10:21 +0100 Subject: [PATCH 2/2] use direct assertion --- .../suites/profiling/manualMode/test.ts | 6 +++--- .../suites/profiling/test-utils.ts | 5 ----- .../profiling/traceLifecycleMode_multiple-chunks/test.ts | 6 +++--- .../profiling/traceLifecycleMode_overlapping-spans/test.ts | 4 ++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts b/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts index 96fabd095ae3..176caad92af6 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/manualMode/test.ts @@ -7,7 +7,7 @@ import { properFullEnvelopeRequestParser, shouldSkipTracingTest, } from '../../../utils/helpers'; -import { validateProfile, validateProfileItemHeader, validateProfilePayloadMetadata } from '../test-utils'; +import { validateProfile, validateProfilePayloadMetadata } from '../test-utils'; sentryTest( 'does not send profile envelope when document-policy is not set', @@ -48,7 +48,7 @@ sentryTest('sends profile_chunk envelopes in manual mode', async ({ page, getLoc const envelopeItemHeader = profileChunkEnvelopeItem[0]; const envelopeItemPayload1 = profileChunkEnvelopeItem[1]; - validateProfileItemHeader(envelopeItemHeader); + expect(envelopeItemHeader).toEqual({ type: 'profile_chunk', platform: 'javascript' }); expect(envelopeItemPayload1.profile).toBeDefined(); const profilerId1 = envelopeItemPayload1.profiler_id; @@ -71,7 +71,7 @@ sentryTest('sends profile_chunk envelopes in manual mode', async ({ page, getLoc const envelopeItemHeader2 = profileChunkEnvelopeItem2[0]; const envelopeItemPayload2 = profileChunkEnvelopeItem2[1]; - validateProfileItemHeader(envelopeItemHeader2); + expect(envelopeItemHeader2).toEqual({ type: 'profile_chunk', platform: 'javascript' }); expect(envelopeItemPayload2.profile).toBeDefined(); expect(envelopeItemPayload2.profiler_id).toBe(profilerId1); // same profiler id for the whole session diff --git a/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts b/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts index e1df4382a8dd..39e6d2ca20b7 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/test-utils.ts @@ -7,11 +7,6 @@ interface ValidateProfileOptions { isChunkFormat?: boolean; } -export function validateProfileItemHeader(header: Record): void { - expect(header).toHaveProperty('type', 'profile_chunk'); - expect(header).toHaveProperty('platform', 'javascript'); -} - /** * Validates the metadata of a profile chunk envelope. * https://develop.sentry.dev/sdk/telemetry/profiles/sample-format-v2/ diff --git a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts index 90fe2971c89f..a16a054da45a 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_multiple-chunks/test.ts @@ -7,7 +7,7 @@ import { properFullEnvelopeRequestParser, shouldSkipTracingTest, } from '../../../utils/helpers'; -import { validateProfile, validateProfileItemHeader, validateProfilePayloadMetadata } from '../test-utils'; +import { validateProfile, validateProfilePayloadMetadata } from '../test-utils'; sentryTest( 'does not send profile envelope when document-policy is not set', @@ -51,7 +51,7 @@ sentryTest( const envelopeItemHeader = profileChunkEnvelopeItem[0]; const envelopeItemPayload1 = profileChunkEnvelopeItem[1]; - validateProfileItemHeader(envelopeItemHeader); + expect(envelopeItemHeader).toEqual({ type: 'profile_chunk', platform: 'javascript' }); expect(envelopeItemPayload1.profile).toBeDefined(); validateProfilePayloadMetadata(envelopeItemPayload1); @@ -77,7 +77,7 @@ sentryTest( const envelopeItemHeader2 = profileChunkEnvelopeItem2[0]; const envelopeItemPayload2 = profileChunkEnvelopeItem2[1]; - validateProfileItemHeader(envelopeItemHeader2); + expect(envelopeItemHeader2).toEqual({ type: 'profile_chunk', platform: 'javascript' }); expect(envelopeItemPayload2.profile).toBeDefined(); validateProfilePayloadMetadata(envelopeItemPayload2); diff --git a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts index f5264819ec1c..487cd05f1dbd 100644 --- a/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/profiling/traceLifecycleMode_overlapping-spans/test.ts @@ -8,7 +8,7 @@ import { shouldSkipTracingTest, waitForTransactionRequestOnUrl, } from '../../../utils/helpers'; -import { validateProfile, validateProfileItemHeader, validateProfilePayloadMetadata } from '../test-utils'; +import { validateProfile, validateProfilePayloadMetadata } from '../test-utils'; sentryTest( 'does not send profile envelope when document-policy is not set', @@ -52,7 +52,7 @@ sentryTest( const envelopeItemHeader = profileChunkEnvelopeItem[0]; const envelopeItemPayload = profileChunkEnvelopeItem[1]; - validateProfileItemHeader(envelopeItemHeader); + expect(envelopeItemHeader).toEqual({ type: 'profile_chunk', platform: 'javascript' }); expect(envelopeItemPayload.profile).toBeDefined(); validateProfilePayloadMetadata(envelopeItemPayload);