Skip to content

Commit 5c8483c

Browse files
committed
test(e2e): Add tests to SvelteKit 1.x E2E test app
1 parent 0c16f21 commit 5c8483c

File tree

28 files changed

+483
-66
lines changed

28 files changed

+483
-66
lines changed

dev-packages/e2e-tests/test-applications/sveltekit/event-proxy-server.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as os from 'os';
66
import * as path from 'path';
77
import * as util from 'util';
88
import * as zlib from 'zlib';
9-
import type { Envelope, EnvelopeItem, Event } from '@sentry/types';
9+
import type { Envelope, EnvelopeItem, Event, SerializedEvent } from '@sentry/types';
1010
import { parseEnvelope } from '@sentry/utils';
1111

1212
const readFile = util.promisify(fs.readFile);
@@ -226,13 +226,13 @@ export function waitForError(
226226

227227
export function waitForTransaction(
228228
proxyServerName: string,
229-
callback: (transactionEvent: Event) => Promise<boolean> | boolean,
230-
): Promise<Event> {
229+
callback: (transactionEvent: SerializedEvent) => Promise<boolean> | boolean,
230+
): Promise<SerializedEvent> {
231231
return new Promise((resolve, reject) => {
232232
waitForEnvelopeItem(proxyServerName, async envelopeItem => {
233233
const [envelopeItemHeader, envelopeItemBody] = envelopeItem;
234-
if (envelopeItemHeader.type === 'transaction' && (await callback(envelopeItemBody as Event))) {
235-
resolve(envelopeItemBody as Event);
234+
if (envelopeItemHeader.type === 'transaction' && (await callback(envelopeItemBody as SerializedEvent))) {
235+
resolve(envelopeItemBody as SerializedEvent);
236236
return true;
237237
}
238238
return false;

dev-packages/e2e-tests/test-applications/sveltekit/package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@
1010
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
1111
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
1212
"test:prod": "TEST_ENV=production playwright test",
13-
"test:dev": "TEST_ENV=development playwright test",
14-
"test:build": "pnpm install && pnpm build",
15-
"test:assert": "pnpm -v"
13+
"test:build": "pnpm install && npx playwright install && pnpm build",
14+
"test:assert": "pnpm test:prod"
1615
},
1716
"dependencies": {
1817
"@sentry/sveltekit": "latest || *"
1918
},
2019
"devDependencies": {
21-
"@playwright/test": "^1.27.1",
20+
"@playwright/test": "^1.41.1",
2221
"@sentry/types": "latest || *",
2322
"@sentry/utils": "latest || *",
2423
"@sveltejs/adapter-auto": "^2.0.0",
2524
"@sveltejs/adapter-node": "^1.2.4",
26-
"@sveltejs/kit": "^1.5.0",
25+
"@sveltejs/kit": "^1.30.3",
2726
"svelte": "^3.54.0",
2827
"svelte-check": "^3.0.1",
2928
"ts-node": "10.9.1",

dev-packages/e2e-tests/test-applications/sveltekit/playwright.config.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if (!testEnv) {
88
}
99

1010
const port = 3030;
11+
const eventProxyPort = 3031;
1112

1213
/**
1314
* See https://playwright.dev/docs/test-configuration.
@@ -23,8 +24,9 @@ const config: PlaywrightTestConfig = {
2324
*/
2425
timeout: 10000,
2526
},
27+
workers: 1,
2628
/* Run tests in files in parallel */
27-
fullyParallel: true,
29+
fullyParallel: false,
2830
/* Fail the build on CI if you accidentally left test.only in the source code. */
2931
forbidOnly: !!process.env.CI,
3032
/* `next dev` is incredibly buggy with the app dir */
@@ -61,8 +63,8 @@ const config: PlaywrightTestConfig = {
6163
{
6264
command:
6365
testEnv === 'development'
64-
? `pnpm wait-port ${port} && pnpm dev --port ${port}`
65-
: `pnpm wait-port ${port} && pnpm preview --port ${port}`,
66+
? `pnpm wait-port ${eventProxyPort} && pnpm dev --port ${port}`
67+
: `pnpm wait-port ${eventProxyPort} && pnpm preview --port ${port}`,
6668
port,
6769
},
6870
],

dev-packages/e2e-tests/test-applications/sveltekit/src/app.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<meta name="viewport" content="width=device-width" />
77
%sveltekit.head%
88
</head>
9-
<body data-sveltekit-preload-data="hover">
9+
<body data-sveltekit-preload-data="off">
1010
<div style="display: contents">%sveltekit.body%</div>
1111
</body>
1212
</html>

dev-packages/e2e-tests/test-applications/sveltekit/src/hooks.server.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ Sentry.init({
99
tracesSampleRate: 1.0,
1010
});
1111

12-
const myErrorHandler = ({ error, event }: any) => {
13-
console.error('An error occurred on the server side:', error, event);
14-
};
12+
// not logging anything to console to avoid noise in the test output
13+
const myErrorHandler = ({ error, event }: any) => {};
1514

1615
export const handleError = Sentry.handleErrorWithSentry(myErrorHandler);
1716

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script lang="typescript">
2+
import { onMount } from 'svelte';
3+
4+
onMount(() => {
5+
// Indicate that the SvelteKit app was hydrated
6+
document.body.classList.add('hydrated');
7+
});
8+
</script>
9+
10+
<slot />
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,26 @@
11
<h1>Welcome to SvelteKit</h1>
22
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
3+
4+
<ul>
5+
<li>
6+
<a href="/client-error">Client error</a>
7+
</li>
8+
<li>
9+
<a href="/universal-load-error">Universal Load error</a>
10+
</li>
11+
<li>
12+
<a href="/server-load-error">Server Load error</a>
13+
</li>
14+
<li>
15+
<a href="/server-route-error">Server Route error</a>
16+
</li>
17+
<li>
18+
<a href="/users/123abc">Route with Params</a>
19+
</li>
20+
<li>
21+
<a href="/users">Route with Server Load</a>
22+
</li>
23+
<li>
24+
<a href="/universal-load-fetch">Route with fetch in universal load</a>
25+
</li>
26+
</ul>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const GET = () => {
2+
return new Response(JSON.stringify({ users: ['alice', 'bob', 'carol'] }));
3+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script lang="ts">
2+
function throwError() {
3+
throw new Error('Click Error');
4+
}
5+
</script>
6+
7+
<h1>Client error</h1>
8+
9+
<button on:click={throwError}>Throw error</button>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const load = async () => {
2+
throw new Error('Server Load Error');
3+
return {
4+
msg: 'Hello World',
5+
};
6+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script lang="ts">
2+
export let data
3+
</script>
4+
5+
<h1>Server load error</h1>
6+
7+
<p>
8+
Message: {data.msg}
9+
</p>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script lang="ts">
2+
export let data;
3+
</script>
4+
5+
<h1>Server Route error</h1>
6+
7+
<p>
8+
Message: {data.msg}
9+
</p>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const load = async ({ fetch }) => {
2+
const res = await fetch('/server-route-error');
3+
const data = await res.json();
4+
return {
5+
msg: data,
6+
};
7+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const GET = async () => {
2+
throw new Error('Server Route Error');
3+
return {
4+
msg: 'Hello World',
5+
};
6+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script lang="ts">
2+
export let data
3+
</script>
4+
5+
<h1>Universal load error</h1>
6+
7+
<p>
8+
To trigger from client: Load on another route, then navigate to this route.
9+
</p>
10+
11+
<p>
12+
To trigger from server: Load on this route
13+
</p>
14+
15+
<p>
16+
Message: {data.msg}
17+
</p>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { browser } from '$app/environment';
2+
3+
export const load = async () => {
4+
throw new Error(`Universal Load Error (${browser ? 'browser' : 'server'})`);
5+
return {
6+
msg: 'Hello World',
7+
};
8+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts">
2+
export let data;
3+
console.log(data);
4+
</script>
5+
6+
<h2>Fetching in universal load</h2>
7+
8+
<p>Here's a list of a few users:</p>
9+
10+
<ul>
11+
{#each data.users as user}
12+
<li>{user}</li>
13+
{/each}
14+
</ul>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const load = async ({ fetch }) => {
2+
const usersRes = await fetch('/api/users');
3+
const data = await usersRes.json();
4+
return { users: data.users };
5+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const load = async () => {
2+
return {
3+
msg: 'Hi everyone!',
4+
};
5+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script lang="ts">
2+
export let data;
3+
</script>
4+
<h2>
5+
All Users:
6+
</h2>
7+
8+
<p>
9+
message: {data.msg}
10+
</p>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const load = async ({ params }) => {
2+
return {
3+
msg: `This is a special message for user ${params.id}`,
4+
};
5+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts">
2+
import { page } from '$app/stores';
3+
export let data;
4+
</script>
5+
6+
<h1>Route with dynamic params</h1>
7+
8+
<p>
9+
User id: {$page.params.id}
10+
</p>
11+
12+
<p>
13+
Secret message for user: {data.msg}
14+
</p>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForError } from '../event-proxy-server';
3+
import { waitForInitialPageload } from '../utils';
4+
5+
test.describe('client-side errors', () => {
6+
test('captures error thrown on click', async ({ page }) => {
7+
await page.goto('/client-error');
8+
9+
await expect(page.getByText('Client error')).toBeVisible();
10+
11+
const errorEventPromise = waitForError('sveltekit', errorEvent => {
12+
return errorEvent?.exception?.values?.[0]?.value === 'Click Error';
13+
});
14+
15+
const clickPromise = page.getByText('Throw error').click();
16+
17+
const [errorEvent, _] = await Promise.all([errorEventPromise, clickPromise]);
18+
19+
const errorEventFrames = errorEvent.exception?.values?.[0]?.stacktrace?.frames;
20+
21+
expect(errorEventFrames?.[errorEventFrames?.length - 1]).toEqual(
22+
expect.objectContaining({
23+
function: expect.stringContaining('HTMLButtonElement'),
24+
lineno: 1,
25+
in_app: true,
26+
}),
27+
);
28+
29+
expect(errorEvent.tags).toMatchObject({ runtime: 'browser' });
30+
});
31+
32+
test('captures universal load error', async ({ page }) => {
33+
await waitForInitialPageload(page);
34+
await page.reload();
35+
36+
const errorEventPromise = waitForError('sveltekit', errorEvent => {
37+
return errorEvent?.exception?.values?.[0]?.value === 'Universal Load Error (browser)';
38+
});
39+
40+
// navigating triggers the error on the client
41+
await page.getByText('Universal Load error').click();
42+
43+
const errorEvent = await errorEventPromise;
44+
const errorEventFrames = errorEvent.exception?.values?.[0]?.stacktrace?.frames;
45+
46+
expect(errorEventFrames?.[errorEventFrames?.length - 1]).toEqual(
47+
expect.objectContaining({
48+
lineno: 1,
49+
in_app: true,
50+
}),
51+
);
52+
53+
expect(errorEvent.tags).toMatchObject({ runtime: 'browser' });
54+
});
55+
});

0 commit comments

Comments
 (0)