Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(solidstart): Add client performance e2e tests #12895

Merged
merged 2 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -5,7 +5,12 @@
"clean": "pnpx rimraf node_modules pnpm-lock.yaml .vinxi .output",
"dev": "NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi dev",
"build": "vinxi build",
"preview": "HOST=localhost PORT=3030 NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi start",
"//": [
"We are using `vinxi dev` to start the server because `vinxi start` is experimental and ",
"doesn't correctly resolve modules for @sentry/solidstart/solidrouter.",
"This is currently not an issue outside of our repo. See: https://github.com/nksaraf/vinxi/issues/177"
],
"preview": "HOST=localhost PORT=3030 NODE_OPTIONS='--import ./src/instrument.server.mjs' vinxi dev",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && npx playwright install && pnpm build",
"test:assert": "pnpm test:prod"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { withSentryRouterRouting } from '@sentry/solidstart/solidrouter';
import { MetaProvider, Title } from '@solidjs/meta';
import { Router } from '@solidjs/router';
import { FileRoutes } from '@solidjs/start/router';
import { Suspense } from 'solid-js';

const SentryRouter = withSentryRouterRouting(Router);

export default function App() {
return (
<Router
<SentryRouter
root={props => (
<MetaProvider>
<Title>SolidStart - with Vitest</Title>
Expand All @@ -14,6 +17,6 @@ export default function App() {
)}
>
<FileRoutes />
</Router>
</SentryRouter>
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// @refresh reload
import * as Sentry from '@sentry/solidstart';
import { solidRouterBrowserTracingIntegration } from '@sentry/solidstart/solidrouter';
import { StartClient, mount } from '@solidjs/start/client';

Sentry.init({
// We can't use env variables here, seems like they are stripped
// out in production builds.
dsn: 'https://[email protected]/1337',
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
integrations: [solidRouterBrowserTracingIntegration()],
tunnel: 'http://localhost:3031/', // proxy server
// Performance Monitoring
tracesSampleRate: 1.0, // Capture 100% of the transactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export default function Home() {
<li>
<A href="/client-error">Client error</A>
</li>
<li>
<A id="navLink" href="/users/5">
User 5
</A>
</li>
</ul>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useParams } from '@solidjs/router';

export default function User() {
const params = useParams();
return <div>User ID: {params.id}</div>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';

test('sends a pageload transaction', async ({ page }) => {
const transactionPromise = waitForTransaction('solidstart', async transactionEvent => {
return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want to assert for a particular transaction name, otherwise the tests are gonna start leaking once you add more page.goto()s

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

});

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

expect(pageloadTransaction).toMatchObject({
contexts: {
trace: {
op: 'pageload',
origin: 'auto.pageload.browser',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up task: We likely want to emit auto.pageload.solidstart.router here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will update this in a follow up PR.

},
},
transaction: '/',
transaction_info: {
source: 'url',
},
});
});

test('sends a navigation transaction', async ({ page }) => {
const transactionPromise = waitForTransaction('solidstart', async transactionEvent => {
return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'navigation';
});

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

expect(navigationTransaction).toMatchObject({
contexts: {
trace: {
op: 'navigation',
origin: 'auto.navigation.solid.solidrouter',
},
},
transaction: '/users/5',
transaction_info: {
source: 'url',
},
});
});

test('updates the transaction 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', async transactionEvent => {
return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'navigation';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The waitForTransaction here and the one in the test above may leak into eachother.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

});

await page.goto(`/`);
await page.locator('#navLink').click();
const navigationTxn = await navigationTxnPromise;

expect(navigationTxn).toMatchObject({
contexts: {
trace: {
op: 'navigation',
origin: 'auto.navigation.solid.solidrouter',
},
},
transaction: '/users/5',
transaction_info: {
source: 'url',
},
});

const backNavigationTxnPromise = waitForTransaction('solidstart', async transactionEvent => {
return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'navigation';
});

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

expect(backNavigationTxn).toMatchObject({
contexts: {
trace: {
op: 'navigation',
origin: 'auto.navigation.solid.solidrouter',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up, this should probably be solidstart.solidrouter

},
},
transaction: '/',
transaction_info: {
source: 'url',
},
});
});
Loading