From 46b1cd134ad7e90966e6ee3e2ee35438935dbaeb Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Tue, 28 Jul 2026 11:08:07 +0200 Subject: [PATCH] test(e2e): Assert TTID/TTFD spans share their navigation transaction's trace and parent span The e2e suite already asserts navigation transactions carry TTID/TTFD measurements, but did not verify the underlying display spans inherit the transaction's trace_id and reference its root span as parent_span_id. Add that end-to-end guard against orphaned display spans. Closes #6529 Co-Authored-By: Claude Opus 4.8 --- ...reSpaceflightNewsScreenTransaction.test.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/samples/react-native/e2e/tests/captureSpaceflightNewsScreenTransaction/captureSpaceflightNewsScreenTransaction.test.ts b/samples/react-native/e2e/tests/captureSpaceflightNewsScreenTransaction/captureSpaceflightNewsScreenTransaction.test.ts index 4d0b3559fb..fe48311072 100644 --- a/samples/react-native/e2e/tests/captureSpaceflightNewsScreenTransaction/captureSpaceflightNewsScreenTransaction.test.ts +++ b/samples/react-native/e2e/tests/captureSpaceflightNewsScreenTransaction/captureSpaceflightNewsScreenTransaction.test.ts @@ -84,6 +84,36 @@ describe('Capture Spaceflight News Screen Transaction', () => { }); }); + it('ttid/ttfd spans share the same trace and parent span as their navigation transaction', async () => { + // Display spans must inherit the navigation transaction's `trace_id` (not + // get a random one) and reference its root span as their `parent_span_id`, + // otherwise they render as orphaned spans in the trace view. + const transaction = getFirstNewsEventItem()?.[1]; + expect(transaction).toBeDefined(); + + const traceId = transaction?.contexts?.trace?.trace_id; + const rootSpanId = transaction?.contexts?.trace?.span_id; + expect(traceId).toEqual(expect.any(String)); + expect(rootSpanId).toEqual(expect.any(String)); + + const ttidSpan = transaction?.spans?.find( + span => span.op === 'ui.load.initial_display', + ); + const ttfdSpan = transaction?.spans?.find( + span => span.op === 'ui.load.full_display', + ); + + // A navigation transaction must at least carry the initial-display span. + expect(ttidSpan).toBeDefined(); + + [ttidSpan, ttfdSpan] + .filter((span): span is NonNullable => span !== undefined) + .forEach(span => { + expect(span.trace_id).toBe(traceId); + expect(span.parent_span_id).toBe(rootSpanId); + }); + }); + function expectToContainTimeToDisplayMeasurements( item: EventItem | undefined, ) {