From ba7554462c9cd2963df843abfce0da572a089cd1 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 26 Apr 2024 15:59:45 +0200 Subject: [PATCH 1/3] test(svelte): Add Svelte 5 E2E test app --- .../test-applications/svelte-5/.gitignore | 24 ++++++ .../test-applications/svelte-5/.npmrc | 2 + .../test-applications/svelte-5/README.md | 47 +++++++++++ .../test-applications/svelte-5/index.html | 13 +++ .../test-applications/svelte-5/package.json | 32 ++++++++ .../svelte-5/playwright.config.ts | 77 ++++++++++++++++++ .../svelte-5/public/vite.svg | 1 + .../test-applications/svelte-5/src/App.svelte | 52 ++++++++++++ .../test-applications/svelte-5/src/app.css | 79 +++++++++++++++++++ .../svelte-5/src/assets/svelte.svg | 1 + .../svelte-5/src/lib/Counter.svelte | 11 +++ .../test-applications/svelte-5/src/main.ts | 23 ++++++ .../svelte-5/src/vite-env.d.ts | 2 + .../svelte-5/start-event-proxy.cjs | 6 ++ .../svelte-5/svelte.config.js | 7 ++ .../svelte-5/test/errors.test.ts | 30 +++++++ .../svelte-5/test/performance.test.ts | 25 ++++++ .../test-applications/svelte-5/tsconfig.json | 20 +++++ .../svelte-5/tsconfig.node.json | 10 +++ .../test-applications/svelte-5/vite.config.ts | 8 ++ 20 files changed, 470 insertions(+) create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/.gitignore create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/.npmrc create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/README.md create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/index.html create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/package.json create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/playwright.config.ts create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/public/vite.svg create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/src/App.svelte create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/src/app.css create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/src/assets/svelte.svg create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/src/vite-env.d.ts create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/start-event-proxy.cjs create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/test/errors.test.ts create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.json create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.node.json create mode 100644 dev-packages/e2e-tests/test-applications/svelte-5/vite.config.ts diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/.gitignore b/dev-packages/e2e-tests/test-applications/svelte-5/.gitignore new file mode 100644 index 000000000000..a547bf36d8d1 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/.npmrc b/dev-packages/e2e-tests/test-applications/svelte-5/.npmrc new file mode 100644 index 000000000000..070f80f05092 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/.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/svelte-5/README.md b/dev-packages/e2e-tests/test-applications/svelte-5/README.md new file mode 100644 index 000000000000..e6cd94fce77d --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/README.md @@ -0,0 +1,47 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/index.html b/dev-packages/e2e-tests/test-applications/svelte-5/index.html new file mode 100644 index 000000000000..b6c5f0afafd6 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + TS + + +
+ + + diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/package.json b/dev-packages/e2e-tests/test-applications/svelte-5/package.json new file mode 100644 index 000000000000..d95aa579e9a6 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/package.json @@ -0,0 +1,32 @@ +{ + "name": "svelte-5", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json", + "test:prod": "TEST_ENV=production playwright test", + "test:build": "pnpm install && npx playwright install && pnpm build", + "test:assert": "pnpm test:prod" + }, + "devDependencies": { + "@playwright/test": "^1.43.1", + "@sentry-internal/event-proxy-server": "link:../../../event-proxy-server", + "@sentry/types": "latest || *", + "@sentry/utils": "latest || *", + "@sveltejs/vite-plugin-svelte": "^3.0.2", + "@tsconfig/svelte": "^5.0.2", + "svelte": "^5.0.0-next.115", + "svelte-check": "^3.6.7", + "tslib": "^2.6.2", + "typescript": "^5.2.2", + "vite": "^5.2.0", + "wait-port": "1.0.4" + }, + "dependencies": { + "@sentry/svelte": "latest || *" + } +} diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/playwright.config.ts b/dev-packages/e2e-tests/test-applications/svelte-5/playwright.config.ts new file mode 100644 index 000000000000..7dfcfbe74cec --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/playwright.config.ts @@ -0,0 +1,77 @@ +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; + +// Fix urls not resolving to localhost on Node v17+ +// See: https://github.com/axios/axios/issues/3821#issuecomment-1413727575 +import { setDefaultResultOrder } from 'dns'; +setDefaultResultOrder('ipv4first'); + +const testEnv = process.env.TEST_ENV; + +if (!testEnv) { + throw new Error('No test env defined'); +} + +const sveltePort = 3030; +const eventProxyPort = 3031; + +/** + * 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: false, + workers: 1, + /* 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:${sveltePort}`, + + /* 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: 'node ./start-event-proxy.cjs', + port: eventProxyPort, + reuseExistingServer: false, + }, + { + command: `pnpm wait-port ${eventProxyPort} && pnpm preview --port ${sveltePort}`, + port: sveltePort, + reuseExistingServer: false, + }, + ], +}; + +export default config; diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/public/vite.svg b/dev-packages/e2e-tests/test-applications/svelte-5/public/vite.svg new file mode 100644 index 000000000000..e7b8dfb1b2a6 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/App.svelte b/dev-packages/e2e-tests/test-applications/svelte-5/src/App.svelte new file mode 100644 index 000000000000..47d6be1385b4 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/App.svelte @@ -0,0 +1,52 @@ + + +
+
+ + + + + + +
+

Vite + Svelte

+ +
+ + +
+ +

+ Check out SvelteKit, the official Svelte app framework powered by Vite! +

+ +

+ Click on the Vite and Svelte logos to learn more +

+
+ + diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/app.css b/dev-packages/e2e-tests/test-applications/svelte-5/src/app.css new file mode 100644 index 000000000000..617f5e93c0a7 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/app.css @@ -0,0 +1,79 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/assets/svelte.svg b/dev-packages/e2e-tests/test-applications/svelte-5/src/assets/svelte.svg new file mode 100644 index 000000000000..c5e08481f8ae --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte b/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte new file mode 100644 index 000000000000..38a921f645f5 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte @@ -0,0 +1,11 @@ + + + diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts b/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts new file mode 100644 index 000000000000..23c27f794892 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts @@ -0,0 +1,23 @@ +import { mount } from 'svelte'; +import App from './App.svelte'; +import './app.css'; + +import * as Sentry from '@sentry/svelte'; + +Sentry.init({ + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: import.meta.env.PUBLIC_E2E_TEST_DSN, + tracesSampleRate: 1.0, + integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()], + tunnel: 'http://localhost:3031/', // proxy server +}); + +const target = document.getElementById('app'); + +if (!target) { + throw new Error('Could not find target element'); +} + +const app = mount(App, { target }); + +export default app; diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/vite-env.d.ts b/dev-packages/e2e-tests/test-applications/svelte-5/src/vite-env.d.ts new file mode 100644 index 000000000000..4078e7476a2e --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/start-event-proxy.cjs b/dev-packages/e2e-tests/test-applications/svelte-5/start-event-proxy.cjs new file mode 100644 index 000000000000..c1bc0c947a67 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/start-event-proxy.cjs @@ -0,0 +1,6 @@ +const { startEventProxyServer } = require('@sentry-internal/event-proxy-server'); + +startEventProxyServer({ + port: 3031, + proxyServerName: 'svelte-5', +}); diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js b/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js new file mode 100644 index 000000000000..b0683fd24d70 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/test/errors.test.ts b/dev-packages/e2e-tests/test-applications/svelte-5/test/errors.test.ts new file mode 100644 index 000000000000..803e49e24fd0 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/test/errors.test.ts @@ -0,0 +1,30 @@ +import { expect, test } from '@playwright/test'; +import { waitForError } from '@sentry-internal/event-proxy-server'; + +test('sends an error', async ({ page }) => { + const errorPromise = waitForError('svelte-5', async errorEvent => { + return !errorEvent.type; + }); + + await page.goto(`/`); + + await page.locator('#errorBtn').click(); + + const error = await errorPromise; + + expect(error).toMatchObject({ + exception: { + values: [ + { + type: 'Error', + value: 'Error thrown from Svelte 5 E2E test app', + mechanism: { + type: 'instrument', + handled: false, + }, + }, + ], + }, + transaction: '/', + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts b/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts new file mode 100644 index 000000000000..54097b7b4356 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from '@playwright/test'; +import { waitForTransaction } from '@sentry-internal/event-proxy-server'; + +test('sends a pageload transaction', async ({ page }) => { + const transactionPromise = waitForTransaction('svelte-5', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; + }); + + await page.goto(`/`); + + const rootSpan = await transactionPromise; + + expect(rootSpan).toMatchObject({ + contexts: { + trace: { + op: 'pageload', + origin: 'auto.pageload.browser', + }, + }, + transaction: '/', + transaction_info: { + source: 'url', + }, + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.json b/dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.json new file mode 100644 index 000000000000..5fb548f2b4f6 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.node.json b/dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.node.json new file mode 100644 index 000000000000..d02c37dfe5fd --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/vite.config.ts b/dev-packages/e2e-tests/test-applications/svelte-5/vite.config.ts new file mode 100644 index 000000000000..73f8ad0c1a43 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/svelte-5/vite.config.ts @@ -0,0 +1,8 @@ +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], + envPrefix: 'PUBLIC_', +}); From c3a4dce8ca2f187635e8e2f963fa51d02225c6d2 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 26 Apr 2024 16:01:26 +0200 Subject: [PATCH 2/3] add to CI, formatting --- .github/workflows/build.yml | 1 + .../test-applications/svelte-5/README.md | 37 +++++++++++++------ .../svelte-5/svelte.config.js | 4 +- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9bcf44c39024..b3429df6f6ca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1006,6 +1006,7 @@ jobs: 'react-create-hash-router', 'react-router-6-use-routes', 'standard-frontend-react', + 'svelte-5', 'sveltekit', 'sveltekit-2', 'sveltekit-2-svelte-5', diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/README.md b/dev-packages/e2e-tests/test-applications/svelte-5/README.md index e6cd94fce77d..89a8fa13539e 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/README.md +++ b/dev-packages/e2e-tests/test-applications/svelte-5/README.md @@ -4,11 +4,14 @@ This template should help get you started developing with Svelte and TypeScript ## Recommended IDE Setup -[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). +[VS Code](https://code.visualstudio.com/) + +[Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). ## Need an official Svelte framework? -Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its +serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, +and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. ## Technical considerations @@ -17,31 +20,43 @@ Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also pow - It brings its own routing solution which might not be preferable for some users. - It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. -This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account +the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other +`create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. -Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been +structured similarly to SvelteKit so that it is easy to migrate. **Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** -Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash +references keeps the default TypeScript setting of accepting type information from the entire workspace, while also +adding `svelte` and `vite/client` type information. **Why include `.vscode/extensions.json`?** -Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to +install the recommended extension upon opening the project. **Why enable `allowJs` in the TS template?** -While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of +JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: +not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing +JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. **Why is HMR not preserving my local component state?** -HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and +`@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details +[here](https://github.com/rixo/svelte-hmr#svelte-hmr). -If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. +If you have state that's important to retain within a component, consider creating an external store which would not be +replaced by HMR. ```ts // store.ts // An extremely simple external store -import { writable } from 'svelte/store' -export default writable(0) +import { writable } from 'svelte/store'; +export default writable(0); ``` diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js b/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js index b0683fd24d70..3bce8eaa6cda 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js +++ b/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js @@ -1,7 +1,7 @@ -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; export default { // Consult https://svelte.dev/docs#compile-time-svelte-preprocess // for more information about preprocessors preprocess: vitePreprocess(), -} +}; From 458aa2217b951c7991ecaeb68c9ae639b0c9660a Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 26 Apr 2024 16:39:10 +0200 Subject: [PATCH 3/3] add component tracking asserts --- .../svelte-5/src/lib/Counter.svelte | 12 ++++++--- .../test-applications/svelte-5/src/main.ts | 1 + .../svelte-5/svelte.config.js | 9 ++++++- .../svelte-5/test/performance.test.ts | 27 ++++++++++++++++--- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte b/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte index 38a921f645f5..397bfd1c7321 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/lib/Counter.svelte @@ -1,11 +1,17 @@ + +

+ doubled: {doubled} +

diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts b/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts index 23c27f794892..e42063fb9183 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts +++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts @@ -10,6 +10,7 @@ Sentry.init({ tracesSampleRate: 1.0, integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()], tunnel: 'http://localhost:3031/', // proxy server + debug: true, }); const target = document.getElementById('app'); diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js b/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js index 3bce8eaa6cda..e888802c9528 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js +++ b/dev-packages/e2e-tests/test-applications/svelte-5/svelte.config.js @@ -1,7 +1,14 @@ +import { withSentryConfig } from '@sentry/svelte'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; -export default { +const config = { // Consult https://svelte.dev/docs#compile-time-svelte-preprocess // for more information about preprocessors preprocess: vitePreprocess(), }; + +const configWithSentry = withSentryConfig(config, { + componentTracking: { trackUpdates: false, trackComponents: true, trackInit: true }, +}); + +export default configWithSentry; diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts b/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts index 54097b7b4356..5e4e52d597b4 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts +++ b/dev-packages/e2e-tests/test-applications/svelte-5/test/performance.test.ts @@ -1,16 +1,16 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/event-proxy-server'; -test('sends a pageload transaction', async ({ page }) => { +test('sends a pageload transaction with component tracking init spans', async ({ page }) => { const transactionPromise = waitForTransaction('svelte-5', async transactionEvent => { return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; }); await page.goto(`/`); - const rootSpan = await transactionPromise; + const pageloadTransaction = await transactionPromise; - expect(rootSpan).toMatchObject({ + expect(pageloadTransaction).toMatchObject({ contexts: { trace: { op: 'pageload', @@ -22,4 +22,25 @@ test('sends a pageload transaction', async ({ page }) => { source: 'url', }, }); + + expect(pageloadTransaction.spans).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + op: 'ui.svelte.init', + description: '', + data: { + 'sentry.op': 'ui.svelte.init', + 'sentry.origin': 'auto.ui.svelte', + }, + }), + expect.objectContaining({ + op: 'ui.svelte.init', + description: '', + data: { + 'sentry.op': 'ui.svelte.init', + 'sentry.origin': 'auto.ui.svelte', + }, + }), + ]), + ); });