From b97d700ed72e3371a9d1a33e73208a33fc5807b4 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 25 Jun 2025 10:58:27 +0200 Subject: [PATCH 1/2] test(browser:) Add test about re-sampling new traces --- .../startNewTraceSampling/init.js | 19 ++++ .../startNewTraceSampling/subject.js | 13 +++ .../startNewTraceSampling/template.html | 9 ++ .../startNewTraceSampling/test.ts | 89 +++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/init.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/template.html create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/test.ts diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/init.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/init.js new file mode 100644 index 000000000000..09af5f3e4ab4 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/init.js @@ -0,0 +1,19 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +// Force this so that the initial sampleRand is consistent +Math.random = () => 0.45; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [Sentry.browserTracingIntegration()], + tracePropagationTargets: ['http://sentry-test-site.example'], + tracesSampler: ({ name }) => { + if (name === 'new-trace') { + return 0.9; + } + + return 0.5; + }, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js new file mode 100644 index 000000000000..ac69f262cf34 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js @@ -0,0 +1,13 @@ +const newTraceBtn = document.getElementById('newTrace'); +newTraceBtn.addEventListener('click', async () => { + Sentry.startNewTrace(() => { + // We want top ensure the new trace is sampled, so we force the sample_rand to a value above 0.9 + Sentry.getCurrentScope().setPropagationContext({ + ...Sentry.getCurrentScope().getPropagationContext(), + sampleRand: 0.85, + }); + Sentry.startSpan({ op: 'ui.interaction.click', name: 'new-trace' }, async () => { + await fetch('http://sentry-test-site.example'); + }); + }); +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/template.html b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/template.html new file mode 100644 index 000000000000..11b051919b55 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/template.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/test.ts new file mode 100644 index 000000000000..616c89cd66f8 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/test.ts @@ -0,0 +1,89 @@ +import { expect } from '@playwright/test'; +import { sentryTest } from '../../../../utils/fixtures'; +import type { EventAndTraceHeader } from '../../../../utils/helpers'; +import { + eventAndTraceHeaderRequestParser, + getFirstSentryEnvelopeRequest, + shouldSkipTracingTest, + waitForTransactionRequest, +} from '../../../../utils/helpers'; + +sentryTest( + 'new trace started with `startNewTrace` is sampled according to the `tracesSampler`', + async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://sentry-test-site.example/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); + + const [pageloadEvent, pageloadTraceHeaders] = await getFirstSentryEnvelopeRequest( + page, + url, + eventAndTraceHeaderRequestParser, + ); + + const pageloadTraceContext = pageloadEvent.contexts?.trace; + + expect(pageloadEvent.type).toEqual('transaction'); + + expect(pageloadTraceContext).toMatchObject({ + op: 'pageload', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + data: { + 'sentry.sample_rate': 0.5, + }, + }); + expect(pageloadTraceContext).not.toHaveProperty('parent_span_id'); + + expect(pageloadTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '0.5', + sampled: 'true', + trace_id: pageloadTraceContext?.trace_id, + sample_rand: '0.45', + }); + + const transactionPromise = waitForTransactionRequest(page, event => { + return event.transaction === 'new-trace'; + }); + + await page.locator('#newTrace').click(); + + const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] = eventAndTraceHeaderRequestParser( + await transactionPromise, + ); + + const newTraceTransactionTraceContext = newTraceTransactionEvent.contexts?.trace; + expect(newTraceTransactionTraceContext).toMatchObject({ + op: 'ui.interaction.click', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + data: { + 'sentry.sample_rate': 0.9, + }, + }); + + expect(newTraceTransactionTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '0.9', + sampled: 'true', + trace_id: newTraceTransactionTraceContext?.trace_id, + transaction: 'new-trace', + sample_rand: '0.85', + }); + + expect(newTraceTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id); + }, +); From 4a82d789112f76f2d669a663691bc94bc6ae409f Mon Sep 17 00:00:00 2001 From: Francesco Gringl-Novy Date: Wed, 25 Jun 2025 12:54:29 +0200 Subject: [PATCH 2/2] Update dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js Co-authored-by: Sigrid Huemer <32902192+s1gr1d@users.noreply.github.com> --- .../tracing/trace-lifetime/startNewTraceSampling/subject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js index ac69f262cf34..711620998cb2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTraceSampling/subject.js @@ -1,7 +1,7 @@ const newTraceBtn = document.getElementById('newTrace'); newTraceBtn.addEventListener('click', async () => { Sentry.startNewTrace(() => { - // We want top ensure the new trace is sampled, so we force the sample_rand to a value above 0.9 + // We want to ensure the new trace is sampled, so we force the sample_rand to a value above 0.9 Sentry.getCurrentScope().setPropagationContext({ ...Sentry.getCurrentScope().getPropagationContext(), sampleRand: 0.85,