diff --git a/packages/svelte/.eslintrc.js b/packages/svelte/.eslintrc.js index 0714feabf8d4..b6d4608e8e7b 100644 --- a/packages/svelte/.eslintrc.js +++ b/packages/svelte/.eslintrc.js @@ -2,6 +2,14 @@ module.exports = { env: { browser: true, }, + overrides: [ + { + files: ['vite.config.ts'], + parserOptions: { + project: ['tsconfig.test.json'], + }, + }, + ], extends: ['../../.eslintrc.js'], rules: { '@sentry-internal/sdk/no-unsupported-es6-methods': 'off', diff --git a/packages/svelte/jest.config.js b/packages/svelte/jest.config.js deleted file mode 100644 index 63637952d9d6..000000000000 --- a/packages/svelte/jest.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const baseConfig = require('../../jest/jest.config.js'); - -module.exports = { - ...baseConfig, - testEnvironment: 'jsdom', - transform: { - '^.+\\.svelte$': 'svelte-jester', - ...baseConfig.transform, - }, -}; diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 10c6dac63b7d..05d8142070d8 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -39,9 +39,9 @@ "svelte": "3.x || 4.x" }, "devDependencies": { - "@testing-library/svelte": "^3.2.1", "svelte": "3.49.0", - "svelte-jester": "^2.3.2" + "@sveltejs/vite-plugin-svelte": "1.4.0", + "@testing-library/svelte": "^3.2.1" }, "scripts": { "build": "run-p build:transpile build:types", @@ -59,8 +59,8 @@ "clean": "rimraf build coverage sentry-svelte-*.tgz", "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", - "test": "jest", - "test:watch": "jest --watch", + "test": "vitest", + "test:watch": "vitest --watch", "yalc:publish": "ts-node ../../scripts/prepack.ts && yalc publish build --push --sig" }, "volta": { diff --git a/packages/svelte/src/types.ts b/packages/svelte/src/types.ts index 4f4516606483..ed7fcfaa4928 100644 --- a/packages/svelte/src/types.ts +++ b/packages/svelte/src/types.ts @@ -60,5 +60,10 @@ export type ComponentTrackingInitOptions = { } & SpanOptions; export type TrackComponentOptions = { + /** + * The name of the component to be used in the recorded spans. + * + * @default to if not specified + */ componentName?: string; } & SpanOptions; diff --git a/packages/svelte/test/performance.test.ts b/packages/svelte/test/performance.test.ts index 9588da6e7d16..bdede73bc092 100644 --- a/packages/svelte/test/performance.test.ts +++ b/packages/svelte/test/performance.test.ts @@ -1,6 +1,7 @@ import type { Scope } from '@sentry/core'; import { act, render } from '@testing-library/svelte'; +import { vi } from 'vitest'; // linter doesn't like Svelte component imports import DummyComponent from './components/Dummy.svelte'; @@ -8,20 +9,20 @@ let returnUndefinedTransaction = false; const testTransaction: { spans: any[]; startChild: jest.Mock; end: jest.Mock; isRecording: () => boolean } = { spans: [], - startChild: jest.fn(), - end: jest.fn(), + startChild: vi.fn(), + end: vi.fn(), isRecording: () => true, }; -const testUpdateSpan = { end: jest.fn() }; +const testUpdateSpan = { end: vi.fn() }; const testInitSpan: any = { transaction: testTransaction, - end: jest.fn(), - startChild: jest.fn(), + end: vi.fn(), + startChild: vi.fn(), isRecording: () => true, }; -jest.mock('@sentry/core', () => { - const original = jest.requireActual('@sentry/core'); +vi.mock('@sentry/core', async () => { + const original = await vi.importActual('@sentry/core'); return { ...original, getCurrentScope(): Scope { @@ -36,7 +37,7 @@ jest.mock('@sentry/core', () => { describe('Sentry.trackComponent()', () => { beforeEach(() => { - jest.resetAllMocks(); + vi.resetAllMocks(); testTransaction.spans = []; testTransaction.startChild.mockImplementation(spanCtx => { @@ -49,7 +50,7 @@ describe('Sentry.trackComponent()', () => { return testUpdateSpan; }); - testInitSpan.end = jest.fn(); + testInitSpan.end = vi.fn(); testInitSpan.isRecording = () => true; returnUndefinedTransaction = false; }); @@ -58,13 +59,13 @@ describe('Sentry.trackComponent()', () => { render(DummyComponent, { props: { options: {} } }); expect(testTransaction.startChild).toHaveBeenCalledWith({ - description: '', + description: '', op: 'ui.svelte.init', origin: 'auto.ui.svelte', }); expect(testInitSpan.startChild).toHaveBeenCalledWith({ - description: '', + description: '', op: 'ui.svelte.update', origin: 'auto.ui.svelte', }); @@ -91,7 +92,7 @@ describe('Sentry.trackComponent()', () => { // once for init (unimportant here), once for starting the update span expect(testTransaction.startChild).toHaveBeenCalledTimes(2); expect(testTransaction.startChild).toHaveBeenLastCalledWith({ - description: '', + description: '', op: 'ui.svelte.update', origin: 'auto.ui.svelte', }); @@ -102,7 +103,7 @@ describe('Sentry.trackComponent()', () => { render(DummyComponent, { props: { options: { trackUpdates: false } } }); expect(testTransaction.startChild).toHaveBeenCalledWith({ - description: '', + description: '', op: 'ui.svelte.init', origin: 'auto.ui.svelte', }); @@ -117,7 +118,7 @@ describe('Sentry.trackComponent()', () => { render(DummyComponent, { props: { options: { trackInit: false } } }); expect(testTransaction.startChild).toHaveBeenCalledWith({ - description: '', + description: '', op: 'ui.svelte.update', origin: 'auto.ui.svelte', }); @@ -187,7 +188,7 @@ describe('Sentry.trackComponent()', () => { // but not the second update expect(testTransaction.startChild).toHaveBeenCalledTimes(1); expect(testTransaction.startChild).toHaveBeenLastCalledWith({ - description: '', + description: '', op: 'ui.svelte.init', origin: 'auto.ui.svelte', }); diff --git a/packages/svelte/test/sdk.test.ts b/packages/svelte/test/sdk.test.ts index 6144e065c643..9ccf5d7a4638 100644 --- a/packages/svelte/test/sdk.test.ts +++ b/packages/svelte/test/sdk.test.ts @@ -2,12 +2,13 @@ import { SDK_VERSION } from '@sentry/browser'; import * as SentryBrowser from '@sentry/browser'; import type { EventProcessor } from '@sentry/types'; +import { vi } from 'vitest'; import { detectAndReportSvelteKit, init as svelteInit, isSvelteKitApp } from '../src/sdk'; let passedEventProcessor: EventProcessor | undefined; -const browserInit = jest.spyOn(SentryBrowser, 'init'); -const addEventProcessor = jest +const browserInit = vi.spyOn(SentryBrowser, 'init'); +const addEventProcessor = vi .spyOn(SentryBrowser, 'addEventProcessor') .mockImplementation((eventProcessor: EventProcessor) => { passedEventProcessor = eventProcessor; @@ -16,7 +17,7 @@ const addEventProcessor = jest describe('Initialize Svelte SDk', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('has the correct metadata', () => { @@ -74,7 +75,7 @@ describe('Initialize Svelte SDk', () => { describe('detectAndReportSvelteKit()', () => { const originalHtmlBody = document.body.innerHTML; beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); document.body.innerHTML = originalHtmlBody; passedEventProcessor = undefined; }); diff --git a/packages/svelte/tsconfig.test.json b/packages/svelte/tsconfig.test.json index af7e36ec0eda..fc9e549d35ce 100644 --- a/packages/svelte/tsconfig.test.json +++ b/packages/svelte/tsconfig.test.json @@ -1,11 +1,11 @@ { "extends": "./tsconfig.json", - "include": ["test/**/*"], + "include": ["test/**/*", "vite.config.ts"], "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["jest"] + "types": ["vitest/globals"] // other package-specific, test-specific options } diff --git a/packages/svelte/vite.config.ts b/packages/svelte/vite.config.ts new file mode 100644 index 000000000000..50b07efd9b71 --- /dev/null +++ b/packages/svelte/vite.config.ts @@ -0,0 +1,15 @@ +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import type { UserConfig } from 'vitest'; +import baseConfig from '../../vite/vite.config'; + +export default { + ...baseConfig, + plugins: [svelte({ hot: !process.env.VITEST })], + test: { + // test exists, no idea why TS doesn't recognize it + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ...(baseConfig as UserConfig & { test: any }).test, + environment: 'jsdom', + alias: [{ find: /^svelte$/, replacement: 'svelte/internal' }], + }, +};