Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { solidRouterBrowserTracingIntegration } from '@sentry/solidstart/solidro
import { StartClient, mount } from '@solidjs/start/client';

Sentry.init({
traceLifecycle: 'static',
// We can't use env variables here, seems like they are stripped
// out in production builds.
dsn: 'https://public@dsn.ingest.sentry.io/1337',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as Sentry from '@sentry/solidstart';

Sentry.init({
traceLifecycle: 'static',
dsn: process.env.E2E_TEST_DSN,
environment: 'qa', // dynamic sampling bias to keep transactions
tracesSampleRate: 1.0, // Capture 100% of the transactions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,119 +1,81 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
import { getSpanOp, waitForStreamedSpan } from '@sentry-internal/test-utils';

test('sends a pageload transaction', async ({ page }) => {
const transactionPromise = waitForTransaction('solidstart-dynamic-import', async transactionEvent => {
return transactionEvent?.transaction === '/' && transactionEvent.contexts?.trace?.op === 'pageload';
test('sends a pageload span', async ({ page }) => {
const spanPromise = waitForStreamedSpan('solidstart-dynamic-import', span => {
return span.name === '/' && getSpanOp(span) === 'pageload' && span.is_segment;
});

await page.goto('/');
const pageloadTransaction = await transactionPromise;
const pageloadSpan = await spanPromise;

expect(pageloadTransaction).toMatchObject({
contexts: {
trace: {
op: 'pageload',
origin: 'auto.pageload.browser',
data: {
'sentry.segment.name.source': 'route',
'url.template': '/',
'url.path': '/',
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/$/),
},
},
},
transaction: '/',
transaction_info: {
source: 'route',
},
expect(getSpanOp(pageloadSpan)).toBe('pageload');
expect(pageloadSpan.attributes).toMatchObject({
'sentry.origin': { value: 'auto.pageload.browser', type: 'string' },
'sentry.op': { value: 'pageload', type: 'string' },
'sentry.segment.name.source': { value: 'route', type: 'string' },
'url.template': { value: '/', type: 'string' },
'url.path': { value: '/', type: 'string' },
'url.full': { value: expect.stringMatching(/^https?:\/\/localhost:\d+\/$/), type: 'string' },
});
});

test('sends a navigation transaction with parametrized route', async ({ page }) => {
const transactionPromise = waitForTransaction('solidstart-dynamic-import', async transactionEvent => {
return transactionEvent?.transaction === '/users/:id' && transactionEvent.contexts?.trace?.op === 'navigation';
test('sends a navigation span with parametrized route', async ({ page }) => {
const spanPromise = waitForStreamedSpan('solidstart-dynamic-import', span => {
return span.name === '/users/:id' && getSpanOp(span) === 'navigation' && span.is_segment;
});

await page.goto(`/`);
await page.locator('#navLink').click();
const navigationTransaction = await transactionPromise;
const navigationSpan = await spanPromise;

expect(navigationTransaction).toMatchObject({
contexts: {
trace: {
op: 'navigation',
origin: 'auto.navigation.solidstart.solidrouter',
data: {
'sentry.segment.name.source': 'route',
'url.template': '/users/:id',
'url.path': '/users/5',
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/5$/),
},
},
},
transaction: '/users/:id',
transaction_info: {
source: 'route',
},
expect(getSpanOp(navigationSpan)).toBe('navigation');
expect(navigationSpan.attributes).toMatchObject({
'sentry.origin': { value: 'auto.navigation.solidstart.solidrouter', type: 'string' },
'sentry.op': { value: 'navigation', type: 'string' },
'sentry.segment.name.source': { value: 'route', type: 'string' },
'url.template': { value: '/users/:id', type: 'string' },
'url.path': { value: '/users/5', type: 'string' },
'url.full': { value: expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/5$/), type: 'string' },
});
});

test('updates the transaction when using the back button', async ({ page }) => {
test('updates the span when using the back button', async ({ page }) => {
// Solid Router sends a `-1` navigation when using the back button.
// The sentry solidRouterBrowserTracingIntegration tries to update such
// transactions with the proper name once the `useLocation` hook triggers.
const navigationTxnPromise = waitForTransaction('solidstart-dynamic-import', async transactionEvent => {
return transactionEvent?.transaction === '/users/:id' && transactionEvent.contexts?.trace?.op === 'navigation';
// spans with the proper name once the `useLocation` hook triggers.
const navigationSpanPromise = waitForStreamedSpan('solidstart-dynamic-import', span => {
return span.name === '/users/:id' && getSpanOp(span) === 'navigation' && span.is_segment;
});

await page.goto(`/back-navigation`);
await page.locator('#navLink').click();
const navigationTxn = await navigationTxnPromise;
const navigationSpan = await navigationSpanPromise;

expect(navigationTxn).toMatchObject({
contexts: {
trace: {
op: 'navigation',
origin: 'auto.navigation.solidstart.solidrouter',
data: {
'sentry.segment.name.source': 'route',
'url.template': '/users/:id',
'url.path': '/users/6',
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/6$/),
},
},
},
transaction: '/users/:id',
transaction_info: {
source: 'route',
},
expect(getSpanOp(navigationSpan)).toBe('navigation');
expect(navigationSpan.attributes).toMatchObject({
'sentry.origin': { value: 'auto.navigation.solidstart.solidrouter', type: 'string' },
'sentry.op': { value: 'navigation', type: 'string' },
'sentry.segment.name.source': { value: 'route', type: 'string' },
'url.template': { value: '/users/:id', type: 'string' },
'url.path': { value: '/users/6', type: 'string' },
'url.full': { value: expect.stringMatching(/^https?:\/\/localhost:\d+\/users\/6$/), type: 'string' },
});

const backNavigationTxnPromise = waitForTransaction('solidstart-dynamic-import', async transactionEvent => {
return (
transactionEvent?.transaction === '/back-navigation' && transactionEvent.contexts?.trace?.op === 'navigation'
);
const backNavigationSpanPromise = waitForStreamedSpan('solidstart-dynamic-import', span => {
return span.name === '/back-navigation' && getSpanOp(span) === 'navigation' && span.is_segment;
});

await page.goBack();
const backNavigationTxn = await backNavigationTxnPromise;
const backNavigationSpan = await backNavigationSpanPromise;

expect(backNavigationTxn).toMatchObject({
contexts: {
trace: {
op: 'navigation',
origin: 'auto.navigation.solidstart.solidrouter',
data: {
'sentry.segment.name.source': 'route',
'url.template': '/back-navigation',
'url.path': '/back-navigation',
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/back-navigation$/),
},
},
},
transaction: '/back-navigation',
transaction_info: {
source: 'route',
},
expect(getSpanOp(backNavigationSpan)).toBe('navigation');
expect(backNavigationSpan.attributes).toMatchObject({
'sentry.origin': { value: 'auto.navigation.solidstart.solidrouter', type: 'string' },
'sentry.op': { value: 'navigation', type: 'string' },
'sentry.segment.name.source': { value: 'route', type: 'string' },
'url.template': { value: '/back-navigation', type: 'string' },
'url.path': { value: '/back-navigation', type: 'string' },
'url.full': { value: expect.stringMatching(/^https?:\/\/localhost:\d+\/back-navigation$/), type: 'string' },
});
});
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/solidstart';

test('sends a server action transaction on pageload', async ({ page }) => {
const transactionPromise = waitForTransaction('solidstart-dynamic-import', transactionEvent => {
return transactionEvent?.transaction === 'GET /users/6';
});
import { collectStreamedSpans, getSpanOp } from '@sentry-internal/test-utils';

test('sends a server action span on pageload', async ({ page }) => {
const spansPromise = collectStreamedSpans(
'solidstart-dynamic-import',
spans =>
spans.some(
span =>
span.is_segment && getSpanOp(span) === 'http.server' && span.attributes['url.path']?.value === '/users/6',
) && spans.some(span => span.name === 'getPrefecture'),
);

await page.goto('/users/6');

const transaction = await transactionPromise;

expect(transaction.spans).toEqual(
expect.arrayContaining([
expect.objectContaining({
description: 'getPrefecture',
data: {
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.solidstart',
},
}),
]),
);
});
const spans = await spansPromise;
const functionSpan = spans.find(span => span.name === 'getPrefecture');

test('sends a server action transaction on client navigation', async ({ page }) => {
const transactionPromise = waitForTransaction('solidstart-dynamic-import', transactionEvent => {
return transactionEvent?.transaction === 'POST getPrefecture';
expect(functionSpan).toBeDefined();
expect(functionSpan?.attributes).toMatchObject({
'sentry.op': { value: 'function', type: 'string' },
'sentry.origin': { value: 'auto.function.solidstart', type: 'string' },
});
});

test('sends a server action span on client navigation', async ({ page }) => {
const spansPromise = collectStreamedSpans(
'solidstart-dynamic-import',
spans =>
spans.some(span => span.is_segment && span.name === 'POST getPrefecture') &&
spans.some(span => span.name === 'getPrefecture' && !span.is_segment),
);

await page.goto('/');
await page.locator('#navLink').click();
await page.waitForURL('/users/5');

const transaction = await transactionPromise;

expect(transaction.spans).toEqual(
expect.arrayContaining([
expect.objectContaining({
description: 'getPrefecture',
data: {
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.solidstart',
},
}),
]),
);
const spans = await spansPromise;
const functionSpan = spans.find(span => span.name === 'getPrefecture' && !span.is_segment);

expect(functionSpan).toBeDefined();
expect(functionSpan?.attributes).toMatchObject({
'sentry.op': { value: 'function', type: 'string' },
'sentry.origin': { value: 'auto.function.solidstart', type: 'string' },
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { solidRouterBrowserTracingIntegration } from '@sentry/solidstart/solidro
import { StartClient, mount } from '@solidjs/start/client';

Sentry.init({
traceLifecycle: 'static',
// We can't use env variables here, seems like they are stripped
// out in production builds.
dsn: 'https://public@dsn.ingest.sentry.io/1337',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as Sentry from '@sentry/solidstart';

Sentry.init({
traceLifecycle: 'static',
dsn: process.env.E2E_TEST_DSN,
environment: 'qa', // dynamic sampling bias to keep transactions
tracesSampleRate: 1.0, // Capture 100% of the transactions
Expand Down
Loading
Loading