-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(browser): Add test for current DSC transaction name updating beh…
…avior (#13953) Add a browser integration test that describes the current behaviour of how we update the `transaction` field in the DSC which is propagated via the `baggage` header and added to envelopes as the `trace` header.
- Loading branch information
Showing
11 changed files
with
599 additions
and
0 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/init.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import * as Sentry from '@sentry/browser'; | ||
|
||
window.Sentry = Sentry; | ||
|
||
Sentry.init({ | ||
dsn: 'https://[email protected]/1337', | ||
integrations: [Sentry.browserTracingIntegration({ instrumentNavigation: false, instrumentPageLoad: false })], | ||
tracesSampleRate: 1, | ||
tracePropagationTargets: ['example.com'], | ||
release: '1.1.1', | ||
}); |
34 changes: 34 additions & 0 deletions
34
dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/subject.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
const btnStartSpan = document.getElementById('btnStartSpan'); | ||
const btnUpdateName = document.getElementById('btnUpdateName'); | ||
const btnMakeRequest = document.getElementById('btnMakeRequest'); | ||
const btnCaptureError = document.getElementById('btnCaptureError'); | ||
const btnEndSpan = document.getElementById('btnEndSpan'); | ||
|
||
btnStartSpan.addEventListener('click', () => { | ||
Sentry.startSpanManual( | ||
{ name: 'test-root-span', attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' } }, | ||
async span => { | ||
window.__traceId = span.spanContext().traceId; | ||
await new Promise(resolve => { | ||
btnEndSpan.addEventListener('click', resolve); | ||
}); | ||
span.end(); | ||
}, | ||
); | ||
}); | ||
|
||
let updateCnt = 0; | ||
btnUpdateName.addEventListener('click', () => { | ||
const span = Sentry.getActiveSpan(); | ||
const rootSpan = Sentry.getRootSpan(span); | ||
rootSpan.updateName(`updated-root-span-${++updateCnt}`); | ||
rootSpan.setAttribute(Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); | ||
}); | ||
|
||
btnMakeRequest.addEventListener('click', () => { | ||
fetch('https://example.com/api'); | ||
}); | ||
|
||
btnCaptureError.addEventListener('click', () => { | ||
Sentry.captureException(new Error('test-error')); | ||
}); |
5 changes: 5 additions & 0 deletions
5
dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/template.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<button id="btnStartSpan">Start Span</button> | ||
<button id="btnUpdateName">Update Name</button> | ||
<button id="btnMakeRequest">Make Request</button> | ||
<button id="btnCaptureError">Capture Error</button> | ||
<button id="btnEndSpan">End Span</button> |
185 changes: 185 additions & 0 deletions
185
dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import { expect } from '@playwright/test'; | ||
import type { Page } from '@playwright/test'; | ||
import type { DynamicSamplingContext } from '@sentry/types'; | ||
import { sentryTest } from '../../../utils/fixtures'; | ||
import type { EventAndTraceHeader } from '../../../utils/helpers'; | ||
import { | ||
eventAndTraceHeaderRequestParser, | ||
getMultipleSentryEnvelopeRequests, | ||
shouldSkipTracingTest, | ||
} from '../../../utils/helpers'; | ||
|
||
sentryTest('updates the DSC when the txn name is updated and high-quality', async ({ getLocalTestUrl, page }) => { | ||
if (shouldSkipTracingTest()) { | ||
sentryTest.skip(); | ||
} | ||
|
||
const url = await getLocalTestUrl({ testDir: __dirname }); | ||
|
||
await page.goto(url); | ||
|
||
/* | ||
Test Steps: | ||
1. Start new span with LQ txn name (source: url) | ||
2. Make request and check that baggage has no transaction name | ||
3. Capture error and check that envelope trace header has no transaction name | ||
4. Update span name and source to HQ (source: route) | ||
5. Make request and check that baggage has HQ txn name | ||
6. Capture error and check that envelope trace header has HQ txn name | ||
7. Update span name again with HQ name (source: route) | ||
8. Make request and check that baggage has updated HQ txn name | ||
9. Capture error and check that envelope trace header has updated HQ txn name | ||
10. End span and check that envelope trace header has updated HQ txn name | ||
11. Make another request and check that there's no span information in baggage | ||
12. Capture an error and check that envelope trace header has no span information | ||
*/ | ||
|
||
// 1 | ||
await page.locator('#btnStartSpan').click(); | ||
const traceId = await page.evaluate(() => { | ||
return (window as any).__traceId; | ||
}); | ||
|
||
expect(traceId).toMatch(/^[0-9a-f]{32}$/); | ||
|
||
// 2 | ||
const baggageItems = await makeRequestAndGetBaggageItems(page); | ||
expect(baggageItems).toEqual([ | ||
'sentry-environment=production', | ||
'sentry-public_key=public', | ||
'sentry-release=1.1.1', | ||
'sentry-sample_rate=1', | ||
'sentry-sampled=true', | ||
`sentry-trace_id=${traceId}`, | ||
]); | ||
|
||
// 3 | ||
const errorEnvelopeTraceHeader = await captureErrorAndGetEnvelopeTraceHeader(page); | ||
expect(errorEnvelopeTraceHeader).toEqual({ | ||
environment: 'production', | ||
public_key: 'public', | ||
release: '1.1.1', | ||
sample_rate: '1', | ||
sampled: 'true', | ||
trace_id: traceId, | ||
}); | ||
|
||
// 4 | ||
await page.locator('#btnUpdateName').click(); | ||
|
||
// 5 | ||
const baggageItemsAfterUpdate = await makeRequestAndGetBaggageItems(page); | ||
expect(baggageItemsAfterUpdate).toEqual([ | ||
'sentry-environment=production', | ||
'sentry-public_key=public', | ||
'sentry-release=1.1.1', | ||
'sentry-sample_rate=1', | ||
'sentry-sampled=true', | ||
`sentry-trace_id=${traceId}`, | ||
'sentry-transaction=updated-root-span-1', | ||
]); | ||
|
||
// 6 | ||
const errorEnvelopeTraceHeaderAfterUpdate = await captureErrorAndGetEnvelopeTraceHeader(page); | ||
expect(errorEnvelopeTraceHeaderAfterUpdate).toEqual({ | ||
environment: 'production', | ||
public_key: 'public', | ||
release: '1.1.1', | ||
sample_rate: '1', | ||
sampled: 'true', | ||
trace_id: traceId, | ||
transaction: 'updated-root-span-1', | ||
}); | ||
|
||
// 7 | ||
await page.locator('#btnUpdateName').click(); | ||
|
||
// 8 | ||
const baggageItemsAfterSecondUpdate = await makeRequestAndGetBaggageItems(page); | ||
expect(baggageItemsAfterSecondUpdate).toEqual([ | ||
'sentry-environment=production', | ||
'sentry-public_key=public', | ||
'sentry-release=1.1.1', | ||
'sentry-sample_rate=1', | ||
'sentry-sampled=true', | ||
`sentry-trace_id=${traceId}`, | ||
'sentry-transaction=updated-root-span-2', | ||
]); | ||
|
||
// 9 | ||
const errorEnvelopeTraceHeaderAfterSecondUpdate = await captureErrorAndGetEnvelopeTraceHeader(page); | ||
expect(errorEnvelopeTraceHeaderAfterSecondUpdate).toEqual({ | ||
environment: 'production', | ||
public_key: 'public', | ||
release: '1.1.1', | ||
sample_rate: '1', | ||
sampled: 'true', | ||
trace_id: traceId, | ||
transaction: 'updated-root-span-2', | ||
}); | ||
|
||
// 10 | ||
const txnEventPromise = getMultipleSentryEnvelopeRequests<EventAndTraceHeader>( | ||
page, | ||
1, | ||
{ envelopeType: 'transaction' }, | ||
eventAndTraceHeaderRequestParser, | ||
); | ||
|
||
await page.locator('#btnEndSpan').click(); | ||
|
||
const [txnEvent, txnEnvelopeTraceHeader] = (await txnEventPromise)[0]; | ||
expect(txnEnvelopeTraceHeader).toEqual({ | ||
environment: 'production', | ||
public_key: 'public', | ||
release: '1.1.1', | ||
sample_rate: '1', | ||
sampled: 'true', | ||
trace_id: traceId, | ||
transaction: 'updated-root-span-2', | ||
}); | ||
|
||
expect(txnEvent.transaction).toEqual('updated-root-span-2'); | ||
|
||
// 11 | ||
const baggageItemsAfterEnd = await makeRequestAndGetBaggageItems(page); | ||
expect(baggageItemsAfterEnd).toEqual([ | ||
'sentry-environment=production', | ||
'sentry-public_key=public', | ||
'sentry-release=1.1.1', | ||
`sentry-trace_id=${traceId}`, | ||
]); | ||
|
||
// 12 | ||
const errorEnvelopeTraceHeaderAfterEnd = await captureErrorAndGetEnvelopeTraceHeader(page); | ||
expect(errorEnvelopeTraceHeaderAfterEnd).toEqual({ | ||
environment: 'production', | ||
public_key: 'public', | ||
release: '1.1.1', | ||
trace_id: traceId, | ||
}); | ||
}); | ||
|
||
async function makeRequestAndGetBaggageItems(page: Page): Promise<string[]> { | ||
const requestPromise = page.waitForRequest('https://example.com/*'); | ||
await page.locator('#btnMakeRequest').click(); | ||
const request = await requestPromise; | ||
|
||
const baggage = await request.headerValue('baggage'); | ||
|
||
return baggage?.split(',').sort() ?? []; | ||
} | ||
|
||
async function captureErrorAndGetEnvelopeTraceHeader(page: Page): Promise<DynamicSamplingContext | undefined> { | ||
const errorEventPromise = getMultipleSentryEnvelopeRequests<EventAndTraceHeader>( | ||
page, | ||
1, | ||
{ envelopeType: 'event' }, | ||
eventAndTraceHeaderRequestParser, | ||
); | ||
|
||
await page.locator('#btnCaptureError').click(); | ||
|
||
const [, errorEnvelopeTraceHeader] = (await errorEventPromise)[0]; | ||
return errorEnvelopeTraceHeader; | ||
} |
16 changes: 16 additions & 0 deletions
16
...packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/subject.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const errorBtn = document.getElementById('errorBtn'); | ||
errorBtn.addEventListener('click', () => { | ||
throw new Error(`Sentry Test Error ${Math.random()}`); | ||
}); | ||
|
||
const fetchBtn = document.getElementById('fetchBtn'); | ||
fetchBtn.addEventListener('click', async () => { | ||
await fetch('http://example.com'); | ||
}); | ||
|
||
const xhrBtn = document.getElementById('xhrBtn'); | ||
xhrBtn.addEventListener('click', () => { | ||
const xhr = new XMLHttpRequest(); | ||
xhr.open('GET', 'http://example.com'); | ||
xhr.send(); | ||
}); |
Oops, something went wrong.