From 8566bc44a4e0ada69bf099b2fa16bcfe903edfec Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 11 Jul 2024 09:16:41 +0200 Subject: [PATCH 1/2] test(solidstart): Add solidstart e2e test app --- .../solid-solidrouter/package.json | 2 +- .../test-applications/solid/package.json | 2 +- .../test-applications/solidstart/.gitignore | 46 +++++++++ .../test-applications/solidstart/.npmrc | 2 + .../test-applications/solidstart/README.md | 42 ++++++++ .../solidstart/app.config.ts | 3 + .../test-applications/solidstart/package.json | 34 +++++++ .../solidstart/playwright.config.mjs | 8 ++ .../solidstart/public/favicon.ico | Bin 0 -> 664 bytes .../test-applications/solidstart/src/app.tsx | 19 ++++ .../solidstart/src/entry-client.tsx | 16 ++++ .../solidstart/src/entry-server.tsx | 21 ++++ .../solidstart/src/instrument.server.mjs | 8 ++ .../solidstart/src/routes/client-error.tsx | 75 +++++++++++++++ .../solidstart/src/routes/index.tsx | 17 ++++ .../solidstart/start-event-proxy.mjs | 6 ++ .../solidstart/tests/errorboundary.test.ts | 90 ++++++++++++++++++ .../solidstart/tests/errors.client.test.ts | 32 +++++++ .../solidstart/tsconfig.json | 19 ++++ .../solidstart/vitest.config.ts | 10 ++ 20 files changed, 450 insertions(+), 2 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/.gitignore create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/.npmrc create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/README.md create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/app.config.ts create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/package.json create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/playwright.config.mjs create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/public/favicon.ico create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/app.tsx create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/entry-client.tsx create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/entry-server.tsx create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/instrument.server.mjs create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/start-event-proxy.mjs create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/tsconfig.json create mode 100644 dev-packages/e2e-tests/test-applications/solidstart/vitest.config.ts diff --git a/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json b/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json index 3f0d7ca13fce..26f2ee5ba342 100644 --- a/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json +++ b/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json @@ -27,7 +27,7 @@ }, "dependencies": { "@solidjs/router": "^0.13.5", - "solid-js": "^1.8.11", + "solid-js": "^1.8.18", "@sentry/solid": "latest || *" } } diff --git a/dev-packages/e2e-tests/test-applications/solid/package.json b/dev-packages/e2e-tests/test-applications/solid/package.json index ebfde066e6ef..6d56a61d08cf 100644 --- a/dev-packages/e2e-tests/test-applications/solid/package.json +++ b/dev-packages/e2e-tests/test-applications/solid/package.json @@ -26,7 +26,7 @@ "vite-plugin-solid": "^2.8.2" }, "dependencies": { - "solid-js": "^1.8.11", + "solid-js": "^1.8.18", "@sentry/solid": "latest || *" } } diff --git a/dev-packages/e2e-tests/test-applications/solidstart/.gitignore b/dev-packages/e2e-tests/test-applications/solidstart/.gitignore new file mode 100644 index 000000000000..a51ed3c20c8d --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/.gitignore @@ -0,0 +1,46 @@ + +dist +.solid +.output +.vercel +.netlify +.vinxi + +# Environment +.env +.env*.local + +# dependencies +/node_modules +/.pnp +.pnp.js + +# IDEs and editors +/.idea +.project +.classpath +*.launch +.settings/ + +# Temp +gitignore + +# testing +/coverage + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +/test-results/ +/playwright-report/ +/playwright/.cache/ + +!*.d.ts diff --git a/dev-packages/e2e-tests/test-applications/solidstart/.npmrc b/dev-packages/e2e-tests/test-applications/solidstart/.npmrc new file mode 100644 index 000000000000..070f80f05092 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/.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/dev-packages/e2e-tests/test-applications/solidstart/README.md b/dev-packages/e2e-tests/test-applications/solidstart/README.md new file mode 100644 index 000000000000..148dccaa7f6f --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/README.md @@ -0,0 +1,42 @@ +# SolidStart + +Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com); + +## Creating a project + +```bash +# create a new project in the current directory +npm init solid@latest + +# create a new project in my-app +npm init solid@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 + +Solid apps are built with _presets_, which optimise your project for deployment to different environments. + +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. + +## Testing + +Tests are written with `vitest`, `@solidjs/testing-library` and `@testing-library/jest-dom` to extend expect with some helpful custom matchers. + +To run them, simply start: + +```sh +npm test +``` + +## This project was created with the [Solid CLI](https://solid-cli.netlify.app) diff --git a/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts b/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts new file mode 100644 index 000000000000..b3c737efe5ba --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/app.config.ts @@ -0,0 +1,3 @@ +import { defineConfig } from '@solidjs/start/config'; + +export default defineConfig({}); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/package.json b/dev-packages/e2e-tests/test-applications/solidstart/package.json new file mode 100644 index 000000000000..b4b81ffcbd88 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/package.json @@ -0,0 +1,34 @@ +{ + "name": "example-with-vitest", + "version": "0.0.0", + "scripts": { + "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", + "test:prod": "TEST_ENV=production playwright test", + "test:build": "pnpm install && npx playwright install && pnpm build", + "test:assert": "pnpm test:prod" + }, + "type": "module", + "dependencies": { + "@sentry/solidstart": "latest || *" + }, + "devDependencies": { + "@playwright/test": "^1.44.1", + "@solidjs/meta": "^0.29.4", + "@solidjs/router": "^0.13.4", + "@solidjs/start": "^1.0.2", + "@solidjs/testing-library": "^0.8.7", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/user-event": "^14.5.2", + "@vitest/ui": "^1.5.0", + "jsdom": "^24.0.0", + "solid-js": "1.8.17", + "typescript": "^5.4.5", + "vinxi": "^0.3.12", + "vite": "^5.2.8", + "vite-plugin-solid": "^2.10.2", + "vitest": "^1.5.0" + } +} diff --git a/dev-packages/e2e-tests/test-applications/solidstart/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/solidstart/playwright.config.mjs new file mode 100644 index 000000000000..395acfc282f9 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/playwright.config.mjs @@ -0,0 +1,8 @@ +import { getPlaywrightConfig } from '@sentry-internal/test-utils'; + +const config = getPlaywrightConfig({ + startCommand: 'pnpm preview', + port: 3030, +}); + +export default config; diff --git a/dev-packages/e2e-tests/test-applications/solidstart/public/favicon.ico b/dev-packages/e2e-tests/test-applications/solidstart/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fb282da0719ef6ab4c1732df93be6216b0d85520 GIT binary patch literal 664 zcmV;J0%!e+P)m9ebk1R zejT~~6f_`?;`cEd!+`7(hw@%%2;?RN8gX-L?z6cM( zKoG@&w+0}f@Pfvwc+deid)qgE!L$ENKYjViZC_Zcr>L(`2oXUT8f0mRQ(6-=HN_Ai zeBBEz3WP+1Cw`m!49Wf!MnZzp5bH8VkR~BcJ1s-j90TAS2Yo4j!J|KodxYR%3Numw zA?gq6e`5@!W~F$_De3yt&uspo&2yLb$(NwcPPI-4LGc!}HdY%jfq@AFs8LiZ4k(p} zZ!c9o+qbWYs-Mg zgdyTALzJX&7QXHdI_DPTFL33;w}88{e6Zk)MX0kN{3DX9uz#O_L58&XRH$Nvvu;fO zf&)7@?C~$z1K<>j0ga$$MIg+5xN;eQ?1-CA=`^Y169@Ab6!vcaNP=hxfKN%@Ly^R* zK1iv*s1Yl6_dVyz8>ZqYhz6J4|3fQ@2LQeX@^%W(B~8>=MoEmBEGGD1;gHXlpX>!W ym)!leA2L@`cpb^hy)P75=I!`pBYxP7<2VfQ3j76qLgzIA0000 ( + + SolidStart - with Vitest + {props.children} + + )} + > + + + ); +} diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/entry-client.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/entry-client.tsx new file mode 100644 index 000000000000..cbcd8f9267ca --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/entry-client.tsx @@ -0,0 +1,16 @@ +// @refresh reload +import * as Sentry from '@sentry/solidstart'; +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://public@dsn.ingest.sentry.io/1337', + environment: 'qa', // dynamic sampling bias to keep transactions + integrations: [Sentry.browserTracingIntegration()], + tunnel: 'http://localhost:3031/', // proxy server + // Performance Monitoring + tracesSampleRate: 1.0, // Capture 100% of the transactions +}); + +mount(() => , document.getElementById('app')!); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/entry-server.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/entry-server.tsx new file mode 100644 index 000000000000..276935366318 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/entry-server.tsx @@ -0,0 +1,21 @@ +// @refresh reload +import { StartServer, createHandler } from '@solidjs/start/server'; + +export default createHandler(() => ( + ( + + + + + + {assets} + + +
{children}
+ {scripts} + + + )} + /> +)); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/instrument.server.mjs b/dev-packages/e2e-tests/test-applications/solidstart/src/instrument.server.mjs new file mode 100644 index 000000000000..4146470295e1 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/instrument.server.mjs @@ -0,0 +1,8 @@ +import * as Sentry from '@sentry/solidstart'; + +Sentry.init({ + dsn: process.env.E2E_TEST_DSN, + environment: 'qa', // dynamic sampling bias to keep transactions + tracesSampleRate: 1.0, // Capture 100% of the transactions + tunnel: 'http://localhost:3031/', // proxy server +}); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx new file mode 100644 index 000000000000..e997e4fbb1e3 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/client-error.tsx @@ -0,0 +1,75 @@ +import * as Sentry from '@sentry/solidstart'; +import type { ParentProps } from 'solid-js'; +import { ErrorBoundary, createSignal, onMount } from 'solid-js'; + +const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary); + +const [count, setCount] = createSignal(1); +const [caughtError, setCaughtError] = createSignal(false); + +export default function ClientErrorPage() { + return ( + + {caughtError() && ( + + )} +
+
+ +
+
+ +
+
+
+ ); +} + +function Throw(props: { error: string }) { + onMount(() => { + throw new Error(props.error); + }); + return null; +} + +function SampleErrorBoundary(props: ParentProps) { + return ( + ( +
+

Error Boundary Fallback

+
+ {error.message} +
+ +
+ )} + > + {props.children} +
+ ); +} diff --git a/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx new file mode 100644 index 000000000000..a6d09d5b36b5 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/src/routes/index.tsx @@ -0,0 +1,17 @@ +import { A } from '@solidjs/router'; + +export default function Home() { + return ( + <> +

Welcome to Solid Start

+

+ Visit docs.solidjs.com/solid-start to read the documentation +

+ + + ); +} diff --git a/dev-packages/e2e-tests/test-applications/solidstart/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/solidstart/start-event-proxy.mjs new file mode 100644 index 000000000000..d45a7a013f36 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/start-event-proxy.mjs @@ -0,0 +1,6 @@ +import { startEventProxyServer } from '@sentry-internal/test-utils'; + +startEventProxyServer({ + port: 3031, + proxyServerName: 'solidstart', +}); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts b/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts new file mode 100644 index 000000000000..a4edf3c46236 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/tests/errorboundary.test.ts @@ -0,0 +1,90 @@ +import { expect, test } from '@playwright/test'; +import { waitForError } from '@sentry-internal/test-utils'; + +test('captures an exception', async ({ page }) => { + const errorEventPromise = waitForError('solidstart', errorEvent => { + return ( + !errorEvent.type && + errorEvent.exception?.values?.[0]?.value === + 'Error 1 thrown from Sentry ErrorBoundary in Solid Start E2E test app' + ); + }); + + await page.goto('/client-error'); + await page.locator('#caughtErrorBtn').click(); + const errorEvent = await errorEventPromise; + + expect(errorEvent).toMatchObject({ + exception: { + values: [ + { + type: 'Error', + value: 'Error 1 thrown from Sentry ErrorBoundary in Solid Start E2E test app', + mechanism: { + type: 'generic', + handled: true, + }, + }, + ], + }, + transaction: '/client-error', + }); +}); + +test('captures a second exception after resetting the boundary', async ({ page }) => { + const firstErrorEventPromise = waitForError('solidstart', errorEvent => { + return ( + !errorEvent.type && + errorEvent.exception?.values?.[0]?.value === + 'Error 1 thrown from Sentry ErrorBoundary in Solid Start E2E test app' + ); + }); + + await page.goto('/client-error'); + await page.locator('#caughtErrorBtn').click(); + const firstErrorEvent = await firstErrorEventPromise; + + expect(firstErrorEvent).toMatchObject({ + exception: { + values: [ + { + type: 'Error', + value: 'Error 1 thrown from Sentry ErrorBoundary in Solid Start E2E test app', + mechanism: { + type: 'generic', + handled: true, + }, + }, + ], + }, + transaction: '/client-error', + }); + + const secondErrorEventPromise = waitForError('solidstart', errorEvent => { + return ( + !errorEvent.type && + errorEvent.exception?.values?.[0]?.value === + 'Error 2 thrown from Sentry ErrorBoundary in Solid Start E2E test app' + ); + }); + + await page.locator('#errorBoundaryResetBtn').click(); + await page.locator('#caughtErrorBtn').click(); + const secondErrorEvent = await secondErrorEventPromise; + + expect(secondErrorEvent).toMatchObject({ + exception: { + values: [ + { + type: 'Error', + value: 'Error 2 thrown from Sentry ErrorBoundary in Solid Start E2E test app', + mechanism: { + type: 'generic', + handled: true, + }, + }, + ], + }, + transaction: '/client-error', + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts new file mode 100644 index 000000000000..c9ab1db244b5 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/tests/errors.client.test.ts @@ -0,0 +1,32 @@ +import { expect, test } from '@playwright/test'; +import { waitForError } from '@sentry-internal/test-utils'; + +test.describe('client-side errors', () => { + test('captures error thrown on click', async ({ page }) => { + const errorPromise = waitForError('solidstart', async errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Solid Start E2E test app'; + }); + + await page.goto(`/client-error`); + await page.locator('#errorBtn').click(); + const error = await errorPromise; + + expect(error).toMatchObject({ + exception: { + values: [ + { + type: 'Error', + value: 'Error thrown from Solid Start E2E test app', + mechanism: { + type: 'instrument', + handled: false, + }, + }, + ], + }, + transaction: '/client-error', + }); + expect(error.tags).toMatchObject({ runtime: 'browser' }); + expect(error.transaction).toEqual('/client-error'); + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/solidstart/tsconfig.json b/dev-packages/e2e-tests/test-applications/solidstart/tsconfig.json new file mode 100644 index 000000000000..6f11292cc5d8 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "allowJs": true, + "strict": true, + "noEmit": true, + "types": ["vinxi/types/client", "vitest/globals", "@testing-library/jest-dom"], + "isolatedModules": true, + "paths": { + "~/*": ["./src/*"] + } + } +} diff --git a/dev-packages/e2e-tests/test-applications/solidstart/vitest.config.ts b/dev-packages/e2e-tests/test-applications/solidstart/vitest.config.ts new file mode 100644 index 000000000000..6c2b639dc300 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/solidstart/vitest.config.ts @@ -0,0 +1,10 @@ +import solid from 'vite-plugin-solid'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [solid()], + resolve: { + conditions: ['development', 'browser'], + }, + envPrefix: 'PUBLIC_', +}); From 307e997ee7256bf1d3c86d763567e9600a566609 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Thu, 11 Jul 2024 12:14:58 +0200 Subject: [PATCH 2/2] Add .output and .vinxi to biome ignore --- biome.json | 4 +++- .../e2e-tests/test-applications/solidstart/README.md | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/biome.json b/biome.json index ccb69e4746db..cee069ac3127 100644 --- a/biome.json +++ b/biome.json @@ -43,7 +43,9 @@ ".angular/**", "angular.json", "ember/instance-initializers/**", - "ember/types.d.ts" + "ember/types.d.ts", + ".output", + ".vinxi" ] }, "files": { diff --git a/dev-packages/e2e-tests/test-applications/solidstart/README.md b/dev-packages/e2e-tests/test-applications/solidstart/README.md index 148dccaa7f6f..9a141e9c2f0d 100644 --- a/dev-packages/e2e-tests/test-applications/solidstart/README.md +++ b/dev-packages/e2e-tests/test-applications/solidstart/README.md @@ -14,7 +14,8 @@ npm init solid@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: +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 @@ -27,11 +28,13 @@ npm run dev -- --open Solid apps are built with _presets_, which optimise your project for deployment to different environments. -By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`. +By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add +it to the `devDependencies` in `package.json` and specify in your `app.config.js`. ## Testing -Tests are written with `vitest`, `@solidjs/testing-library` and `@testing-library/jest-dom` to extend expect with some helpful custom matchers. +Tests are written with `vitest`, `@solidjs/testing-library` and `@testing-library/jest-dom` to extend expect with some +helpful custom matchers. To run them, simply start: