From 96581d8a98eff9bc815fdf25de36a9f81832d8c0 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 15 Dec 2023 16:58:35 +0100 Subject: [PATCH 1/4] test(e2e): Add Sveltekit 2.0.0 E2E test --- .github/workflows/build.yml | 1 + .../test-applications/sveltekit-2/.gitignore | 10 + .../test-applications/sveltekit-2/.npmrc | 2 + .../test-applications/sveltekit-2/README.md | 41 +++ .../sveltekit-2/event-proxy-server.ts | 253 ++++++++++++++++++ .../sveltekit-2/package.json | 41 +++ .../sveltekit-2/playwright.config.ts | 71 +++++ .../sveltekit-2/src/app.html | 12 + .../sveltekit-2/src/hooks.client.ts | 16 ++ .../sveltekit-2/src/hooks.server.ts | 18 ++ .../sveltekit-2/src/routes/+page.svelte | 2 + .../src/routes/building/+page.server.ts | 5 + .../src/routes/building/+page.svelte | 6 + .../sveltekit-2/src/routes/building/+page.ts | 5 + .../sveltekit-2/start-event-proxy.ts | 6 + .../sveltekit-2/static/favicon.png | Bin 0 -> 1571 bytes .../sveltekit-2/svelte.config.js | 18 ++ .../sveltekit-2/test/transaction.test.ts | 48 ++++ .../sveltekit-2/tsconfig.json | 21 ++ .../sveltekit-2/vite.config.js | 12 + 20 files changed, 588 insertions(+) create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/.gitignore create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/.npmrc create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/README.md create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/event-proxy-server.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/package.json create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/playwright.config.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/app.html create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/hooks.client.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/routes/+page.svelte create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.server.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.svelte create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/static/favicon.png create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/svelte.config.js create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/test/transaction.test.ts create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/tsconfig.json create mode 100644 packages/e2e-tests/test-applications/sveltekit-2/vite.config.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd47b36598f2..1c7d639db7ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -870,6 +870,7 @@ jobs: 'standard-frontend-react', 'standard-frontend-react-tracing-import', 'sveltekit', + 'sveltekit-2', 'generic-ts3.8', 'node-experimental-fastify-app', 'node-hapi-app', diff --git a/packages/e2e-tests/test-applications/sveltekit-2/.gitignore b/packages/e2e-tests/test-applications/sveltekit-2/.gitignore new file mode 100644 index 000000000000..6635cf554275 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/packages/e2e-tests/test-applications/sveltekit-2/.npmrc b/packages/e2e-tests/test-applications/sveltekit-2/.npmrc new file mode 100644 index 000000000000..070f80f05092 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/.npmrc @@ -0,0 +1,2 @@ +@sentry:registry=http://127.0.0.1:4873 +@sentry-internal:registry=http://127.0.0.1:4873 diff --git a/packages/e2e-tests/test-applications/sveltekit-2/README.md b/packages/e2e-tests/test-applications/sveltekit-2/README.md new file mode 100644 index 000000000000..7c0d9fbb26ab --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/README.md @@ -0,0 +1,41 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by +[`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a +development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target +> environment. diff --git a/packages/e2e-tests/test-applications/sveltekit-2/event-proxy-server.ts b/packages/e2e-tests/test-applications/sveltekit-2/event-proxy-server.ts new file mode 100644 index 000000000000..66a9e744846e --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/event-proxy-server.ts @@ -0,0 +1,253 @@ +import * as fs from 'fs'; +import * as http from 'http'; +import * as https from 'https'; +import type { AddressInfo } from 'net'; +import * as os from 'os'; +import * as path from 'path'; +import * as util from 'util'; +import * as zlib from 'zlib'; +import type { Envelope, EnvelopeItem, Event } from '@sentry/types'; +import { parseEnvelope } from '@sentry/utils'; + +const readFile = util.promisify(fs.readFile); +const writeFile = util.promisify(fs.writeFile); + +interface EventProxyServerOptions { + /** Port to start the event proxy server at. */ + port: number; + /** The name for the proxy server used for referencing it with listener functions */ + proxyServerName: string; +} + +interface SentryRequestCallbackData { + envelope: Envelope; + rawProxyRequestBody: string; + rawSentryResponseBody: string; + sentryResponseStatusCode?: number; +} + +/** + * Starts an event proxy server that will proxy events to sentry when the `tunnel` option is used. Point the `tunnel` + * option to this server (like this `tunnel: http://localhost:${port option}/`). + */ +export async function startEventProxyServer(options: EventProxyServerOptions): Promise { + const eventCallbackListeners: Set<(data: string) => void> = new Set(); + + const proxyServer = http.createServer((proxyRequest, proxyResponse) => { + const proxyRequestChunks: Uint8Array[] = []; + + proxyRequest.addListener('data', (chunk: Buffer) => { + proxyRequestChunks.push(chunk); + }); + + proxyRequest.addListener('error', err => { + throw err; + }); + + proxyRequest.addListener('end', () => { + const proxyRequestBody = + proxyRequest.headers['content-encoding'] === 'gzip' + ? zlib.gunzipSync(Buffer.concat(proxyRequestChunks)).toString() + : Buffer.concat(proxyRequestChunks).toString(); + + let envelopeHeader = JSON.parse(proxyRequestBody.split('\n')[0]); + + if (!envelopeHeader.dsn) { + throw new Error('[event-proxy-server] No dsn on envelope header. Please set tunnel option.'); + } + + const { origin, pathname, host } = new URL(envelopeHeader.dsn); + + const projectId = pathname.substring(1); + const sentryIngestUrl = `${origin}/api/${projectId}/envelope/`; + + proxyRequest.headers.host = host; + + const sentryResponseChunks: Uint8Array[] = []; + + const sentryRequest = https.request( + sentryIngestUrl, + { headers: proxyRequest.headers, method: proxyRequest.method }, + sentryResponse => { + sentryResponse.addListener('data', (chunk: Buffer) => { + proxyResponse.write(chunk, 'binary'); + sentryResponseChunks.push(chunk); + }); + + sentryResponse.addListener('end', () => { + eventCallbackListeners.forEach(listener => { + const rawSentryResponseBody = Buffer.concat(sentryResponseChunks).toString(); + + const data: SentryRequestCallbackData = { + envelope: parseEnvelope(proxyRequestBody, new TextEncoder(), new TextDecoder()), + rawProxyRequestBody: proxyRequestBody, + rawSentryResponseBody, + sentryResponseStatusCode: sentryResponse.statusCode, + }; + + listener(Buffer.from(JSON.stringify(data)).toString('base64')); + }); + proxyResponse.end(); + }); + + sentryResponse.addListener('error', err => { + throw err; + }); + + proxyResponse.writeHead(sentryResponse.statusCode || 500, sentryResponse.headers); + }, + ); + + sentryRequest.write(Buffer.concat(proxyRequestChunks), 'binary'); + sentryRequest.end(); + }); + }); + + const proxyServerStartupPromise = new Promise(resolve => { + proxyServer.listen(options.port, () => { + resolve(); + }); + }); + + const eventCallbackServer = http.createServer((eventCallbackRequest, eventCallbackResponse) => { + eventCallbackResponse.statusCode = 200; + eventCallbackResponse.setHeader('connection', 'keep-alive'); + + const callbackListener = (data: string): void => { + eventCallbackResponse.write(data.concat('\n'), 'utf8'); + }; + + eventCallbackListeners.add(callbackListener); + + eventCallbackRequest.on('close', () => { + eventCallbackListeners.delete(callbackListener); + }); + + eventCallbackRequest.on('error', () => { + eventCallbackListeners.delete(callbackListener); + }); + }); + + const eventCallbackServerStartupPromise = new Promise(resolve => { + eventCallbackServer.listen(0, () => { + const port = String((eventCallbackServer.address() as AddressInfo).port); + void registerCallbackServerPort(options.proxyServerName, port).then(resolve); + }); + }); + + await eventCallbackServerStartupPromise; + await proxyServerStartupPromise; + return; +} + +export async function waitForRequest( + proxyServerName: string, + callback: (eventData: SentryRequestCallbackData) => Promise | boolean, +): Promise { + const eventCallbackServerPort = await retrieveCallbackServerPort(proxyServerName); + + return new Promise((resolve, reject) => { + const request = http.request(`http://localhost:${eventCallbackServerPort}/`, {}, response => { + let eventContents = ''; + + response.on('error', err => { + reject(err); + }); + + response.on('data', (chunk: Buffer) => { + const chunkString = chunk.toString('utf8'); + chunkString.split('').forEach(char => { + if (char === '\n') { + const eventCallbackData: SentryRequestCallbackData = JSON.parse( + Buffer.from(eventContents, 'base64').toString('utf8'), + ); + const callbackResult = callback(eventCallbackData); + if (typeof callbackResult !== 'boolean') { + callbackResult.then( + match => { + if (match) { + response.destroy(); + resolve(eventCallbackData); + } + }, + err => { + throw err; + }, + ); + } else if (callbackResult) { + response.destroy(); + resolve(eventCallbackData); + } + eventContents = ''; + } else { + eventContents = eventContents.concat(char); + } + }); + }); + }); + + request.end(); + }); +} + +export function waitForEnvelopeItem( + proxyServerName: string, + callback: (envelopeItem: EnvelopeItem) => Promise | boolean, +): Promise { + return new Promise((resolve, reject) => { + waitForRequest(proxyServerName, async eventData => { + const envelopeItems = eventData.envelope[1]; + for (const envelopeItem of envelopeItems) { + if (await callback(envelopeItem)) { + resolve(envelopeItem); + return true; + } + } + return false; + }).catch(reject); + }); +} + +export function waitForError( + proxyServerName: string, + callback: (transactionEvent: Event) => Promise | boolean, +): Promise { + return new Promise((resolve, reject) => { + waitForEnvelopeItem(proxyServerName, async envelopeItem => { + const [envelopeItemHeader, envelopeItemBody] = envelopeItem; + if (envelopeItemHeader.type === 'event' && (await callback(envelopeItemBody as Event))) { + resolve(envelopeItemBody as Event); + return true; + } + return false; + }).catch(reject); + }); +} + +export function waitForTransaction( + proxyServerName: string, + callback: (transactionEvent: Event) => Promise | boolean, +): Promise { + return new Promise((resolve, reject) => { + waitForEnvelopeItem(proxyServerName, async envelopeItem => { + const [envelopeItemHeader, envelopeItemBody] = envelopeItem; + if (envelopeItemHeader.type === 'transaction' && (await callback(envelopeItemBody as Event))) { + resolve(envelopeItemBody as Event); + return true; + } + return false; + }).catch(reject); + }); +} + +const TEMP_FILE_PREFIX = 'event-proxy-server-'; + +async function registerCallbackServerPort(serverName: string, port: string): Promise { + const tmpFilePath = path.join(os.tmpdir(), `${TEMP_FILE_PREFIX}${serverName}`); + await writeFile(tmpFilePath, port, { encoding: 'utf8' }); +} + +async function retrieveCallbackServerPort(serverName: string): Promise { + const tmpFilePath = path.join(os.tmpdir(), `${TEMP_FILE_PREFIX}${serverName}`); + return await readFile(tmpFilePath, 'utf8'); +} diff --git a/packages/e2e-tests/test-applications/sveltekit-2/package.json b/packages/e2e-tests/test-applications/sveltekit-2/package.json new file mode 100644 index 000000000000..e10818e519e6 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/package.json @@ -0,0 +1,41 @@ +{ + "name": "sveltekit-2.0", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "clean": "npx rimraf node_modules,pnpm-lock.yaml", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "test:prod": "TEST_ENV=production playwright test", + "test:dev": "TEST_ENV=development playwright test", + "test:build": "pnpm install && pnpm build", + "test:assert": "pnpm -v" + }, + "dependencies": { + "@sentry/sveltekit": "latest || *" + }, + "devDependencies": { + "@playwright/test": "^1.27.1", + "@sentry/types": "latest || *", + "@sentry/utils": "latest || *", + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/adapter-node": "^2.0.0", + "@sveltejs/kit": "^2.0.0", + "svelte": "^4.2.8", + "svelte-check": "^3.6.0", + "ts-node": "10.9.1", + "typescript": "^5.0.0", + "vite": "^5.0.3", + "wait-port": "1.0.4" + }, + "pnpm": { + "overrides": { + "@sentry/node": "latest || *", + "@sentry/tracing": "latest || *" + } + }, + "type": "module" +} diff --git a/packages/e2e-tests/test-applications/sveltekit-2/playwright.config.ts b/packages/e2e-tests/test-applications/sveltekit-2/playwright.config.ts new file mode 100644 index 000000000000..bfa29df7d549 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/playwright.config.ts @@ -0,0 +1,71 @@ +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; + +const testEnv = process.env.TEST_ENV; + +if (!testEnv) { + throw new Error('No test env defined'); +} + +const port = 3030; + +/** + * See https://playwright.dev/docs/test-configuration. + */ +const config: PlaywrightTestConfig = { + testDir: './test', + /* Maximum time one test can run for. */ + timeout: 150_000, + expect: { + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 10000, + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* `next dev` is incredibly buggy with the app dir */ + retries: testEnv === 'development' ? 3 : 0, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'list', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 0, + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: `http://localhost:${port}`, + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + }, + }, + ], + + /* Run your local dev server before starting the tests */ + webServer: [ + { + command: 'pnpm ts-node --esm start-event-proxy.ts', + port: 3031, + }, + { + command: + testEnv === 'development' + ? `pnpm wait-port ${port} && pnpm dev --port ${port}` + : `pnpm wait-port ${port} && pnpm preview --port ${port}`, + port, + }, + ], +}; + +export default config; diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/app.html b/packages/e2e-tests/test-applications/sveltekit-2/src/app.html new file mode 100644 index 000000000000..117bd026151a --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.client.ts b/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.client.ts new file mode 100644 index 000000000000..bfe90b150886 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.client.ts @@ -0,0 +1,16 @@ +import { env } from '$env/dynamic/public'; +import * as Sentry from '@sentry/sveltekit'; + +Sentry.init({ + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: env.PUBLIC_E2E_TEST_DSN, + debug: true, + tunnel: `http://localhost:3031/`, // proxy server + tracesSampleRate: 1.0, +}); + +const myErrorHandler = ({ error, event }: any) => { + console.error('An error occurred on the client side:', error, event); +}; + +export const handleError = Sentry.handleErrorWithSentry(myErrorHandler); diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts b/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts new file mode 100644 index 000000000000..2d9cb9b02328 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts @@ -0,0 +1,18 @@ +import { env } from '$env/dynamic/private'; +import * as Sentry from '@sentry/sveltekit'; + +Sentry.init({ + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: env.E2E_TEST_DSN, + debug: true, + tunnel: `http://localhost:3031/`, // proxy server + tracesSampleRate: 1.0, +}); + +const myErrorHandler = ({ error, event }: any) => { + console.error('An error occurred on the server side:', error, event); +}; + +export const handleError = Sentry.handleErrorWithSentry(myErrorHandler); + +export const handle = Sentry.sentryHandle(); diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/routes/+page.svelte b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/+page.svelte new file mode 100644 index 000000000000..5982b0ae37dd --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/+page.svelte @@ -0,0 +1,2 @@ +

