diff --git a/commons/src/frontmatter-extractor/extractor.spec.ts b/commons/src/frontmatter-extractor/extractor.spec.ts index 3ded83770..66937f8a3 100644 --- a/commons/src/frontmatter-extractor/extractor.spec.ts +++ b/commons/src/frontmatter-extractor/extractor.spec.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { extractFrontmatter } from './extractor.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' describe('frontmatter extraction', () => { describe('isPresent property', () => { diff --git a/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts b/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts index 08db95bde..788974a5f 100644 --- a/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts +++ b/commons/src/note-frontmatter-parser/convert-raw-frontmatter-to-note-frontmatter.spec.ts @@ -11,7 +11,7 @@ import { } from '../note-frontmatter/frontmatter.js' import { SlideOptions } from '../note-frontmatter/slide-show-options.js' import { convertRawFrontmatterToNoteFrontmatter } from './convert-raw-frontmatter-to-note-frontmatter.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' describe('convertRawFrontmatterToNoteFrontmatter', () => { it.each([false, true])( diff --git a/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts b/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts index 45446188c..f2166c627 100644 --- a/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts +++ b/commons/src/note-frontmatter-parser/parse-raw-frontmatter-from-yaml.spec.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { parseRawFrontmatterFromYaml } from './parse-raw-frontmatter-from-yaml.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' describe('yaml frontmatter', () => { it('should parse "title"', () => { diff --git a/commons/src/parse-url/parse-url.spec.ts b/commons/src/parse-url/parse-url.spec.ts index f5e2955a8..d94ed33d5 100644 --- a/commons/src/parse-url/parse-url.spec.ts +++ b/commons/src/parse-url/parse-url.spec.ts @@ -5,7 +5,7 @@ */ import { NoSubdirectoryAllowedError, WrongProtocolError } from './errors.js' import { parseUrl } from './parse-url.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' describe('validate url', () => { it("doesn't accept non-urls", () => { diff --git a/commons/src/permissions/permissions.spec.ts b/commons/src/permissions/permissions.spec.ts index 8e13d20e0..076c5523b 100644 --- a/commons/src/permissions/permissions.spec.ts +++ b/commons/src/permissions/permissions.spec.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { userCanEdit, userIsOwner } from './permissions.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' import { NotePermissionsDto, SpecialGroup } from '../dtos/index.js' describe('Permissions', () => { diff --git a/commons/src/title-extraction/extract-first-heading.spec.ts b/commons/src/title-extraction/extract-first-heading.spec.ts index 8267b2efa..0b5b4bf0f 100644 --- a/commons/src/title-extraction/extract-first-heading.spec.ts +++ b/commons/src/title-extraction/extract-first-heading.spec.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { extractFirstHeading } from './extract-first-heading.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' import { Document, Element, Text } from 'domhandler' describe('extract first heading', () => { diff --git a/commons/src/title-extraction/generate-note-title.spec.ts b/commons/src/title-extraction/generate-note-title.spec.ts index 301a1dd44..e56049dcf 100644 --- a/commons/src/title-extraction/generate-note-title.spec.ts +++ b/commons/src/title-extraction/generate-note-title.spec.ts @@ -9,7 +9,7 @@ import { NoteType, } from '../note-frontmatter/frontmatter.js' import { generateNoteTitle } from './generate-note-title.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' const testFrontmatter: NoteFrontmatter = { title: '', diff --git a/commons/src/y-doc-sync/realtime-doc.spec.ts b/commons/src/y-doc-sync/realtime-doc.spec.ts index 7293a0dd5..b3a5838de 100644 --- a/commons/src/y-doc-sync/realtime-doc.spec.ts +++ b/commons/src/y-doc-sync/realtime-doc.spec.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { RealtimeDoc } from './realtime-doc.js' -import { describe, expect, it } from 'vitest' +import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' describe('realtime doc', () => { it('saves an initial text content correctly', () => { diff --git a/frontend/package.json b/frontend/package.json index a09fdffef..ff149d922 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,9 +19,9 @@ "test:e2e:open": "cypress open", "test:e2e": "cypress run --browser chrome", "test:e2e:ci": "cypress run --browser chrome --record true --parallel --group \"chrome\"", - "test:watch": "cross-env NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" NODE_ENV=test jest --watch", - "test:ci": "cross-env NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" NODE_ENV=test jest --coverage", - "test": "cross-env NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" NODE_ENV=test jest" + "test:watch": "cross-env NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" NODE_ENV=test vitest --watch", + "test:ci": "cross-env NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" NODE_ENV=test vitest --coverage", + "test": "cross-env NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" NODE_ENV=test vitest" }, "browserslist": [ "Chrome 118", @@ -131,7 +131,6 @@ "@types/d3-graphviz": "2.6.10", "@types/diff": "6.0.0", "@types/dompurify": "3.0.5", - "@types/jest": "29.5.14", "@types/katex": "0.16.7", "@types/luxon": "3.4.2", "@types/markdown-it": "13.0.8", @@ -141,6 +140,7 @@ "@types/react": "19.1.2", "@types/react-dom": "19.1.2", "@types/ws": "8.5.12", + "@vitejs/plugin-react": "4.4.1", "csstype": "3.1.3", "cypress": "13.17.0", "cypress-commands": "3.0.0", @@ -156,8 +156,7 @@ "eslint-plugin-prettier": "5.2.6", "eslint-plugin-promise": "7.2.1", "eslint-plugin-testing-library": "7.1.1", - "jest": "29.7.0", - "jest-environment-jsdom": "29.7.0", + "jsdom": "26.1.0", "prettier": "3.3.3", "react-test-renderer": "18.3.1", "ts-loader": "9.5.2", @@ -165,7 +164,8 @@ "ts-node": "11.0.0-beta.1", "typescript": "5.6.3", "typescript-eslint": "8.31.0", - "user-agent-data-types": "0.4.2" + "user-agent-data-types": "0.4.2", + "vitest": "3.1.2" }, "packageManager": "yarn@4.5.3", "resolutions": { diff --git a/frontend/src/api/common/api-request-builder/delete-api-request-builder.spec.ts b/frontend/src/api/common/api-request-builder/delete-api-request-builder.spec.ts index 4d46143a6..7483c37a4 100644 --- a/frontend/src/api/common/api-request-builder/delete-api-request-builder.spec.ts +++ b/frontend/src/api/common/api-request-builder/delete-api-request-builder.spec.ts @@ -7,6 +7,7 @@ import { ApiError } from '../api-error' import type { ApiErrorResponse } from '../api-error-response' import { DeleteApiRequestBuilder } from './delete-api-request-builder' import { expectFetch } from './test-utils/expect-fetch' +import { describe, expect, it, beforeAll, afterAll } from 'vitest' describe('DeleteApiRequestBuilder', () => { let originalFetch: (typeof global)['fetch'] diff --git a/frontend/src/api/common/api-request-builder/get-api-request-builder.spec.ts b/frontend/src/api/common/api-request-builder/get-api-request-builder.spec.ts index ca7576df7..ada851851 100644 --- a/frontend/src/api/common/api-request-builder/get-api-request-builder.spec.ts +++ b/frontend/src/api/common/api-request-builder/get-api-request-builder.spec.ts @@ -7,6 +7,7 @@ import { ApiError } from '../api-error' import type { ApiErrorResponse } from '../api-error-response' import { GetApiRequestBuilder } from './get-api-request-builder' import { expectFetch } from './test-utils/expect-fetch' +import { describe, expect, it, beforeAll, afterAll } from 'vitest' describe('GetApiRequestBuilder', () => { let originalFetch: (typeof global)['fetch'] diff --git a/frontend/src/api/common/api-request-builder/post-api-request-builder.spec.ts b/frontend/src/api/common/api-request-builder/post-api-request-builder.spec.ts index 11ec1856d..6192efa8b 100644 --- a/frontend/src/api/common/api-request-builder/post-api-request-builder.spec.ts +++ b/frontend/src/api/common/api-request-builder/post-api-request-builder.spec.ts @@ -7,6 +7,7 @@ import { ApiError } from '../api-error' import type { ApiErrorResponse } from '../api-error-response' import { PostApiRequestBuilder } from './post-api-request-builder' import { expectFetch } from './test-utils/expect-fetch' +import { describe, expect, it, beforeAll, afterAll } from 'vitest' describe('PostApiRequestBuilder', () => { let originalFetch: (typeof global)['fetch'] diff --git a/frontend/src/api/common/api-request-builder/put-api-request-builder.spec.ts b/frontend/src/api/common/api-request-builder/put-api-request-builder.spec.ts index 4c4d9b8d6..dcdf51742 100644 --- a/frontend/src/api/common/api-request-builder/put-api-request-builder.spec.ts +++ b/frontend/src/api/common/api-request-builder/put-api-request-builder.spec.ts @@ -7,6 +7,7 @@ import { ApiError } from '../api-error' import type { ApiErrorResponse } from '../api-error-response' import { PutApiRequestBuilder } from './put-api-request-builder' import { expectFetch } from './test-utils/expect-fetch' +import { describe, expect, it, beforeAll, afterAll } from 'vitest' describe('PutApiRequestBuilder', () => { let originalFetch: (typeof global)['fetch'] diff --git a/frontend/src/api/common/api-request-builder/test-utils/expect-fetch.ts b/frontend/src/api/common/api-request-builder/test-utils/expect-fetch.ts index 62667fb88..7ad0e5c1c 100644 --- a/frontend/src/api/common/api-request-builder/test-utils/expect-fetch.ts +++ b/frontend/src/api/common/api-request-builder/test-utils/expect-fetch.ts @@ -5,6 +5,7 @@ */ import { defaultConfig } from '../../default-config' import { Mock } from 'ts-mockery' +import { vi, expect } from 'vitest' /** * Mock fetch api for tests. @@ -20,7 +21,7 @@ export const expectFetch = ( expectedOptions: RequestInit, responseBody?: unknown ): void => { - global.fetch = jest.fn((fetchUrl: RequestInfo | URL, fetchOptions?: RequestInit): Promise => { + global.fetch = vi.fn((fetchUrl: RequestInfo | URL, fetchOptions?: RequestInit): Promise => { expect(fetchUrl).toEqual(expectedUrl) expect(fetchOptions).toStrictEqual({ ...defaultConfig, @@ -32,7 +33,7 @@ export const expectFetch = ( Mock.of({ status: requestStatusCode, statusText: mapCodeToText(requestStatusCode), - json: jest.fn(() => (responseBody ? Promise.resolve(responseBody) : Promise.reject(new Error()))) + json: vi.fn(() => (responseBody ? Promise.resolve(responseBody) : Promise.reject(new Error()))) }) ) }) as typeof global.fetch diff --git a/frontend/src/api/common/api-response.spec.ts b/frontend/src/api/common/api-response.spec.ts index 006f01236..b4563391d 100644 --- a/frontend/src/api/common/api-response.spec.ts +++ b/frontend/src/api/common/api-response.spec.ts @@ -5,6 +5,7 @@ */ import { ApiResponse } from './api-response' import { Mock } from 'ts-mockery' +import { describe, expect, it, beforeAll, afterAll } from 'vitest' describe('ApiResponse', () => { it('getResponse returns input response', () => { diff --git a/frontend/src/api/common/error-to-i18n-key-mapper.spec.ts b/frontend/src/api/common/error-to-i18n-key-mapper.spec.ts index 02ae3ea4f..0b5e45e32 100644 --- a/frontend/src/api/common/error-to-i18n-key-mapper.spec.ts +++ b/frontend/src/api/common/error-to-i18n-key-mapper.spec.ts @@ -5,6 +5,7 @@ */ import { ApiError } from './api-error' import { ErrorToI18nKeyMapper } from './error-to-i18n-key-mapper' +import { describe, expect, it, beforeAll, afterAll } from 'vitest' describe('ErrorToI18nKeyMapper', () => { it('returns fallback with namespace when no mapper is defined', () => { diff --git a/frontend/src/app/(editor)/@appBar/n/[noteId]/__snapshots__/editor-app-bar.spec.tsx.snap b/frontend/src/app/(editor)/@appBar/n/[noteId]/__snapshots__/editor-app-bar.spec.tsx.snap index e2cae6dc6..9790905cc 100644 --- a/frontend/src/app/(editor)/@appBar/n/[noteId]/__snapshots__/editor-app-bar.spec.tsx.snap +++ b/frontend/src/app/(editor)/@appBar/n/[noteId]/__snapshots__/editor-app-bar.spec.tsx.snap @@ -1,20 +1,12 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`app bar contains alert when editor is not synced 1`] = ` +exports[`app bar > contains alert when editor is not synced 1`] = `
first part -
- -
+
last part @@ -22,24 +14,13 @@ exports[`app bar contains alert when editor is not synced 1`] = `
`; -exports[`app bar contains note title and read-only marker when having only read permissions 1`] = ` +exports[`app bar > contains note title and read-only marker when having only read permissions 1`] = `
first part -
- - - BootstrapIconMock_Lock - - Note Title Test - -
+
last part @@ -47,19 +28,13 @@ exports[`app bar contains note title and read-only marker when having only read
`; -exports[`app bar contains note title when editor is synced 1`] = ` +exports[`app bar > contains note title when editor is synced 1`] = `
first part -
- - Note Title Test - -
+
last part diff --git a/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx b/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx index 8614d6e91..5852aea51 100644 --- a/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx +++ b/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx @@ -10,8 +10,9 @@ import { render } from '@testing-library/react' import type { PropsWithChildren } from 'react' import React from 'react' import { mockAppState } from '../../../../../test-utils/mock-app-state' +import { vi, describe, it, beforeAll, afterAll, expect } from 'vitest' -jest.mock('../../../../../components/layout/app-bar/base-app-bar', () => ({ +vi.mock('../../../../../components/layout/app-bar/base-app-bar', () => ({ __esModule: true, BaseAppBar: ({ children }: PropsWithChildren) => (
@@ -21,7 +22,7 @@ jest.mock('../../../../../components/layout/app-bar/base-app-bar', () => ({
) })) -jest.mock('../../../../../hooks/common/use-application-state') +vi.mock('../../../../../hooks/common/use-application-state') const mockedCommonAppState = { noteDetails: { @@ -44,7 +45,7 @@ const mockedCommonAppState = { describe('app bar', () => { beforeAll(mockI18n) - afterAll(() => jest.restoreAllMocks()) + afterAll(() => vi.restoreAllMocks()) it('contains note title when editor is synced', () => { mockAppState({ diff --git a/frontend/src/components/common/application-error-alert/__snapshots__/application-error-alert.spec.tsx.snap b/frontend/src/components/common/application-error-alert/__snapshots__/application-error-alert.spec.tsx.snap index 289c36a54..b37e253c6 100644 --- a/frontend/src/components/common/application-error-alert/__snapshots__/application-error-alert.spec.tsx.snap +++ b/frontend/src/components/common/application-error-alert/__snapshots__/application-error-alert.spec.tsx.snap @@ -1,15 +1,15 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`ApplicationErrorAlert renders correctly 1`] = ` +exports[`ApplicationErrorAlert > renders correctly 1`] = `