diff --git a/packages/@n8n/vitest-config/frontend.ts b/packages/@n8n/vitest-config/frontend.ts index 7a9bd9d2c1b..24d3bf95779 100644 --- a/packages/@n8n/vitest-config/frontend.ts +++ b/packages/@n8n/vitest-config/frontend.ts @@ -18,7 +18,15 @@ export const createVitestConfig = (options: InlineConfig = {}) => { // Scoped to `nodes/` because those icons never appear in component // snapshots (unlike the eagerly-imported `custom/` icons), and to // `test.alias` so it never leaks into production/dev builds. See svg-stub.ts. - alias: [{ find: /^.*\/nodes\/[^/]+\.svg(\?.*)?$/, replacement: svgStub }], + alias: [ + { find: /^.*\/nodes\/[^/]+\.svg(\?.*)?$/, replacement: svgStub }, + // Load `element-plus` from its single-file bundle. Its `es/` entry makes Node evaluate + // ~980 files in every test file (about 0.25 s each); the bundle has the same 432 exports. + // A bare replacement resolves from the importer, so a package without `element-plus` + // is not affected. `vue` stays external to the bundle, so there is one Vue instance. + // `patches/element-plus@2.4.3.patch` applies the same lockscreen guard to this bundle. + { find: /^element-plus$/, replacement: 'element-plus/dist/index.full.mjs' }, + ], silent: true, globals: true, // Restore `vi.spyOn` spies to their original implementation before each test, so diff --git a/packages/frontend/editor-ui/src/__tests__/setup.ts b/packages/frontend/editor-ui/src/__tests__/setup.ts index 1d5f0dc615c..bddebcdf9b1 100644 --- a/packages/frontend/editor-ui/src/__tests__/setup.ts +++ b/packages/frontend/editor-ui/src/__tests__/setup.ts @@ -3,7 +3,8 @@ import 'fake-indexeddb/auto'; import 'core-js/proposals/set-methods-v2'; import englishBaseText from '@n8n/i18n/locales/en.json'; import { loadLanguage, type LocaleMessages } from '@n8n/i18n'; -import { APP_MODALS_ELEMENT_ID } from '@/app/constants'; +// Not the `@/app/constants` barrel: it pulls the full `@n8n/api-types` graph into every test file. +import { APP_MODALS_ELEMENT_ID } from '@/app/constants/selectors'; // Global stub for Reka UI Popover components used by N8nPopover. // Unlike Element+ popover which always renders content regardless of visibility, diff --git a/packages/frontend/editor-ui/src/app/components/MainHeader/MainHeader.test.ts b/packages/frontend/editor-ui/src/app/components/MainHeader/MainHeader.test.ts index 8a6fb20511f..25884249937 100644 --- a/packages/frontend/editor-ui/src/app/components/MainHeader/MainHeader.test.ts +++ b/packages/frontend/editor-ui/src/app/components/MainHeader/MainHeader.test.ts @@ -14,7 +14,8 @@ import { createWorkflowDocumentId, } from '@/app/stores/workflowDocument.store'; -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: vi.fn(() => ({ workflow: { update: true, diff --git a/packages/frontend/editor-ui/src/app/composables/useWorkflowSaving.test.ts b/packages/frontend/editor-ui/src/app/composables/useWorkflowSaving.test.ts index 3aba966ac1e..4d222ef1b3d 100644 --- a/packages/frontend/editor-ui/src/app/composables/useWorkflowSaving.test.ts +++ b/packages/frontend/editor-ui/src/app/composables/useWorkflowSaving.test.ts @@ -67,7 +67,8 @@ vi.mock('@n8n/composables/useToast', () => ({ }), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: () => ({ workflow: { update: true }, }), diff --git a/packages/frontend/editor-ui/src/app/stores/workflows.store.test.ts b/packages/frontend/editor-ui/src/app/stores/workflows.store.test.ts index 6c4a72592e3..fd7e3a69b81 100644 --- a/packages/frontend/editor-ui/src/app/stores/workflows.store.test.ts +++ b/packages/frontend/editor-ui/src/app/stores/workflows.store.test.ts @@ -63,7 +63,8 @@ vi.mock('@/features/integrations/sourceControl.ee/sourceControl.store', () => ({ })), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: vi.fn((scopes: string[] = []) => ({ workflow: { update: scopes.includes('workflow:update'), diff --git a/packages/frontend/editor-ui/src/features/agents/__tests__/AgentModelSelector.spec.ts b/packages/frontend/editor-ui/src/features/agents/__tests__/AgentModelSelector.spec.ts index 47e7612fd23..d54759809b2 100644 --- a/packages/frontend/editor-ui/src/features/agents/__tests__/AgentModelSelector.spec.ts +++ b/packages/frontend/editor-ui/src/features/agents/__tests__/AgentModelSelector.spec.ts @@ -2,6 +2,7 @@ import { flushPromises, mount, type VueWrapper } from '@vue/test-utils'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { AI_GATEWAY_MANAGED_TAG } from '@n8n/api-types'; +import type * as permissions from '@n8n/permissions'; import type { AgentCredentialsByProvider, @@ -93,7 +94,8 @@ vi.mock('@n8n/i18n', () => ({ }), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: () => ({ credential: { create: canCreateCredentials.value } }), })); diff --git a/packages/frontend/editor-ui/src/features/agents/__tests__/AgentVectorStoresModal.test.ts b/packages/frontend/editor-ui/src/features/agents/__tests__/AgentVectorStoresModal.test.ts index 44177588503..6da07922f1b 100644 --- a/packages/frontend/editor-ui/src/features/agents/__tests__/AgentVectorStoresModal.test.ts +++ b/packages/frontend/editor-ui/src/features/agents/__tests__/AgentVectorStoresModal.test.ts @@ -27,7 +27,8 @@ vi.mock('@n8n/stores/useRootStore', () => ({ useRootStore: () => ({ restApiContext: {} }), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: () => ({ credential: { create: true } }), })); diff --git a/packages/frontend/editor-ui/src/features/ai/shared/components/ChannelSetupCard.test.ts b/packages/frontend/editor-ui/src/features/ai/shared/components/ChannelSetupCard.test.ts index 6ba37c91b86..114481b5b59 100644 --- a/packages/frontend/editor-ui/src/features/ai/shared/components/ChannelSetupCard.test.ts +++ b/packages/frontend/editor-ui/src/features/ai/shared/components/ChannelSetupCard.test.ts @@ -54,7 +54,8 @@ vi.mock('@n8n/stores/useRootStore', () => ({ useRootStore: () => ({ restApiContext: {} }), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: () => ({ credential: { create: true, read: true, update: true, delete: true, share: true, move: true }, }), diff --git a/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useExecutionCommands.test.ts b/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useExecutionCommands.test.ts index 896d4eb7e63..fbb19554825 100644 --- a/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useExecutionCommands.test.ts +++ b/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useExecutionCommands.test.ts @@ -62,7 +62,8 @@ vi.mock('@n8n/composables/useTelemetry', () => ({ }), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: vi.fn(() => ({ workflow: { update: true, diff --git a/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useNodeCommands.test.ts b/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useNodeCommands.test.ts index b90f7ed51c8..e0bdbb50df9 100644 --- a/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useNodeCommands.test.ts +++ b/packages/frontend/editor-ui/src/features/shared/commandBar/composables/useNodeCommands.test.ts @@ -48,7 +48,8 @@ vi.mock('@/features/shared/nodeCreator/composables/useActionsGeneration', () => }), })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: vi.fn(), })); diff --git a/packages/frontend/editor-ui/src/features/workflows/components/WorkflowShareModal.ee.test.ts b/packages/frontend/editor-ui/src/features/workflows/components/WorkflowShareModal.ee.test.ts index 84bd350f907..4dc26f8cdd6 100644 --- a/packages/frontend/editor-ui/src/features/workflows/components/WorkflowShareModal.ee.test.ts +++ b/packages/frontend/editor-ui/src/features/workflows/components/WorkflowShareModal.ee.test.ts @@ -67,7 +67,8 @@ vi.mock('@/app/composables/useWorkflowSaving', () => ({ const mockGetResourcePermissions = vi.fn(() => ({ workflow: { share: true }, })); -vi.mock('@n8n/permissions', () => ({ +vi.mock('@n8n/permissions', async (importOriginal) => ({ + ...(await importOriginal()), getResourcePermissions: () => mockGetResourcePermissions(), })); vi.mock('@n8n/utils/event-bus', () => ({ diff --git a/patches/element-plus@2.4.3.patch b/patches/element-plus@2.4.3.patch index 9a57e6b9953..2a3e7ca8e7f 100644 --- a/patches/element-plus@2.4.3.patch +++ b/patches/element-plus@2.4.3.patch @@ -1,3 +1,16 @@ +diff --git a/dist/index.full.mjs b/dist/index.full.mjs +index 18aa99b6f0473e765efdb8de3a65c7f1cf42b619..47041a2a81f1130f9679082a734d59840fa5f96b 100644 +--- a/dist/index.full.mjs ++++ b/dist/index.full.mjs +@@ -9274,6 +9274,8 @@ const useLockscreen = (trigger, options = {}) => { + let bodyWidth = "0"; + const cleanup = () => { + setTimeout(() => { ++ // Cherry-pick from https://github.com/element-plus/element-plus/pull/18445 ++ if (typeof document === "undefined") return; + removeClass(document == null ? void 0 : document.body, hiddenCls.value); + if (withoutHiddenClass && document) { + document.body.style.width = bodyWidth; diff --git a/es/hooks/use-lockscreen/index.mjs b/es/hooks/use-lockscreen/index.mjs --- a/es/hooks/use-lockscreen/index.mjs +++ b/es/hooks/use-lockscreen/index.mjs diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31894c1a45d..7efb32a6114 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1063,7 +1063,7 @@ patchedDependencies: assert@2.1.0: a73271b303dca8c10a0c9caf77d2083b52032b6a887227563bee3ce3dbf5e9d2 axios: 149e256a2a7b632497650b32816716ced972ab02a5ab00fbd8a5158a51722c49 bull@4.16.4: a4b6d56db16fe5870646929938466d6a5c668435fd1551bed6a93fffb597ba42 - element-plus@2.4.3: 9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c + element-plus@2.4.3: 95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff ics: 163587ad2fa9bc787ed09cd5e958eace08b4aa8aaca651869e9434ba674e158d imapflow@1.7.1: 9a2144a656c11ce1dbc8a0400e46e4fb575dc28be8b461e612cecf31be6f8025 lodash@4.18.1: 81ead1b07fc8efda87bd2724dbd876ab49f4a0aa03f96c3770060b2ea47d9e0b @@ -5397,7 +5397,7 @@ importers: version: 4.17.17 element-plus: specifier: catalog:frontend - version: 2.4.3(patch_hash=9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c)(vue@3.5.26(typescript@6.0.2)) + version: 2.4.3(patch_hash=95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff)(vue@3.5.26(typescript@6.0.2)) pinia: specifier: catalog:frontend version: 2.2.4(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2)) @@ -5490,7 +5490,7 @@ importers: version: 3.0.3 element-plus: specifier: catalog:frontend - version: 2.4.3(patch_hash=9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c)(vue@3.5.26(typescript@6.0.2)) + version: 2.4.3(patch_hash=95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff)(vue@3.5.26(typescript@6.0.2)) highlight.js: specifier: catalog:frontend version: 11.12.0 @@ -6086,7 +6086,7 @@ importers: version: link:../../../@n8n/utils element-plus: specifier: catalog:frontend - version: 2.4.3(patch_hash=9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c)(vue@3.5.26(typescript@6.0.2)) + version: 2.4.3(patch_hash=95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff)(vue@3.5.26(typescript@6.0.2)) pinia: specifier: catalog:frontend version: 2.2.4(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2)) @@ -6484,7 +6484,7 @@ importers: version: 3.0.3 element-plus: specifier: catalog:frontend - version: 2.4.3(patch_hash=9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c)(vue@3.5.26(typescript@6.0.2)) + version: 2.4.3(patch_hash=95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff)(vue@3.5.26(typescript@6.0.2)) eslint: specifier: 'catalog:' version: 9.29.0(jiti@2.6.1)(supports-color@8.1.1) @@ -6721,7 +6721,7 @@ importers: version: 3.0.3 element-plus: specifier: catalog:frontend - version: 2.4.3(patch_hash=9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c)(vue@3.5.26(typescript@6.0.2)) + version: 2.4.3(patch_hash=95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff)(vue@3.5.26(typescript@6.0.2)) lodash: specifier: 4.18.1 version: 4.18.1(patch_hash=81ead1b07fc8efda87bd2724dbd876ab49f4a0aa03f96c3770060b2ea47d9e0b) @@ -29326,7 +29326,7 @@ snapshots: mongodb: 6.21.0(@aws-sdk/credential-providers@3.808.0)(gcp-metadata@5.3.0(supports-color@8.1.1))(socks@2.8.9) mysql2: 3.23.1(@types/node@20.19.41) pdf-parse: 2.4.5 - pg: 8.21.0(pg-native@3.8.0) + pg: 8.21.0 playwright: 1.62.1 puppeteer: 24.41.0(bufferutil@4.0.9)(supports-color@8.1.1)(typescript@7.0.2)(utf-8-validate@5.0.10) redis: 4.6.14 @@ -36829,7 +36829,7 @@ snapshots: transitivePeerDependencies: - supports-color - element-plus@2.4.3(patch_hash=9547bca88969f416e6132b09a48e71a969dce25ee6669c7f1f78d51ce9b80e7c)(vue@3.5.26(typescript@6.0.2)): + element-plus@2.4.3(patch_hash=95b9793afc4529bc887bf7dac437131975e133feb7152dce68aa4b3c9b648aff)(vue@3.5.26(typescript@6.0.2)): dependencies: '@ctrl/tinycolor': 3.6.0 '@element-plus/icons-vue': 2.3.1(vue@3.5.26(typescript@6.0.2)) @@ -41798,10 +41798,15 @@ snapshots: libpq: 1.11.0 pg-types: 2.2.0 - pg-pool@3.14.0(pg@8.21.0): + pg-pool@3.14.0(pg@8.21.0(pg-native@3.8.0)): dependencies: pg: 8.21.0(pg-native@3.8.0) + pg-pool@3.14.0(pg@8.21.0): + dependencies: + pg: 8.21.0 + optional: true + pg-promise@11.9.1(pg-native@3.8.0): dependencies: assert-options: 0.8.1 @@ -41826,13 +41831,24 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.21.0(pg-native@3.8.0): + pg@8.21.0: dependencies: pg-connection-string: 2.14.0 pg-pool: 3.14.0(pg@8.21.0) pg-protocol: 1.15.0 pg-types: 2.2.0 pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.4.0 + optional: true + + pg@8.21.0(pg-native@3.8.0): + dependencies: + pg-connection-string: 2.14.0 + pg-pool: 3.14.0(pg@8.21.0(pg-native@3.8.0)) + pg-protocol: 1.15.0 + pg-types: 2.2.0 + pgpass: 1.0.5 optionalDependencies: pg-cloudflare: 1.4.0 pg-native: 3.8.0