From 1ad134c00b28142930c4dbc9d752236f8ec16f32 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 16 Apr 2024 17:56:35 +0200 Subject: [PATCH 1/2] test(browser-integration-tests): Add trace lifetime tests in TwP scenario --- .../suites/tracing/trace-lifetime/README.md | 1 + .../suites/tracing/trace-lifetime/subject.js | 2 +- .../tracing-without-performance/init.js | 10 ++ .../tracing-without-performance/template.html | 15 +++ .../tracing-without-performance/test.ts | 106 ++++++++++++++++++ 5 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/init.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/template.html create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/README.md b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/README.md index d7330f233425..3413aac3bcbf 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/README.md +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/README.md @@ -5,5 +5,6 @@ connected to a trace. This suite distinguishes the following cases: 2. `pageload-meta` - Traces started on the initial pageload as a continuation of the trace on the server (via `` tags) 3. `navigation` - Traces started during navigations on a page +4. `tracing-without-performance` - Traces originating from an app configured for "Tracing without Performance". Tests scenarios should be fairly similar for all three cases but it's important we test all of them. diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/subject.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/subject.js index 71e03b3c8a7c..9528f861a723 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/subject.js +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/subject.js @@ -1,6 +1,6 @@ const errorBtn = document.getElementById('errorBtn'); errorBtn.addEventListener('click', () => { - throw new Error('Sentry Test Error'); + throw new Error(`Sentry Test Error ${Math.random()}`); }); const fetchBtn = document.getElementById('fetchBtn'); diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/init.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/init.js new file mode 100644 index 000000000000..c273986e1a94 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/init.js @@ -0,0 +1,10 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + // in browser TwP means not setting tracesSampleRate but adding browserTracingIntegration, + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [Sentry.browserTracingIntegration()], + tracePropagationTargets: ['http://example.com'], +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/template.html b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/template.html new file mode 100644 index 000000000000..7cf101e4cf9e --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/template.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts new file mode 100644 index 000000000000..fb187e102dcd --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts @@ -0,0 +1,106 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/types'; +import { sentryTest } from '../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; + +const META_TAG_TRACE_ID = '12345678901234567890123456789012'; +const META_TAG_PARENT_SPAN_ID = '1234567890123456'; +const META_TAG_BAGGAGE = + 'sentry-trace_id=12345678901234567890123456789012,sentry-public_key=public,sentry-release=1.0.0,sentry-environment=prod'; + +sentryTest('error has new traceId after navigation', async ({ getLocalTestPath, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestPath({ testDir: __dirname }); + await page.goto(url); + + const errorEventPromise = getFirstSentryEnvelopeRequest(page); + await page.locator('#errorBtn').click(); + const errorEvent = await errorEventPromise; + + expect(errorEvent.contexts?.trace).toEqual({ + trace_id: META_TAG_TRACE_ID, + parent_span_id: META_TAG_PARENT_SPAN_ID, + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + + // await page.goto(); + + const errorEventPromise2 = getFirstSentryEnvelopeRequest(page, `${url}#navigation`); + await page.locator('#errorBtn').click(); + const errorEvent2 = await errorEventPromise2; + + expect(errorEvent2.contexts?.trace).toEqual({ + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + expect(errorEvent2.contexts?.trace?.trace_id).not.toBe(META_TAG_TRACE_ID); +}); + +sentryTest('outgoing fetch requests have new traceId after navigation', async ({ getLocalTestPath, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestPath({ testDir: __dirname }); + await page.goto(url); + + const requestPromise = page.waitForRequest('http://example.com/*'); + await page.locator('#fetchBtn').click(); + const request = await requestPromise; + const headers = request.headers(); + + // sampling decision is deferred because TwP means we didn't sample any span + expect(headers['sentry-trace']).toMatch(new RegExp(`^${META_TAG_TRACE_ID}-[0-9a-f]{16}$`)); + expect(headers['baggage']).toBe(META_TAG_BAGGAGE); + + await page.goto(`${url}#navigation`); + + const requestPromise2 = page.waitForRequest('http://example.com/*'); + await page.locator('#fetchBtn').click(); + const request2 = await requestPromise2; + const headers2 = request2.headers(); + + // sampling decision is deferred because TwP means we didn't sample any span + expect(headers2['sentry-trace']).toMatch(/^[0-9a-f]{32}-[0-9a-f]{16}$/); + expect(headers2['baggage']).not.toBe(`${META_TAG_TRACE_ID}-${META_TAG_PARENT_SPAN_ID}`); + expect(headers2['baggage']).toMatch( + /sentry-environment=production,sentry-public_key=public,sentry-trace_id=[0-9a-f]{32}/, + ); + expect(headers2['baggage']).not.toContain(`sentry-trace_id=${META_TAG_TRACE_ID}`); +}); + +sentryTest('outgoing XHR requests have new traceId after navigation', async ({ getLocalTestPath, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestPath({ testDir: __dirname }); + await page.goto(url); + + const requestPromise = page.waitForRequest('http://example.com/*'); + await page.locator('#xhrBtn').click(); + const request = await requestPromise; + const headers = request.headers(); + + // sampling decision is deferred because TwP means we didn't sample any span + expect(headers['sentry-trace']).toMatch(new RegExp(`^${META_TAG_TRACE_ID}-[0-9a-f]{16}$`)); + expect(headers['baggage']).toBe(META_TAG_BAGGAGE); + + await page.goto(`${url}#navigation`); + + const requestPromise2 = page.waitForRequest('http://example.com/*'); + await page.locator('#xhrBtn').click(); + const request2 = await requestPromise2; + const headers2 = request2.headers(); + + // sampling decision is deferred because TwP means we didn't sample any span + expect(headers2['sentry-trace']).toMatch(/^[0-9a-f]{32}-[0-9a-f]{16}$/); + expect(headers2['baggage']).not.toBe(`${META_TAG_TRACE_ID}-${META_TAG_PARENT_SPAN_ID}`); + expect(headers2['baggage']).toMatch( + /sentry-environment=production,sentry-public_key=public,sentry-trace_id=[0-9a-f]{32}/, + ); + expect(headers2['baggage']).not.toContain(`sentry-trace_id=${META_TAG_TRACE_ID}`); +}); From 5ea734df7258305cc81e8834c9254e736b6ee6c7 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 16 Apr 2024 18:03:51 +0200 Subject: [PATCH 2/2] cleanup --- .../tracing/trace-lifetime/tracing-without-performance/test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts index fb187e102dcd..151842337970 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/tracing-without-performance/test.ts @@ -26,8 +26,6 @@ sentryTest('error has new traceId after navigation', async ({ getLocalTestPath, span_id: expect.stringMatching(/^[0-9a-f]{16}$/), }); - // await page.goto(); - const errorEventPromise2 = getFirstSentryEnvelopeRequest(page, `${url}#navigation`); await page.locator('#errorBtn').click(); const errorEvent2 = await errorEventPromise2;