diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts index 56de5715b102..cd5c25237eb7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts @@ -9,12 +9,12 @@ import { shouldSkipTracingTest, } from '../../../../utils/helpers'; -sentryTest('creates a new trace on each navigation', async ({ getLocalTestPath, page }) => { +sentryTest('creates a new trace on each navigation', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); await getFirstSentryEnvelopeRequest(page, url); @@ -32,6 +32,9 @@ sentryTest('creates a new trace on each navigation', async ({ getLocalTestPath, const navigation1TraceContext = navigation1Event.contexts?.trace; const navigation2TraceContext = navigation2Event.contexts?.trace; + expect(navigation1Event.type).toEqual('transaction'); + expect(navigation2Event.type).toEqual('transaction'); + expect(navigation1TraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -65,12 +68,12 @@ sentryTest('creates a new trace on each navigation', async ({ getLocalTestPath, expect(navigation1TraceContext?.trace_id).not.toEqual(navigation2TraceContext?.trace_id); }); -sentryTest('error after navigation has navigation traceId', async ({ getLocalTestPath, page }) => { +sentryTest('error after navigation has navigation traceId', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); // ensure pageload transaction is finished await getFirstSentryEnvelopeRequest(page, url); @@ -82,6 +85,8 @@ sentryTest('error after navigation has navigation traceId', async ({ getLocalTes ); const navigationTraceContext = navigationEvent.contexts?.trace; + expect(navigationEvent.type).toEqual('transaction'); + expect(navigationTraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -105,6 +110,8 @@ sentryTest('error after navigation has navigation traceId', async ({ getLocalTes await page.locator('#errorBtn').click(); const [errorEvent, errorTraceHeader] = await errorEventPromise; + expect(errorEvent.type).toEqual(undefined); + const errorTraceContext = errorEvent.contexts?.trace; expect(errorTraceContext).toEqual({ trace_id: navigationTraceContext?.trace_id, @@ -119,12 +126,12 @@ sentryTest('error after navigation has navigation traceId', async ({ getLocalTes }); }); -sentryTest('error during navigation has new navigation traceId', async ({ getLocalTestPath, page }) => { +sentryTest('error during navigation has new navigation traceId', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); // ensure navigation transaction is finished await getFirstSentryEnvelopeRequest(page, url); @@ -143,6 +150,9 @@ sentryTest('error during navigation has new navigation traceId', async ({ getLoc const [navigationEvent, navigationTraceHeader] = envelopes.find(envelope => envelope[0].type === 'transaction')!; const [errorEvent, errorTraceHeader] = envelopes.find(envelope => !envelope[0].type)!; + expect(navigationEvent.type).toEqual('transaction'); + expect(errorEvent.type).toEqual(undefined); + const navigationTraceContext = navigationEvent?.contexts?.trace; expect(navigationTraceContext).toMatchObject({ op: 'navigation', @@ -161,14 +171,6 @@ sentryTest('error during navigation has new navigation traceId', async ({ getLoc const errorTraceContext = errorEvent?.contexts?.trace; expect(errorTraceContext).toEqual({ - data: { - 'sentry.op': 'navigation', - 'sentry.origin': 'auto.navigation.browser', - 'sentry.sample_rate': 1, - 'sentry.source': 'url', - }, - op: 'navigation', - origin: 'auto.navigation.browser', trace_id: navigationTraceContext?.trace_id, span_id: expect.stringMatching(/^[0-9a-f]{16}$/), }); @@ -184,12 +186,20 @@ sentryTest('error during navigation has new navigation traceId', async ({ getLoc sentryTest( 'outgoing fetch request after navigation has navigation traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); // ensure navigation transaction is finished await getFirstSentryEnvelopeRequest(page, url); @@ -201,6 +211,8 @@ sentryTest( ); const navigationTraceContext = navigationEvent.contexts?.trace; + + expect(navigationEvent.type).toEqual('transaction'); expect(navigationTraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -232,12 +244,20 @@ sentryTest( sentryTest( 'outgoing fetch request during navigation has navigation traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); // ensure navigation transaction is finished await getFirstSentryEnvelopeRequest(page, url); @@ -256,6 +276,8 @@ sentryTest( ]); const navigationTraceContext = navigationEvent.contexts?.trace; + + expect(navigationEvent.type).toEqual('transaction'); expect(navigationTraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -284,12 +306,20 @@ sentryTest( sentryTest( 'outgoing XHR request after navigation has navigation traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); // ensure navigation transaction is finished await getFirstSentryEnvelopeRequest(page, url); @@ -301,6 +331,8 @@ sentryTest( ); const navigationTraceContext = navigationEvent.contexts?.trace; + + expect(navigationEvent.type).toEqual('transaction'); expect(navigationTraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -332,12 +364,20 @@ sentryTest( sentryTest( 'outgoing XHR request during navigation has navigation traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); // ensure navigation transaction is finished await getFirstSentryEnvelopeRequest(page, url); @@ -356,6 +396,8 @@ sentryTest( ]); const navigationTraceContext = navigationEvent.contexts?.trace; + + expect(navigationEvent.type).toEqual('transaction'); expect(navigationTraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts index 9fd98fe02925..0495c9003579 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts @@ -15,12 +15,12 @@ const META_TAG_BAGGAGE = sentryTest( 'create a new trace for a navigation after the tag pageload trace', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( page, @@ -36,6 +36,7 @@ sentryTest( const pageloadTraceContext = pageloadEvent.contexts?.trace; const navigationTraceContext = navigationEvent.contexts?.trace; + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: META_TAG_TRACE_ID, @@ -53,6 +54,7 @@ sentryTest( trace_id: META_TAG_TRACE_ID, }); + expect(navigationEvent.type).toEqual('transaction'); expect(navigationTraceContext).toMatchObject({ op: 'navigation', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -73,12 +75,12 @@ sentryTest( }, ); -sentryTest('error after tag pageload has pageload traceId', async ({ getLocalTestPath, page }) => { +sentryTest('error after tag pageload has pageload traceId', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( page, @@ -111,6 +113,7 @@ sentryTest('error after tag pageload has pageload traceId', async ({ getL await page.locator('#errorBtn').click(); const [errorEvent, errorTraceHeader] = await errorEventPromise; + expect(errorEvent.type).toEqual(undefined); expect(errorEvent.contexts?.trace).toEqual({ trace_id: META_TAG_TRACE_ID, parent_span_id: META_TAG_PARENT_SPAN_ID, @@ -128,12 +131,12 @@ sentryTest('error after tag pageload has pageload traceId', async ({ getL }); }); -sentryTest('error during tag pageload has pageload traceId', async ({ getLocalTestPath, page }) => { +sentryTest('error during tag pageload has pageload traceId', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); const envelopeRequestsPromise = getMultipleSentryEnvelopeRequests( page, @@ -150,6 +153,7 @@ sentryTest('error during tag pageload has pageload traceId', async ({ get )!; const [errorEvent, errorTraceHeader] = envelopes.find(eventAndHeader => !eventAndHeader[0].type)!; + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadEvent?.contexts?.trace).toMatchObject({ op: 'pageload', trace_id: META_TAG_TRACE_ID, @@ -167,15 +171,8 @@ sentryTest('error during tag pageload has pageload traceId', async ({ get trace_id: META_TAG_TRACE_ID, }); + expect(errorEvent.type).toEqual(undefined); expect(errorEvent?.contexts?.trace).toEqual({ - data: { - 'sentry.op': 'pageload', - 'sentry.origin': 'auto.pageload.browser', - 'sentry.sample_rate': 1, - 'sentry.source': 'url', - }, - op: 'pageload', - origin: 'auto.pageload.browser', trace_id: META_TAG_TRACE_ID, parent_span_id: META_TAG_PARENT_SPAN_ID, span_id: expect.stringMatching(/^[0-9a-f]{16}$/), @@ -194,18 +191,27 @@ sentryTest('error during tag pageload has pageload traceId', async ({ get sentryTest( 'outgoing fetch request after tag pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( page, url, eventAndTraceHeaderRequestParser, ); + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadEvent?.contexts?.trace).toMatchObject({ op: 'pageload', trace_id: META_TAG_TRACE_ID, @@ -236,12 +242,20 @@ sentryTest( sentryTest( 'outgoing fetch request during tag pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); const pageloadEventPromise = getFirstSentryEnvelopeRequest( page, @@ -253,6 +267,7 @@ sentryTest( await page.locator('#fetchBtn').click(); const [[pageloadEvent, pageloadTraceHeader], request] = await Promise.all([pageloadEventPromise, requestPromise]); + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadEvent?.contexts?.trace).toMatchObject({ op: 'pageload', trace_id: META_TAG_TRACE_ID, @@ -280,18 +295,27 @@ sentryTest( sentryTest( 'outgoing XHR request after tag pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); + + const url = await getLocalTestUrl({ testDir: __dirname }); const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( page, url, eventAndTraceHeaderRequestParser, ); + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadEvent?.contexts?.trace).toMatchObject({ op: 'pageload', trace_id: META_TAG_TRACE_ID, @@ -321,12 +345,20 @@ sentryTest( sentryTest( 'outgoing XHR request during tag pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); + + const url = await getLocalTestUrl({ testDir: __dirname }); const pageloadEventPromise = getFirstSentryEnvelopeRequest( page, @@ -338,6 +370,7 @@ sentryTest( await page.locator('#xhrBtn').click(); const [[pageloadEvent, pageloadTraceHeader], request] = await Promise.all([pageloadEventPromise, requestPromise]); + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadEvent?.contexts?.trace).toMatchObject({ op: 'pageload', trace_id: META_TAG_TRACE_ID, diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts index 7ad9bb34f00b..e167c63d626e 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts @@ -10,12 +10,12 @@ import { sentryTest( 'should create a new trace for a navigation after the initial pageload', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); const [pageloadEvent, pageloadTraceHeaders] = await getFirstSentryEnvelopeRequest( page, @@ -31,6 +31,9 @@ sentryTest( const pageloadTraceContext = pageloadEvent.contexts?.trace; const navigationTraceContext = navigationEvent.contexts?.trace; + expect(pageloadEvent.type).toEqual('transaction'); + expect(navigationEvent.type).toEqual('transaction'); + expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -65,12 +68,12 @@ sentryTest( }, ); -sentryTest('error after pageload has pageload traceId', async ({ getLocalTestPath, page }) => { +sentryTest('error after pageload has pageload traceId', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( page, @@ -79,6 +82,7 @@ sentryTest('error after pageload has pageload traceId', async ({ getLocalTestPat ); const pageloadTraceContext = pageloadEvent.contexts?.trace; + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -103,6 +107,7 @@ sentryTest('error after pageload has pageload traceId', async ({ getLocalTestPat const [errorEvent, errorTraceHeader] = await errorEventPromise; const errorTraceContext = errorEvent.contexts?.trace; + expect(errorEvent.type).toEqual(undefined); expect(errorTraceContext).toEqual({ trace_id: pageloadTraceContext?.trace_id, @@ -118,12 +123,12 @@ sentryTest('error after pageload has pageload traceId', async ({ getLocalTestPat }); }); -sentryTest('error during pageload has pageload traceId', async ({ getLocalTestPath, page }) => { +sentryTest('error during pageload has pageload traceId', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); const envelopeRequestsPromise = getMultipleSentryEnvelopeRequests( page, @@ -141,6 +146,8 @@ sentryTest('error during pageload has pageload traceId', async ({ getLocalTestPa const [errorEvent, errorTraceHeader] = envelopes.find(eventAndHeader => !eventAndHeader[0].type)!; const pageloadTraceContext = pageloadEvent?.contexts?.trace; + + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -157,15 +164,9 @@ sentryTest('error during pageload has pageload traceId', async ({ getLocalTestPa }); const errorTraceContext = errorEvent?.contexts?.trace; + + expect(errorEvent.type).toEqual(undefined); expect(errorTraceContext).toEqual({ - data: { - 'sentry.op': 'pageload', - 'sentry.origin': 'auto.pageload.browser', - 'sentry.sample_rate': 1, - 'sentry.source': 'url', - }, - op: 'pageload', - origin: 'auto.pageload.browser', trace_id: pageloadTraceContext?.trace_id, span_id: expect.stringMatching(/^[0-9a-f]{16}$/), }); @@ -181,12 +182,20 @@ sentryTest('error during pageload has pageload traceId', async ({ getLocalTestPa sentryTest( 'outgoing fetch request after pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( page, @@ -196,6 +205,7 @@ sentryTest( const pageloadTraceContext = pageloadEvent.contexts?.trace; const pageloadTraceId = pageloadTraceContext?.trace_id; + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -226,12 +236,20 @@ sentryTest( sentryTest( 'outgoing fetch request during pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); const pageloadEventPromise = getFirstSentryEnvelopeRequest( page, @@ -246,6 +264,7 @@ sentryTest( const pageloadTraceContext = pageloadEvent.contexts?.trace; const pageloadTraceId = pageloadTraceContext?.trace_id; + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), @@ -271,59 +290,73 @@ sentryTest( }, ); -sentryTest( - 'outgoing XHR request after pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { - if (shouldSkipTracingTest()) { - sentryTest.skip(); - } - - const url = await getLocalTestPath({ testDir: __dirname }); +sentryTest('outgoing XHR request after pageload has pageload traceId in headers', async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } - const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( - page, - url, - eventAndTraceHeaderRequestParser, - ); - const pageloadTraceContext = pageloadEvent.contexts?.trace; - const pageloadTraceId = pageloadTraceContext?.trace_id; + const url = await getLocalTestUrl({ testDir: __dirname }); - expect(pageloadTraceContext).toMatchObject({ - op: 'pageload', - trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), - span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), }); - expect(pageloadTraceContext).not.toHaveProperty('parent_span_id'); + }); - expect(pageloadTraceHeader).toEqual({ - environment: 'production', - public_key: 'public', - sample_rate: '1', - sampled: 'true', - trace_id: pageloadTraceId, - }); + const [pageloadEvent, pageloadTraceHeader] = await getFirstSentryEnvelopeRequest( + page, + url, + eventAndTraceHeaderRequestParser, + ); + const pageloadTraceContext = pageloadEvent.contexts?.trace; + const pageloadTraceId = pageloadTraceContext?.trace_id; - const requestPromise = page.waitForRequest('http://example.com/*'); - await page.locator('#xhrBtn').click(); - const request = await requestPromise; - const headers = request.headers(); + 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}$/), + }); + expect(pageloadTraceContext).not.toHaveProperty('parent_span_id'); - // sampling decision and DSC are continued from the pageload span even after it ended - expect(headers['sentry-trace']).toMatch(new RegExp(`^${pageloadTraceId}-[0-9a-f]{16}-1$`)); - expect(headers['baggage']).toEqual( - `sentry-environment=production,sentry-public_key=public,sentry-trace_id=${pageloadTraceId},sentry-sample_rate=1,sentry-sampled=true`, - ); - }, -); + expect(pageloadTraceHeader).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: pageloadTraceId, + }); + + const requestPromise = page.waitForRequest('http://example.com/*'); + await page.locator('#xhrBtn').click(); + const request = await requestPromise; + const headers = request.headers(); + + // sampling decision and DSC are continued from the pageload span even after it ended + expect(headers['sentry-trace']).toMatch(new RegExp(`^${pageloadTraceId}-[0-9a-f]{16}-1$`)); + expect(headers['baggage']).toEqual( + `sentry-environment=production,sentry-public_key=public,sentry-trace_id=${pageloadTraceId},sentry-sample_rate=1,sentry-sampled=true`, + ); +}); sentryTest( 'outgoing XHR request during pageload has pageload traceId in headers', - async ({ getLocalTestPath, page }) => { + async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); const pageloadEventPromise = getFirstSentryEnvelopeRequest( page, @@ -338,6 +371,7 @@ sentryTest( const pageloadTraceContext = pageloadEvent.contexts?.trace; const pageloadTraceId = pageloadTraceContext?.trace_id; + expect(pageloadEvent.type).toEqual('transaction'); expect(pageloadTraceContext).toMatchObject({ op: 'pageload', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), 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 6bc7b634b25f..76a618f79989 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 @@ -12,12 +12,12 @@ 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 }) => { +sentryTest('error has new traceId after navigation', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); await page.goto(url); const errorEventPromise = getFirstSentryEnvelopeRequest( @@ -28,6 +28,7 @@ sentryTest('error has new traceId after navigation', async ({ getLocalTestPath, await page.locator('#errorBtn').click(); const [errorEvent, errorTraceHeader] = await errorEventPromise; + expect(errorEvent.type).toEqual(undefined); expect(errorEvent.contexts?.trace).toEqual({ trace_id: META_TAG_TRACE_ID, parent_span_id: META_TAG_PARENT_SPAN_ID, @@ -63,12 +64,21 @@ sentryTest('error has new traceId after navigation', async ({ getLocalTestPath, expect(errorEvent2.contexts?.trace?.trace_id).not.toBe(META_TAG_TRACE_ID); }); -sentryTest('outgoing fetch requests have new traceId after navigation', async ({ getLocalTestPath, page }) => { +sentryTest('outgoing fetch requests have new traceId after navigation', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); + await page.goto(url); const requestPromise = page.waitForRequest('http://example.com/*'); @@ -96,12 +106,21 @@ sentryTest('outgoing fetch requests have new traceId after navigation', async ({ expect(headers2['baggage']).not.toContain(`sentry-trace_id=${META_TAG_TRACE_ID}`); }); -sentryTest('outgoing XHR requests have new traceId after navigation', async ({ getLocalTestPath, page }) => { +sentryTest('outgoing XHR requests have new traceId after navigation', async ({ getLocalTestUrl, page }) => { if (shouldSkipTracingTest()) { sentryTest.skip(); } - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); + await page.goto(url); const requestPromise = page.waitForRequest('http://example.com/*'); diff --git a/packages/core/src/tracing/sentrySpan.ts b/packages/core/src/tracing/sentrySpan.ts index 31fd35bc4b68..1bde4649cf89 100644 --- a/packages/core/src/tracing/sentrySpan.ts +++ b/packages/core/src/tracing/sentrySpan.ts @@ -32,7 +32,7 @@ import { getStatusMessage, spanTimeInputToSeconds, spanToJSON, - spanToTraceContext, + spanToTransactionTraceContext, } from '../utils/spanUtils'; import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext'; import { logSpanEnd } from './logSpans'; @@ -275,7 +275,7 @@ export class SentrySpan implements Span { const transaction: TransactionEvent = { contexts: { - trace: spanToTraceContext(this), + trace: spanToTransactionTraceContext(this), }, spans, start_timestamp: this._startTime, diff --git a/packages/core/src/utils/applyScopeDataToEvent.ts b/packages/core/src/utils/applyScopeDataToEvent.ts index b41aa2bb4818..f3b1ac0d0be7 100644 --- a/packages/core/src/utils/applyScopeDataToEvent.ts +++ b/packages/core/src/utils/applyScopeDataToEvent.ts @@ -161,7 +161,10 @@ function applySdkMetadataToEvent(event: Event, sdkProcessingMetadata: ScopeData[ } function applySpanToEvent(event: Event, span: Span): void { - event.contexts = { trace: spanToTraceContext(span), ...event.contexts }; + event.contexts = { + trace: spanToTraceContext(span), + ...event.contexts, + }; event.sdkProcessingMetadata = { dynamicSamplingContext: getDynamicSamplingContextFromSpan(span), diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index b4fb587dd5d3..55b3df65aa2b 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -31,22 +31,34 @@ export const TRACE_FLAG_SAMPLED = 0x1; /** * Convert a span to a trace context, which can be sent as the `trace` context in an event. + * By default, this will only include trace_id, span_id & parent_span_id. + * If `includeAllData` is true, it will also include data, op, status & origin. */ -export function spanToTraceContext(span: Span): TraceContext { +export function spanToTransactionTraceContext(span: Span): TraceContext { const { spanId: span_id, traceId: trace_id } = span.spanContext(); const { data, op, parent_span_id, status, origin } = spanToJSON(span); return dropUndefinedKeys({ - data, - op, parent_span_id, span_id, - status, trace_id, + data, + op, + status, origin, }); } +/** + * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event. + */ +export function spanToTraceContext(span: Span): TraceContext { + const { spanId: span_id, traceId: trace_id } = span.spanContext(); + const { parent_span_id } = spanToJSON(span); + + return dropUndefinedKeys({ parent_span_id, span_id, trace_id }); +} + /** * Convert a Span to a Sentry trace header. */ diff --git a/packages/core/test/lib/tracing/sentrySpan.test.ts b/packages/core/test/lib/tracing/sentrySpan.test.ts index 6ed12488000c..13d52149bb8b 100644 --- a/packages/core/test/lib/tracing/sentrySpan.test.ts +++ b/packages/core/test/lib/tracing/sentrySpan.test.ts @@ -1,7 +1,7 @@ import { timestampInSeconds } from '@sentry/utils'; import { SentrySpan } from '../../../src/tracing/sentrySpan'; import { SPAN_STATUS_ERROR } from '../../../src/tracing/spanstatus'; -import { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, spanToJSON, spanToTraceContext } from '../../../src/utils/spanUtils'; +import { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, spanToJSON } from '../../../src/utils/spanUtils'; describe('SentrySpan', () => { describe('name', () => { @@ -33,7 +33,7 @@ describe('SentrySpan', () => { test('setStatus', () => { const span = new SentrySpan({}); span.setStatus({ code: SPAN_STATUS_ERROR, message: 'permission_denied' }); - expect(spanToTraceContext(span).status).toBe('permission_denied'); + expect(spanToJSON(span).status).toBe('permission_denied'); }); });