mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
d29b06c6e8
Promote Viewer grants to Editor on book libraries for non-superusers who hold Edit metadata but can edit nowhere, which is how every such account was left after the upgrade. Accounts with any Editor or Owner role are left alone. The Users drawer now says where Edit metadata takes effect, read from a new GET /users/:id/library-access route. Closes #1902
1380 lines
51 KiB
JavaScript
1380 lines
51 KiB
JavaScript
const TEST_RESULTS_DIR = "../test-results/server";
|
|
|
|
export const E2E_GLOBAL_CHANGE_PATHS = Object.freeze([
|
|
".github/workflows/ci.yml",
|
|
".github/workflows/e2e.yml",
|
|
".github/workflows/e2e-runner.yml",
|
|
"Dockerfile",
|
|
"docker-compose*.yml",
|
|
"docker/**",
|
|
]);
|
|
|
|
const SHARED_DB_AND_HELPER_PATHS = Object.freeze(["server/src/db/schema/**", "scripts/e2e/**", "scripts/db/**"]);
|
|
|
|
const SHARED_AUTH_TYPE_PATHS = Object.freeze(["packages/types/src/auth.ts", "packages/types/src/permissions.ts"]);
|
|
|
|
const SHARED_TYPES_PATHS = Object.freeze(["packages/types/src/**"]);
|
|
|
|
export const E2E_SUITES = Object.freeze({
|
|
"djvu-reader": {
|
|
id: "djvu-reader",
|
|
name: "DjVuLibre Reader",
|
|
timeout: 30,
|
|
lane: "full",
|
|
description: "Native decoding, OCR, authenticated cache revalidation, paged progress and reader preference isolation",
|
|
vitestTarget: "test/djvu-reader.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/djvu-reader-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/reader/djvu/**",
|
|
"server/src/modules/djvu/**",
|
|
"client/src/features/reader/**",
|
|
"server/test/djvu-reader.e2e-spec.ts",
|
|
"server/test/e2e/djvu-fixture.ts",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"read-aloud-delivery": {
|
|
id: "read-aloud-delivery",
|
|
name: "Read-aloud Delivery",
|
|
timeout: 30,
|
|
lane: "full",
|
|
description: "Variant byte stability, profile isolation, Kobo artifacts and replacement, and released-client settings semantics",
|
|
vitestTarget: "test/read-aloud-delivery.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/read-aloud-delivery-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book/delivery*",
|
|
"server/src/modules/kobo/**",
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/opds/**",
|
|
"server/src/modules/email/**",
|
|
"server/test/read-aloud-delivery.e2e-spec.ts",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"guard-mechanics": {
|
|
id: "guard-mechanics",
|
|
name: "Guard Mechanics",
|
|
timeout: 30,
|
|
lane: "smoke",
|
|
description: "Guard mechanics suite - verifies @Public/@RequirePermission wiring without a real DB",
|
|
vitestTarget: "test/guard-mechanics.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/guard-mechanics-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: false,
|
|
useDedicatedDatabase: false,
|
|
changedPaths: [
|
|
"server/src/common/guards/**",
|
|
"server/src/common/decorators/**",
|
|
"server/src/common/types/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/role/**",
|
|
"server/src/**",
|
|
"server/test/guard-mechanics.e2e-spec.ts",
|
|
"server/test/e2e/**",
|
|
...SHARED_AUTH_TYPE_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"scanner-scenarios": {
|
|
id: "scanner-scenarios",
|
|
name: "Scanner Scenarios",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Scanner scenario matrix",
|
|
vitestTarget: "test/scanner-scenarios.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/scanner-scenarios-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/metadata/cover-slot-reconciler.service.ts",
|
|
"server/src/modules/scanner/**",
|
|
"server/test/scanner-scenarios.e2e-spec.ts",
|
|
"server/test/e2e/scanner/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"scanner-file-operations": {
|
|
id: "scanner-file-operations",
|
|
name: "Scanner File Operations",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Scanner file operation matrix",
|
|
vitestTarget: "test/scanner-file-operations.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/scanner-file-operations-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/metadata/cover-slot-reconciler.service.ts",
|
|
"server/src/modules/scanner/**",
|
|
"server/test/scanner-file-operations.e2e-spec.ts",
|
|
"server/test/e2e/scanner/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"audiobook-track-order": {
|
|
id: "audiobook-track-order",
|
|
name: "Audiobook Track Order",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Audiobook playback order matches file names after overlapping scans and added tracks",
|
|
vitestTarget: "test/audiobook-track-order.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/audiobook-track-order-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/common/utils/audio-track-order.utils.ts",
|
|
"server/src/common/utils/book-media.utils.ts",
|
|
"server/src/db/audio-track-order.ts",
|
|
"server/src/modules/audiobook/**",
|
|
"server/src/modules/scanner/**",
|
|
"server/src/modules/upload/**",
|
|
"server/test/audiobook-track-order.e2e-spec.ts",
|
|
"server/test/e2e/scanner/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"auth-session-security": {
|
|
id: "auth-session-security",
|
|
name: "Auth Session Security",
|
|
timeout: 50,
|
|
lane: "full",
|
|
description: "Auth session security suite",
|
|
vitestTarget: "test/auth-session-security.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/auth-session-security-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/role/**",
|
|
"server/src/common/guards/**",
|
|
"server/src/common/decorators/**",
|
|
"server/src/common/types/**",
|
|
"server/test/auth-session-security.e2e-spec.ts",
|
|
"server/test/e2e/app-harness.ts",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_AUTH_TYPE_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"auth-recovery-oidc-logout": {
|
|
id: "auth-recovery-oidc-logout",
|
|
name: "Auth Recovery OIDC Logout",
|
|
timeout: 50,
|
|
lane: "full",
|
|
description: "Auth recovery and OIDC logout suite",
|
|
vitestTarget: "test/auth-recovery-oidc-logout.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/auth-recovery-oidc-logout-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/email/**",
|
|
"server/src/modules/metadata/**",
|
|
"server/test/auth-recovery-oidc-logout.e2e-spec.ts",
|
|
"server/test/e2e/app-harness.ts",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/auth.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"book-dock-ingest-finalize": {
|
|
id: "book-dock-ingest-finalize",
|
|
name: "Book Dock Ingest Finalize",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Book Dock ingest and finalize suite",
|
|
vitestTarget: "test/book-dock-ingest-finalize.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/book-dock-ingest-finalize-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/book-dock/**",
|
|
"server/src/modules/upload/**",
|
|
"server/src/modules/metadata/**",
|
|
"server/test/book-dock-ingest-finalize.e2e-spec.ts",
|
|
"server/test/e2e/book-dock/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"metadata-write": {
|
|
id: "metadata-write",
|
|
name: "Metadata Write",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Metadata write operations suite",
|
|
vitestTarget: "test/metadata-write.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/metadata-write-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/file-write/**",
|
|
"server/src/modules/metadata/**",
|
|
"server/src/modules/app-settings/**",
|
|
"server/test/metadata-write.e2e-spec.ts",
|
|
"server/test/e2e/metadata-write/**",
|
|
"packages/types/src/file-write.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"metadata-cache": {
|
|
id: "metadata-cache",
|
|
name: "Metadata Cache",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Metadata provider cache repository, executor and admin API suite",
|
|
vitestTarget: "test/metadata-cache.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/metadata-cache-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/metadata-cache/**",
|
|
"server/src/common/provider-cache/**",
|
|
"server/src/modules/metadata-fetch/**",
|
|
"server/src/modules/authors/metadata/**",
|
|
"server/src/modules/app-info/**",
|
|
"server/test/metadata-cache.e2e-spec.ts",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"metadata-http-providers": {
|
|
id: "metadata-http-providers",
|
|
name: "External Metadata Providers",
|
|
timeout: 90,
|
|
lane: "full",
|
|
description: "External HTTP metadata providers: registration, search, refresh, ids, ratings and purge",
|
|
vitestTarget: "test/metadata-http-providers.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/metadata-http-providers-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/metadata-http-provider/**",
|
|
"server/src/modules/metadata-fetch/**",
|
|
"server/src/modules/metadata-preferences/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/book-dock/**",
|
|
"server/src/modules/book-metadata-fetch/**",
|
|
"server/test/metadata-http-providers.e2e-spec.ts",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"metadata-lock": {
|
|
id: "metadata-lock",
|
|
name: "Metadata Lock",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Metadata lock end-to-end suite",
|
|
vitestTarget: "test/metadata-lock.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/metadata-lock-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/book-metadata-lock/**",
|
|
"server/src/modules/book-metadata-fetch/**",
|
|
"server/src/modules/metadata-fetch/**",
|
|
"server/src/modules/metadata-preferences/**",
|
|
"server/src/modules/cover/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/scanner/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/app-settings/**",
|
|
"server/test/metadata-lock.e2e-spec.ts",
|
|
"server/test/e2e/metadata-lock/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"migration-booklore": {
|
|
id: "migration-booklore",
|
|
name: "Migration Booklore",
|
|
timeout: 70,
|
|
lane: "full",
|
|
description: "Booklore migration end-to-end suite",
|
|
vitestTarget: "test/migration-booklore.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/migration-booklore-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/migration/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/test/migration-booklore.e2e-spec.ts",
|
|
"server/test/e2e/migration-booklore/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"migration-audiobookshelf": {
|
|
id: "migration-audiobookshelf",
|
|
name: "Migration Audiobookshelf",
|
|
timeout: 90,
|
|
lane: "full",
|
|
description: "Audiobookshelf live API and real-backup migration end-to-end suite",
|
|
vitestTarget: "test/migration-audiobookshelf.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/migration-audiobookshelf-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
requiresDocker: true,
|
|
changedPaths: [
|
|
"server/src/modules/migration/**",
|
|
"server/test/migration-audiobookshelf.e2e-spec.ts",
|
|
"server/test/e2e/migration-audiobookshelf/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"migration-calibre-web-automated": {
|
|
id: "migration-calibre-web-automated",
|
|
name: "Migration Calibre-Web Automated",
|
|
timeout: 120,
|
|
lane: "full",
|
|
description: "Calibre-Web Automated stopped-snapshot migration end-to-end suite",
|
|
vitestTarget: "test/migration-calibre-web-automated.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/migration-calibre-web-automated-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
requiresDocker: true,
|
|
changedPaths: [
|
|
"server/src/modules/migration/**",
|
|
"server/test/migration-calibre-web-automated.e2e-spec.ts",
|
|
"server/test/e2e/migration-calibre-web-automated/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"authorization-matrix": {
|
|
id: "authorization-matrix",
|
|
name: "Authorization Matrix",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Authorization matrix suite",
|
|
vitestTarget: "test/authorization-matrix.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/authorization-matrix-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/test/authorization-matrix.e2e-spec.ts",
|
|
"server/test/e2e/slot-cover-artifacts.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"catalog-visibility": {
|
|
id: "catalog-visibility",
|
|
name: "Catalog Visibility",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Catalog metadata library and content-filter visibility suite",
|
|
vitestTarget: "test/catalog-visibility.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/catalog-visibility-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/catalog/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/common/utils/content-filter-sql.utils.ts",
|
|
"server/test/catalog-visibility.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"dashboard-random": {
|
|
id: "dashboard-random",
|
|
name: "Dashboard Random Scroller",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Dashboard random scroller repository integration suite",
|
|
vitestTarget: "test/dashboard-random.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/dashboard-random-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/dashboard/**",
|
|
"server/test/dashboard-random.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/dashboard.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"audiobook-chapter-revision": {
|
|
id: "audiobook-chapter-revision",
|
|
name: "Audiobook Chapter Revision",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Audiobook chapter edits keep released-client playback writes and locks working",
|
|
vitestTarget: "test/audiobook-chapter-revision.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/audiobook-chapter-revision-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/audiobook/**",
|
|
"server/src/modules/audiobook-chapters/**",
|
|
"server/src/modules/chapter-editor/**",
|
|
"server/src/modules/metadata/metadata.service.ts",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/book-metadata-lock/**",
|
|
"server/src/common/utils/audiobook-chapters.utils.ts",
|
|
"server/test/audiobook-chapter-revision.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/audiobook.ts",
|
|
"packages/types/src/metadata-lock.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"audiobook-chapter-write": {
|
|
id: "audiobook-chapter-write",
|
|
name: "Audiobook Chapter Write",
|
|
timeout: 120,
|
|
lane: "full",
|
|
description: "Edited audiobook chapters are written into real audio files and read back unchanged",
|
|
vitestTarget: "test/audiobook-chapter-write.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/audiobook-chapter-write-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/chapter-editor/**",
|
|
"server/src/modules/file-write/**",
|
|
"server/src/modules/metadata/extractors/audio-chapter-merge.ts",
|
|
"server/src/common/utils/audiobook-chapters.utils.ts",
|
|
"server/test/audiobook-chapter-write.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/audiobook.ts",
|
|
"packages/types/src/file-write.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"chapter-health": {
|
|
id: "chapter-health",
|
|
name: "Chapter Health",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Chapter health categories, library scoping, and the bulk Audible lookup queue and worker",
|
|
vitestTarget: "test/chapter-health.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/chapter-health-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/chapter-health/**",
|
|
"server/src/modules/chapter-editor/**",
|
|
"server/src/modules/audiobook-chapters/**",
|
|
"server/src/modules/book-metadata-lock/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/common/utils/audiobook-chapters.utils.ts",
|
|
"server/test/chapter-health.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/chapter-health.ts",
|
|
"packages/types/src/audiobook.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"dashboard-continue-listening": {
|
|
id: "dashboard-continue-listening",
|
|
name: "Dashboard Continue Listening",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Dashboard continue-listening completion regression suite",
|
|
vitestTarget: "test/dashboard-continue-listening.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/dashboard-continue-listening-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/dashboard/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/user-book-status/**",
|
|
"server/test/dashboard-continue-listening.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/dashboard.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"book-requests": {
|
|
id: "book-requests",
|
|
name: "Book Requests",
|
|
timeout: 90,
|
|
lane: "full",
|
|
description: "Book request lifecycle, dedupe, ownership, and plugin-route authorization suite",
|
|
vitestTarget: "test/book-requests.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/book-requests-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-request/**",
|
|
"server/src/modules/book-dock/**",
|
|
"server/src/modules/library/**",
|
|
"server/test/book-requests.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/book-request.ts",
|
|
"packages/types/src/book-request-automation.ts",
|
|
"packages/types/src/book-request-destination.ts",
|
|
"packages/types/src/indexer.ts",
|
|
"packages/types/src/download-client.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"author-books-collapse": {
|
|
id: "author-books-collapse",
|
|
name: "Author Books Collapse",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Author page series collapsing, and the row and book counts it reports",
|
|
vitestTarget: "test/author-books-collapse.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/author-books-collapse-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/authors/**",
|
|
"server/src/modules/book/book.repository.ts",
|
|
"server/src/modules/book/book-read.service.ts",
|
|
"server/test/author-books-collapse.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/author.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"achievement-hints": {
|
|
id: "achievement-hints",
|
|
name: "Achievement Hints",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Achievement how-to-get-it hints: real queries, library scoping, and per-user isolation",
|
|
vitestTarget: "test/achievement-hints.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/achievement-hints-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/achievement/**",
|
|
"server/test/achievement-hints.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/achievement.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"series-next-book": {
|
|
id: "series-next-book",
|
|
name: "Series Next Book",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Series next-readable-book resolution suite",
|
|
vitestTarget: "test/series-next-book.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/series-next-book-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/series/**",
|
|
"server/test/series-next-book.e2e-spec.ts",
|
|
"server/test/e2e/authorization-matrix/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/series.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"series-index-migration": {
|
|
id: "series-index-migration",
|
|
name: "Series Index Migration",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Legacy series index upgrade compatibility suite",
|
|
vitestTarget: "test/series-index-migration.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/series-index-migration-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/db/migrations/**",
|
|
"server/src/scripts/migrate.ts",
|
|
"server/src/scripts/series-index-migration-compatibility.ts",
|
|
"server/test/series-index-migration.e2e-spec.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"metadata-editor-access-migration": {
|
|
id: "metadata-editor-access-migration",
|
|
name: "Metadata Editor Access Migration",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Editor role backfill for accounts that held Edit metadata before library roles were enforced",
|
|
vitestTarget: "test/metadata-editor-access-migration.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/metadata-editor-access-migration-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/db/migrations/**",
|
|
"server/src/scripts/migrate.ts",
|
|
"server/test/metadata-editor-access-migration.e2e-spec.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"reading-attempts": {
|
|
id: "reading-attempts",
|
|
name: "Reading Attempts",
|
|
timeout: 120,
|
|
lane: "full",
|
|
description: "Reading attempt lifecycle, external read identity, and Hardcover read ownership suite",
|
|
vitestTarget: "test/reading-attempts.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/reading-attempts-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/user-book-status/**",
|
|
"server/src/modules/hardcover/**",
|
|
"server/src/modules/dashboard/**",
|
|
"server/test/reading-attempts.e2e-spec.ts",
|
|
"server/test/e2e/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/book.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"reading-history": {
|
|
id: "reading-history",
|
|
name: "Reading History",
|
|
timeout: 120,
|
|
lane: "full",
|
|
description: "Reading history ordering, rereads, ratings, deleted-book retention and ownership suite",
|
|
vitestTarget: "test/reading-history.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/reading-history-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/reading-history/**",
|
|
"server/src/modules/user-book-status/**",
|
|
"server/src/modules/dashboard/**",
|
|
"server/src/db/reading-attempt-retention.ts",
|
|
"server/src/db/book-file-hash-history.ts",
|
|
"server/test/reading-history.e2e-spec.ts",
|
|
"server/test/e2e/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
"packages/types/src/reading-history.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"book-api-contract": {
|
|
id: "book-api-contract",
|
|
name: "Book API Contract",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Book API contract suite",
|
|
vitestTarget: "test/book-api-contract.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/book-api-contract-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/collection/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/user/**",
|
|
"server/test/book-api-contract.e2e-spec.ts",
|
|
"server/test/e2e/slot-cover-artifacts.ts",
|
|
"server/test/e2e/book-api-contract/**",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"jump-buckets-invariant": {
|
|
id: "jump-buckets-invariant",
|
|
name: "Jump Buckets Invariant",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Asserts jump-bucket indexes match real listing offsets for every eligible sort, direction, and collapse mode",
|
|
vitestTarget: "test/jump-buckets-invariant.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/jump-buckets-invariant-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/db/book-author-sort-key.ts",
|
|
"server/test/jump-buckets-invariant.e2e-spec.ts",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"browse-facets-invariant": {
|
|
id: "browse-facets-invariant",
|
|
name: "Browse Facets Invariant",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Asserts library browse facet counts match the listing totals for the same filter, search, and format",
|
|
vitestTarget: "test/browse-facets-invariant.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/browse-facets-invariant-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/test/browse-facets-invariant.e2e-spec.ts",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"server-connection-identity": {
|
|
id: "server-connection-identity",
|
|
name: "Server Connection Identity",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Public installation identity and concurrent singleton persistence",
|
|
vitestTarget: "test/server-connection-identity.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/server-connection-identity-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/server-identity/**",
|
|
"server/src/modules/app-info/**",
|
|
"server/test/server-connection-identity.e2e-spec.ts",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"app-settings-oidc-contract": {
|
|
id: "app-settings-oidc-contract",
|
|
name: "App Settings OIDC Contract",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "App settings OIDC contract suite",
|
|
vitestTarget: "test/app-settings-oidc-contract.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/app-settings-oidc-contract-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/app-settings/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/metadata/**",
|
|
"server/test/app-settings-oidc-contract.e2e-spec.ts",
|
|
"server/test/e2e/app-settings/**",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"library-admin-workflows": {
|
|
id: "library-admin-workflows",
|
|
name: "Library Admin Workflows",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Library admin workflows suite",
|
|
vitestTarget: "test/library-admin-workflows.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/library-admin-workflows-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/role/**",
|
|
"server/test/library-admin-workflows.e2e-spec.ts",
|
|
"server/test/e2e/slot-cover-artifacts.ts",
|
|
"server/test/e2e/library/**",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"missing-resources": {
|
|
id: "missing-resources",
|
|
name: "Missing Resources",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Missing Resources cover sweep and cleanup suite",
|
|
vitestTarget: "test/missing-resources.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/missing-resources-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/maintenance/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/test/missing-resources.e2e-spec.ts",
|
|
"server/test/e2e/metadata-write/**",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"reader-format-delivery": {
|
|
id: "reader-format-delivery",
|
|
name: "Reader Format Delivery",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Reader format delivery suite",
|
|
vitestTarget: "test/reader-format-delivery.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/reader-format-delivery-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/reader-preferences/**",
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/bookmark/**",
|
|
"server/test/reader-format-delivery.e2e-spec.ts",
|
|
"server/test/e2e/reader-format-delivery/**",
|
|
"packages/types/src/reader-settings.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"opds-auth-catalog": {
|
|
id: "opds-auth-catalog",
|
|
name: "OPDS Auth Catalog",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "OPDS auth and catalog suite",
|
|
vitestTarget: "test/opds-auth-catalog.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/opds-auth-catalog-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/opds/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/collection/**",
|
|
"server/src/modules/lens/**",
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/app-settings/**",
|
|
"server/test/opds-auth-catalog.e2e-spec.ts",
|
|
"server/test/e2e/opds/**",
|
|
"server/test/e2e/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"email-lifecycle": {
|
|
id: "email-lifecycle",
|
|
name: "Email Lifecycle",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Email lifecycle suite",
|
|
vitestTarget: "test/email-lifecycle.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/email-lifecycle-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/email/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/modules/cover/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/scanner/**",
|
|
"server/src/modules/seed/**",
|
|
"server/test/email-lifecycle.e2e-spec.ts",
|
|
"server/test/e2e/email/**",
|
|
"server/test/e2e/**",
|
|
"client/src/features/email/**",
|
|
"client/src/router/index.ts",
|
|
"client/src/features/settings/SettingsHeader.vue",
|
|
"client/src/views/HomeView.vue",
|
|
"client/src/views/CollectionView.vue",
|
|
"client/src/views/LensView.vue",
|
|
"client/src/features/book/components/BookCoverCard.vue",
|
|
"client/src/features/book/components/BookListRow.vue",
|
|
...SHARED_TYPES_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"reader-state-isolation": {
|
|
id: "reader-state-isolation",
|
|
name: "Reader State Isolation",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Reader state isolation suite",
|
|
vitestTarget: "test/reader-state-isolation.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/reader-state-isolation-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/bookmark/**",
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/reader-preferences/**",
|
|
"server/src/modules/reading-session/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/scanner/**",
|
|
"server/src/modules/user-book-status/**",
|
|
"server/src/scripts/db-prepare-e2e.ts",
|
|
"server/test/reader-state-isolation.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
"packages/types/src/reader-settings.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-annotation-exchange": {
|
|
id: "koreader-annotation-exchange",
|
|
name: "KOReader Annotation Exchange",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader annotation exchange suite",
|
|
vitestTarget: "test/koreader-annotation-exchange.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-annotation-exchange-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/position-converter/**",
|
|
"server/test/koreader-annotation-exchange.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-bookmark-exchange": {
|
|
id: "koreader-bookmark-exchange",
|
|
name: "KOReader Bookmark Exchange",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader two-way bookmark (dogear) exchange suite",
|
|
vitestTarget: "test/koreader-bookmark-exchange.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-bookmark-exchange-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/bookmark/**",
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/position-converter/**",
|
|
"server/test/koreader-bookmark-exchange.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-bulk-manifest": {
|
|
id: "koreader-bulk-manifest",
|
|
name: "KOReader Bulk Manifest Scale",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader bulk manifest pagination and index support at 25,000 books",
|
|
vitestTarget: "test/koreader-bulk-manifest.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-bulk-manifest-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/opds/opds-book.service.ts",
|
|
"server/src/db/schema/books.ts",
|
|
"server/test/koreader-bulk-manifest.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-audio-only-catalog": {
|
|
id: "koreader-audio-only-catalog",
|
|
name: "KOReader Audiobook-Only Catalog",
|
|
timeout: 20,
|
|
lane: "full",
|
|
description: "KOReader catalog setting that hides books whose only content files are audio",
|
|
vitestTarget: "test/koreader-audio-only-catalog.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-audio-only-catalog-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/opds/**",
|
|
"server/src/modules/dashboard/dashboard.repository.ts",
|
|
"server/src/modules/dashboard/dashboard.service.ts",
|
|
"server/src/modules/smart-scope/smart-scope.service.ts",
|
|
"server/src/common/utils/audio-only-book-sql.utils.ts",
|
|
"server/test/koreader-audio-only-catalog.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-page-stats": {
|
|
id: "koreader-page-stats",
|
|
name: "KOReader Page Stats Derivation",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader incremental page-stat derivation suite",
|
|
vitestTarget: "test/koreader-page-stats.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-page-stats-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/src/common/utils/reading-daily-stats.utils.ts",
|
|
"server/test/koreader-page-stats.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-progress-reset": {
|
|
id: "koreader-progress-reset",
|
|
name: "KOReader Progress Reset Propagation",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader reset propagation: a cleared position survives a device replaying its old one",
|
|
vitestTarget: "test/koreader-progress-reset.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-progress-reset-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/book/book.repository.ts",
|
|
"server/src/modules/reading-state/**",
|
|
"server/src/db/schema/koreader.ts",
|
|
"server/test/koreader-progress-reset.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-progress-position": {
|
|
id: "koreader-progress-position",
|
|
name: "KOReader Progress Position Routing",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader progress position routing into cfi or pageNumber per book format",
|
|
vitestTarget: "test/koreader-progress-position.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-progress-position-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/book/book.service.ts",
|
|
"server/src/db/schema/reader.ts",
|
|
"server/test/koreader-progress-position.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-readaloud-progress": {
|
|
id: "koreader-readaloud-progress",
|
|
name: "KOReader Read-Along Sibling Progress",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "KOReader and web reader positions carried between an EPUB and its Storyteller read-along copy",
|
|
vitestTarget: "test/koreader-readaloud-progress.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-readaloud-progress-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/book/audiobook-ebook-progress-sync.service.ts",
|
|
"server/src/modules/book/book.repository.ts",
|
|
"server/src/modules/book/book.service.ts",
|
|
"server/src/modules/position-converter/**",
|
|
"server/src/modules/reader/epub/**",
|
|
"server/src/common/utils/primary-file-selection.utils.ts",
|
|
"server/test/koreader-readaloud-progress.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"read-aloud-jobs": {
|
|
id: "read-aloud-jobs",
|
|
name: "Read-Aloud Jobs",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description:
|
|
"Read-along generation lifecycle against a fake worker: publish, review and re-sync, replace in place, ownership, retry, cancel, resume",
|
|
vitestTarget: "test/read-aloud-jobs.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/read-aloud-jobs-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/read-aloud/**",
|
|
"server/src/modules/upload/generated-book-file.service.ts",
|
|
"server/src/modules/upload/upload.service.ts",
|
|
"server/src/db/schema/read-aloud.ts",
|
|
"server/test/read-aloud-jobs.e2e-spec.ts",
|
|
"server/test/e2e/read-aloud/**",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
"packages/types/src/read-aloud.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"koreader-file-naming": {
|
|
id: "koreader-file-naming",
|
|
name: "KOReader File Naming",
|
|
timeout: 30,
|
|
lane: "full",
|
|
description: "KOReader file naming persistence and authorization suite",
|
|
vitestTarget: "test/koreader-file-naming.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/koreader-file-naming-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/koreader/**",
|
|
"server/test/koreader-file-naming.e2e-spec.ts",
|
|
"packages/types/src/pattern-resolver.ts",
|
|
...SHARED_AUTH_TYPE_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"annotations-hub": {
|
|
id: "annotations-hub",
|
|
name: "Annotations Hub",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Annotations hub suite",
|
|
vitestTarget: "test/annotations-hub.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/annotations-hub-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/position-converter/**",
|
|
"server/test/annotations-hub.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"book-notebook": {
|
|
id: "book-notebook",
|
|
name: "Book Notebook",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Book journal, annotation stars and reading order, bookmark edits and colour names suite",
|
|
vitestTarget: "test/book-notebook.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/book-notebook-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-journal/**",
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/bookmark/**",
|
|
"server/src/modules/user-preferences/**",
|
|
"server/src/modules/app-info/**",
|
|
"server/test/book-notebook.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
...SHARED_TYPES_PATHS,
|
|
],
|
|
},
|
|
"notebook-hub": {
|
|
id: "notebook-hub",
|
|
name: "Notebook Hub",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Library-wide notebook: entries, overview, books, review decks, on this day and trash suite",
|
|
vitestTarget: "test/notebook-hub.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/notebook-hub-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/notebook/**",
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/book-journal/**",
|
|
"server/src/modules/bookmark/**",
|
|
"server/src/modules/user-book-note/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/library/**",
|
|
"server/src/common/utils/content-filter-sql.utils.ts",
|
|
"server/src/common/utils/accent-insensitive-search.utils.ts",
|
|
"server/test/notebook-hub.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
...SHARED_TYPES_PATHS,
|
|
],
|
|
},
|
|
"kobo-annotation-sync": {
|
|
id: "kobo-annotation-sync",
|
|
name: "Kobo Annotation Sync",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Kobo annotation three-way sync suite",
|
|
vitestTarget: "test/kobo-annotation-sync.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/kobo-annotation-sync-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/annotation/**",
|
|
"server/src/modules/kobo/**",
|
|
"server/src/modules/koreader/**",
|
|
"server/src/modules/position-converter/**",
|
|
"server/test/kobo-annotation-sync.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
"packages/types/src/kobo.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"kobo-multi-device-sync": {
|
|
id: "kobo-multi-device-sync",
|
|
name: "Kobo Multi-Device Sync",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Kobo device-owned library snapshot suite",
|
|
vitestTarget: "test/kobo-multi-device-sync.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/kobo-multi-device-sync-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/kobo/**",
|
|
"server/src/modules/book/**",
|
|
"server/src/modules/file-write/**",
|
|
"server/test/kobo-multi-device-sync.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
"packages/types/src/book.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"kobo-koreader-download": {
|
|
id: "kobo-koreader-download",
|
|
name: "Kobo KOReader Download Identity",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Kobo delivered hashes, KOReader matching, cache recovery and access isolation",
|
|
vitestTarget: "test/kobo-koreader-download.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/kobo-koreader-download-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/kobo/**",
|
|
"server/src/modules/koreader/**",
|
|
"server/src/common/utils/file-hash.utils.ts",
|
|
"server/test/kobo-koreader-download.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"kobo-reading-time-reconciliation": {
|
|
id: "kobo-reading-time-reconciliation",
|
|
name: "Kobo Reading Time Reconciliation",
|
|
timeout: 45,
|
|
lane: "full",
|
|
description: "Kobo counter-derived estimate and measured session reconciliation suite",
|
|
vitestTarget: "test/kobo-reading-time-reconciliation.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/kobo-reading-time-reconciliation-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/kobo/**",
|
|
"server/src/modules/reading-session/**",
|
|
"server/src/common/utils/reading-daily-stats.utils.ts",
|
|
"server/test/kobo-reading-time-reconciliation.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"kobo-cover-identity": {
|
|
id: "kobo-cover-identity",
|
|
name: "Kobo Cover Identity",
|
|
timeout: 60,
|
|
lane: "full",
|
|
description: "Kobo CoverImageId stability across metadata edits and cover changes",
|
|
vitestTarget: "test/kobo-cover-identity.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/kobo-cover-identity-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/kobo/**",
|
|
"server/src/modules/cover/**",
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/metadata/**",
|
|
"server/test/kobo-cover-identity.e2e-spec.ts",
|
|
"server/test/e2e/reader-state-isolation/**",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"users-admin-lifecycle": {
|
|
id: "users-admin-lifecycle",
|
|
name: "Users Admin Lifecycle",
|
|
timeout: 50,
|
|
lane: "full",
|
|
description: "Users admin lifecycle suite",
|
|
vitestTarget: "test/users-admin-lifecycle.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/users-admin-lifecycle-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/user/**",
|
|
"server/src/modules/auth/**",
|
|
"server/src/common/guards/**",
|
|
"server/src/common/decorators/**",
|
|
"server/src/common/types/**",
|
|
"server/test/users-admin-lifecycle.e2e-spec.ts",
|
|
"server/test/e2e/users-admin-lifecycle/**",
|
|
".github/workflows/e2e-runner.yml",
|
|
...SHARED_AUTH_TYPE_PATHS,
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"file-rename": {
|
|
id: "file-rename",
|
|
name: "File Rename",
|
|
timeout: 120,
|
|
lane: "full",
|
|
description: "Bulk file rename end-to-end suite covering all library/file structure permutations",
|
|
vitestTarget: "test/file-rename.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/file-rename-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-cover-store/**",
|
|
"server/src/modules/metadata/cover-slot-reconciler.service.ts",
|
|
"server/src/modules/library/**",
|
|
"server/src/modules/file-write/**",
|
|
"server/src/modules/scanner/**",
|
|
"server/src/modules/app-settings/**",
|
|
"server/test/file-rename.e2e-spec.ts",
|
|
"server/test/e2e/file-rename/**",
|
|
"packages/types/src/file-write.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
"book-move": {
|
|
id: "book-move",
|
|
name: "Book Move",
|
|
timeout: 120,
|
|
lane: "full",
|
|
description: "Cross-library book move suite covering preview classification, collision policies, and file relocation",
|
|
vitestTarget: "test/book-move.e2e-spec.ts",
|
|
junitOutput: `${TEST_RESULTS_DIR}/book-move-e2e-junit.xml`,
|
|
prepareDedicatedDatabase: true,
|
|
useDedicatedDatabase: true,
|
|
changedPaths: [
|
|
"server/src/modules/book-move/**",
|
|
"server/src/modules/scanner/**",
|
|
"server/src/modules/app-settings/**",
|
|
"server/test/book-move.e2e-spec.ts",
|
|
"server/test/e2e/metadata-write/**",
|
|
"packages/types/src/book-move.ts",
|
|
"packages/types/src/book-selection.ts",
|
|
...SHARED_DB_AND_HELPER_PATHS,
|
|
],
|
|
},
|
|
});
|
|
|
|
export function listE2ESuites() {
|
|
return Object.values(E2E_SUITES);
|
|
}
|
|
|
|
export function getE2ESuite(suiteId) {
|
|
return E2E_SUITES[suiteId] ?? null;
|
|
}
|