Welcome to SvelteKit

+

Visit kit.svelte.dev to read the documentation

diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.server.ts b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.server.ts new file mode 100644 index 000000000000..b07376ba97c9 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.server.ts @@ -0,0 +1,5 @@ +import type { PageServerLoad } from './$types'; + +export const load = (async _event => { + return { name: 'building (server)' }; +}) satisfies PageServerLoad; diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.svelte b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.svelte new file mode 100644 index 000000000000..fde274c60705 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.svelte @@ -0,0 +1,6 @@ +

Check Build

+ +

+ This route only exists to check that Typescript definitions + and auto instrumentation are working when the project is built. +

diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.ts b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.ts new file mode 100644 index 000000000000..049acdc1fafa --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/routes/building/+page.ts @@ -0,0 +1,5 @@ +import type { PageLoad } from './$types'; + +export const load = (async _event => { + return { name: 'building' }; +}) satisfies PageLoad; diff --git a/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts b/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts new file mode 100644 index 000000000000..236066c73e3c --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts @@ -0,0 +1,6 @@ +import { startEventProxyServer } from "./event-proxy-server"; + +startEventProxyServer({ + port: 3031, + proxyServerName: "sveltekit-2", +}); diff --git a/packages/e2e-tests/test-applications/sveltekit-2/static/favicon.png b/packages/e2e-tests/test-applications/sveltekit-2/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..825b9e65af7c104cfb07089bb28659393b4f2097 GIT binary patch literal 1571 zcmV+;2Hg3HP)Px)-AP12RCwC$UE6KzI1p6{F2N z1VK2vi|pOpn{~#djwYcWXTI_im_u^TJgMZ4JMOsSj!0ma>B?-(Hr@X&W@|R-$}W@Z zgj#$x=!~7LGqHW?IO8+*oE1MyDp!G=L0#^lUx?;!fXv@l^6SvTnf^ac{5OurzC#ZMYc20lI%HhX816AYVs1T3heS1*WaWH z%;x>)-J}YB5#CLzU@GBR6sXYrD>Vw(Fmt#|JP;+}<#6b63Ike{Fuo!?M{yEffez;| zp!PfsuaC)>h>-AdbnwN13g*1LowNjT5?+lFVd#9$!8Z9HA|$*6dQ8EHLu}U|obW6f z2%uGv?vr=KNq7YYa2Roj;|zooo<)lf=&2yxM@e`kM$CmCR#x>gI>I|*Ubr({5Y^rb zghxQU22N}F51}^yfDSt786oMTc!W&V;d?76)9KXX1 z+6Okem(d}YXmmOiZq$!IPk5t8nnS{%?+vDFz3BevmFNgpIod~R{>@#@5x9zJKEHLHv!gHeK~n)Ld!M8DB|Kfe%~123&Hz1Z(86nU7*G5chmyDe ziV7$pB7pJ=96hpxHv9rCR29%bLOXlKU<_13_M8x)6;P8E1Kz6G<&P?$P^%c!M5`2` zfY2zg;VK5~^>TJGQzc+33-n~gKt{{of8GzUkWmU110IgI0DLxRIM>0US|TsM=L|@F z0Bun8U!cRB7-2apz=y-7*UxOxz@Z0)@QM)9wSGki1AZ38ceG7Q72z5`i;i=J`ILzL z@iUO?SBBG-0cQuo+an4TsLy-g-x;8P4UVwk|D8{W@U1Zi z!M)+jqy@nQ$p?5tsHp-6J304Q={v-B>66$P0IDx&YT(`IcZ~bZfmn11#rXd7<5s}y zBi9eim&zQc0Dk|2>$bs0PnLmDfMP5lcXRY&cvJ=zKxI^f0%-d$tD!`LBf9^jMSYUA zI8U?CWdY@}cRq6{5~y+)#h1!*-HcGW@+gZ4B};0OnC~`xQOyH19z*TA!!BJ%9s0V3F?CAJ{hTd#*tf+ur-W9MOURF-@B77_-OshsY}6 zOXRY=5%C^*26z?l)1=$bz30!so5tfABdSYzO+H=CpV~aaUefmjvfZ3Ttu9W&W3Iu6 zROlh0MFA5h;my}8lB0tAV-Rvc2Zs_CCSJnx@d`**$idgy-iMob4dJWWw|21b4NB=LfsYp0Aeh{Ov)yztQi;eL4y5 zMi>8^SzKqk8~k?UiQK^^-5d8c%bV?$F8%X~czyiaKCI2=UH { + const pageloadTransactionEventPromise = waitForTransaction('sveltekit', (transactionEvent: any) => { + return transactionEvent?.contexts?.trace?.op === 'pageload' && transactionEvent?.transaction === '/'; + }); + + await page.goto('/'); + + const transactionEvent = await pageloadTransactionEventPromise; + const transactionEventId = transactionEvent.event_id; + + await expect + .poll( + async () => { + try { + const response = await axios.get( + `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${transactionEventId}/`, + { headers: { Authorization: `Bearer ${authToken}` } }, + ); + + return response.status; + } catch (e) { + if (e instanceof AxiosError && e.response) { + if (e.response.status !== 404) { + throw e; + } else { + return e.response.status; + } + } else { + throw e; + } + } + }, + { + timeout: EVENT_POLLING_TIMEOUT, + }, + ) + .toBe(200); +}); diff --git a/packages/e2e-tests/test-applications/sveltekit-2/tsconfig.json b/packages/e2e-tests/test-applications/sveltekit-2/tsconfig.json new file mode 100644 index 000000000000..12aa7328fc83 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "allowImportingTsExtensions": true + }, + "ts-node": { + "esm": true, + "experimentalSpecifierResolution": "node" + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/packages/e2e-tests/test-applications/sveltekit-2/vite.config.js b/packages/e2e-tests/test-applications/sveltekit-2/vite.config.js new file mode 100644 index 000000000000..1a410bee7e11 --- /dev/null +++ b/packages/e2e-tests/test-applications/sveltekit-2/vite.config.js @@ -0,0 +1,12 @@ +import { sentrySvelteKit } from '@sentry/sveltekit'; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [ + sentrySvelteKit({ + autoUploadSourceMaps: false, + }), + sveltekit(), + ], +}); From 2e5d799dd56d2cc77babef4b28798c7ed583628a Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 15 Dec 2023 18:11:23 +0100 Subject: [PATCH 2/4] vite preprocess import --- .../e2e-tests/test-applications/sveltekit-2/svelte.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/test-applications/sveltekit-2/svelte.config.js b/packages/e2e-tests/test-applications/sveltekit-2/svelte.config.js index ba3eb7ca4745..c521eff7de30 100644 --- a/packages/e2e-tests/test-applications/sveltekit-2/svelte.config.js +++ b/packages/e2e-tests/test-applications/sveltekit-2/svelte.config.js @@ -1,5 +1,5 @@ import adapter from '@sveltejs/adapter-node'; -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { From 1d45be0ec502d59ac698489870930391e76dc54f Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 18 Dec 2023 10:49:47 +0100 Subject: [PATCH 3/4] biome --- .../test-applications/sveltekit-2/start-event-proxy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts b/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts index 236066c73e3c..3af64eb5960a 100644 --- a/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts +++ b/packages/e2e-tests/test-applications/sveltekit-2/start-event-proxy.ts @@ -1,6 +1,6 @@ -import { startEventProxyServer } from "./event-proxy-server"; +import { startEventProxyServer } from './event-proxy-server'; startEventProxyServer({ port: 3031, - proxyServerName: "sveltekit-2", + proxyServerName: 'sveltekit-2', }); From 4c042eaaeaf92894f7d5cc3d0ad7a32d5e760fb8 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 18 Dec 2023 10:56:55 +0100 Subject: [PATCH 4/4] fix build error --- .../test-applications/sveltekit-2/src/hooks.server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts b/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts index 2d9cb9b02328..ae99e0e0e7b4 100644 --- a/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts +++ b/packages/e2e-tests/test-applications/sveltekit-2/src/hooks.server.ts @@ -1,9 +1,9 @@ -import { env } from '$env/dynamic/private'; +import { E2E_TEST_DSN } from '$env/static/private'; import * as Sentry from '@sentry/sveltekit'; Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions - dsn: env.E2E_TEST_DSN, + dsn: E2E_TEST_DSN, debug: true, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1.0,