diff --git a/packages/frontend/editor-ui/src/__tests__/setup.ts b/packages/frontend/editor-ui/src/__tests__/setup.ts index b168727df1..56db5ae67f 100644 --- a/packages/frontend/editor-ui/src/__tests__/setup.ts +++ b/packages/frontend/editor-ui/src/__tests__/setup.ts @@ -2,12 +2,39 @@ import '@testing-library/jest-dom'; import 'fake-indexeddb/auto'; import { configure } from '@testing-library/vue'; import 'core-js/proposals/set-methods-v2'; +import { APP_MODALS_ELEMENT_ID } from '@/constants'; // Avoid tests failing because of difference between local and GitHub actions timezone process.env.TZ = 'UTC'; configure({ testIdAttribute: 'data-test-id' }); +// Create DOM containers for Element Plus components before each test +beforeEach(() => { + // Create app-grid container for toasts + const appGrid = document.createElement('div'); + appGrid.id = 'app-grid'; + document.body.appendChild(appGrid); + + // Create app-modals container for modals + const appModals = document.createElement('div'); + appModals.id = APP_MODALS_ELEMENT_ID; + document.body.appendChild(appModals); +}); + +afterEach(() => { + // Clean up only our specific DOM containers to avoid interfering with Vue's unmounting + const appGrid = document.getElementById('app-grid'); + const appModals = document.getElementById(APP_MODALS_ELEMENT_ID); + + if (appGrid) { + appGrid.remove(); + } + if (appModals) { + appModals.remove(); + } +}); + window.ResizeObserver = window.ResizeObserver || vi.fn().mockImplementation(() => ({ diff --git a/packages/frontend/editor-ui/src/__tests__/utils.ts b/packages/frontend/editor-ui/src/__tests__/utils.ts index 9a756874ae..b726165db6 100644 --- a/packages/frontend/editor-ui/src/__tests__/utils.ts +++ b/packages/frontend/editor-ui/src/__tests__/utils.ts @@ -3,7 +3,6 @@ import userEvent from '@testing-library/user-event'; import type { ISettingsState } from '@/Interface'; import { UserManagementAuthenticationMethod } from '@/Interface'; import { defaultSettings } from './defaults'; -import { APP_MODALS_ELEMENT_ID } from '@/constants'; import type { Mock } from 'vitest'; import type { Store, StoreDefinition } from 'pinia'; import type { ComputedRef } from 'vue'; @@ -95,23 +94,6 @@ export const getSelectedDropdownValue = async (items: NodeListOf) => { return selectedItem?.querySelector('p')?.textContent?.trim(); }; -/** - * Create a container for teleported modals - * - * More info: https://test-utils.vuejs.org/guide/advanced/teleport#Mounting-the-Component - * @returns {HTMLElement} appModals - */ -export const createAppModals = () => { - const appModals = document.createElement('div'); - appModals.id = APP_MODALS_ELEMENT_ID; - document.body.appendChild(appModals); - return appModals; -}; - -export const cleanupAppModals = () => { - document.body.innerHTML = ''; -}; - /** * Typescript helper for mocking pinia store actions return value * diff --git a/packages/frontend/editor-ui/src/components/ApiKeyCreateOrEditModal.test.ts b/packages/frontend/editor-ui/src/components/ApiKeyCreateOrEditModal.test.ts index 3088cf2b54..2ff859ea30 100644 --- a/packages/frontend/editor-ui/src/components/ApiKeyCreateOrEditModal.test.ts +++ b/packages/frontend/editor-ui/src/components/ApiKeyCreateOrEditModal.test.ts @@ -2,9 +2,9 @@ import { createComponentRenderer } from '@/__tests__/render'; import { createTestingPinia } from '@pinia/testing'; import { API_KEY_CREATE_OR_EDIT_MODAL_KEY } from '@/constants'; import { STORES } from '@n8n/stores'; -import { cleanupAppModals, createAppModals, mockedStore, retry } from '@/__tests__/utils'; +import { mockedStore, retry } from '@/__tests__/utils'; import ApiKeyEditModal from './ApiKeyCreateOrEditModal.vue'; -import { fireEvent } from '@testing-library/vue'; +import userEvent from '@testing-library/user-event'; import { useApiKeysStore } from '@/stores/apiKeys.store'; import { DateTime } from 'luxon'; @@ -40,13 +40,11 @@ const settingsStore = mockedStore(useSettingsStore); describe('ApiKeyCreateOrEditModal', () => { beforeEach(() => { - createAppModals(); apiKeysStore.availableScopes = ['user:create', 'user:list']; settingsStore.settings.enterprise = createMockEnterpriseSettings({ apiKeyScopes: false }); }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); @@ -68,9 +66,9 @@ describe('ApiKeyCreateOrEditModal', () => { expect(inputLabel).toBeInTheDocument(); expect(saveButton).toBeInTheDocument(); - await fireEvent.update(inputLabel, 'new label'); + await userEvent.type(inputLabel, 'new label'); - await fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(getByText('API Key Created')).toBeInTheDocument(); @@ -114,23 +112,23 @@ describe('ApiKeyCreateOrEditModal', () => { expect(saveButton).toBeInTheDocument(); expect(expirationSelect).toBeInTheDocument(); - await fireEvent.update(inputLabel, 'new label'); + await userEvent.type(inputLabel, 'new label'); - await fireEvent.click(expirationSelect); + await userEvent.click(expirationSelect); const customOption = getByText('Custom'); expect(customOption).toBeInTheDocument(); - await fireEvent.click(customOption); + await userEvent.click(customOption); const customExpirationInput = getByPlaceholderText('yyyy-mm-dd'); expect(customExpirationInput).toBeInTheDocument(); - await fireEvent.input(customExpirationInput, '2029-12-31'); + await userEvent.type(customExpirationInput, '2029-12-31'); - await fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(getByText('***456')).toBeInTheDocument(); @@ -167,17 +165,17 @@ describe('ApiKeyCreateOrEditModal', () => { expect(saveButton).toBeInTheDocument(); expect(expirationSelect).toBeInTheDocument(); - await fireEvent.update(inputLabel, 'new label'); + await userEvent.type(inputLabel, 'new label'); - await fireEvent.click(expirationSelect); + await userEvent.click(expirationSelect); const noExpirationOption = getByText('No Expiration'); expect(noExpirationOption).toBeInTheDocument(); - await fireEvent.click(noExpirationOption); + await userEvent.click(noExpirationOption); - await fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(getByText('API Key Created')).toBeInTheDocument(); @@ -215,22 +213,22 @@ describe('ApiKeyCreateOrEditModal', () => { expect(scopesSelect).toBeInTheDocument(); expect(saveButton).toBeInTheDocument(); - await fireEvent.update(inputLabel, 'new label'); + await userEvent.type(inputLabel, 'new label'); - await fireEvent.click(scopesSelect); + await userEvent.click(scopesSelect); const userCreateScope = getByText('user:create'); expect(userCreateScope).toBeInTheDocument(); - await fireEvent.click(userCreateScope); + await userEvent.click(userCreateScope); const [userCreateTag, userCreateSelectOption] = getAllByText('user:create'); expect(userCreateTag).toBeInTheDocument(); expect(userCreateSelectOption).toBeInTheDocument(); - await fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(getByText('API Key Created')).toBeInTheDocument(); @@ -250,7 +248,7 @@ describe('ApiKeyCreateOrEditModal', () => { apiKeysStore.createApiKey.mockResolvedValue(testApiKey); - const { getByText, getByPlaceholderText, getByTestId, getAllByText } = renderComponent({ + const { getByText, getByPlaceholderText, getByTestId, getByRole } = renderComponent({ props: { mode: 'new', }, @@ -271,23 +269,23 @@ describe('ApiKeyCreateOrEditModal', () => { expect(scopesSelect).toBeInTheDocument(); expect(saveButton).toBeInTheDocument(); - await fireEvent.update(inputLabel, 'new label'); + await userEvent.type(inputLabel, 'new label'); - await fireEvent.click(scopesSelect); + await userEvent.click(scopesSelect); - const userCreateScope = getAllByText('user:create'); + // Use separate semantic queries instead of destructuring + // The text is nested inside .el-select__tags-text which is inside .el-tag + const userCreateTag = getByText('user:create', { selector: '.el-select__tags-text' }); + const userCreateSelectOption = getByRole('option', { name: 'user:create' }); - const [userCreateTag, userCreateSelectOption] = userCreateScope; expect(userCreateTag).toBeInTheDocument(); expect(userCreateSelectOption).toBeInTheDocument(); - expect(userCreateSelectOption).toBeInTheDocument(); + expect(userCreateSelectOption).toHaveClass('is-disabled'); - expect(userCreateSelectOption.parentNode).toHaveClass('is-disabled'); + await userEvent.click(userCreateSelectOption); - await fireEvent.click(userCreateSelectOption); - - await fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(getByText('API Key Created')).toBeInTheDocument(); @@ -328,13 +326,14 @@ describe('ApiKeyCreateOrEditModal', () => { expect((labelInput as unknown as HTMLInputElement).value).toBe('new api key'); - await fireEvent.update(labelInput, 'updated api key'); + await userEvent.clear(labelInput); + await userEvent.type(labelInput, 'updated api key'); const saveButton = getByText('Save'); expect(saveButton).toBeInTheDocument(); - await fireEvent.click(saveButton); + await userEvent.click(saveButton); expect(apiKeysStore.updateApiKey).toHaveBeenCalledWith('123', { label: 'updated api key', diff --git a/packages/frontend/editor-ui/src/components/ApiKeyScopes.vue b/packages/frontend/editor-ui/src/components/ApiKeyScopes.vue index 533d21912e..970d378ed5 100644 --- a/packages/frontend/editor-ui/src/components/ApiKeyScopes.vue +++ b/packages/frontend/editor-ui/src/components/ApiKeyScopes.vue @@ -31,6 +31,7 @@ const { goToUpgrade } = usePageRedirectionHelper(); const checkAll = ref(false); const indeterminate = ref(false); +const popperContainer = ref(null); const groupedScopes = computed(() => { const groups = {}; diff --git a/packages/frontend/editor-ui/src/components/AssignmentCollection/Assignment.test.ts b/packages/frontend/editor-ui/src/components/AssignmentCollection/Assignment.test.ts index 7011323942..8acd18a1a7 100644 --- a/packages/frontend/editor-ui/src/components/AssignmentCollection/Assignment.test.ts +++ b/packages/frontend/editor-ui/src/components/AssignmentCollection/Assignment.test.ts @@ -7,7 +7,6 @@ import Assignment from './Assignment.vue'; import { defaultSettings } from '@/__tests__/defaults'; import { STORES } from '@n8n/stores'; import merge from 'lodash/merge'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; import * as useResolvedExpression from '@/composables/useResolvedExpression'; const DEFAULT_SETUP = { @@ -28,12 +27,7 @@ const DEFAULT_SETUP = { const renderComponent = createComponentRenderer(Assignment, DEFAULT_SETUP); describe('Assignment.vue', () => { - beforeEach(() => { - createAppModals(); - }); - afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/AssignmentCollection/AssignmentCollection.test.ts b/packages/frontend/editor-ui/src/components/AssignmentCollection/AssignmentCollection.test.ts index 226045d6b7..f181243769 100644 --- a/packages/frontend/editor-ui/src/components/AssignmentCollection/AssignmentCollection.test.ts +++ b/packages/frontend/editor-ui/src/components/AssignmentCollection/AssignmentCollection.test.ts @@ -6,7 +6,7 @@ import { fireEvent, within } from '@testing-library/vue'; import * as workflowHelpers from '@/composables/useWorkflowHelpers'; import AssignmentCollection from './AssignmentCollection.vue'; import { STORES } from '@n8n/stores'; -import { cleanupAppModals, createAppModals, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; +import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; const DEFAULT_SETUP = { pinia: createTestingPinia({ @@ -64,13 +64,8 @@ async function dropAssignment({ } describe('AssignmentCollection.vue', () => { - beforeEach(() => { - createAppModals(); - }); - afterEach(() => { vi.clearAllMocks(); - cleanupAppModals(); }); it('renders empty state properly', async () => { diff --git a/packages/frontend/editor-ui/src/components/ChangePasswordModal.test.ts b/packages/frontend/editor-ui/src/components/ChangePasswordModal.test.ts index b7d11ced5f..7248774c81 100644 --- a/packages/frontend/editor-ui/src/components/ChangePasswordModal.test.ts +++ b/packages/frontend/editor-ui/src/components/ChangePasswordModal.test.ts @@ -2,7 +2,6 @@ import { createTestingPinia } from '@pinia/testing'; import ChangePasswordModal from '@/components/ChangePasswordModal.vue'; import type { createPinia } from 'pinia'; import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; const renderComponent = createComponentRenderer(ChangePasswordModal); @@ -10,14 +9,9 @@ describe('ChangePasswordModal', () => { let pinia: ReturnType; beforeEach(() => { - createAppModals(); pinia = createTestingPinia({}); }); - afterEach(() => { - cleanupAppModals(); - }); - it('should render correctly', () => { const wrapper = renderComponent({ pinia }); diff --git a/packages/frontend/editor-ui/src/components/ChatEmbedModal.test.ts b/packages/frontend/editor-ui/src/components/ChatEmbedModal.test.ts index 5af65c7d05..359bb8ad1a 100644 --- a/packages/frontend/editor-ui/src/components/ChatEmbedModal.test.ts +++ b/packages/frontend/editor-ui/src/components/ChatEmbedModal.test.ts @@ -4,7 +4,6 @@ import { CHAT_EMBED_MODAL_KEY, WEBHOOK_NODE_TYPE } from '@/constants'; import { STORES } from '@n8n/stores'; import { createComponentRenderer } from '@/__tests__/render'; import { waitFor } from '@testing-library/vue'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; const renderComponent = createComponentRenderer(ChatEmbedModal, { props: { @@ -28,13 +27,6 @@ const renderComponent = createComponentRenderer(ChatEmbedModal, { }); describe('ChatEmbedModal', () => { - beforeEach(() => { - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); - }); it('should render correctly', async () => { const { getByTestId } = renderComponent(); diff --git a/packages/frontend/editor-ui/src/components/CommunityPackageInstallModal.test.ts b/packages/frontend/editor-ui/src/components/CommunityPackageInstallModal.test.ts index d3cc8ec2a5..18e9aa32c5 100644 --- a/packages/frontend/editor-ui/src/components/CommunityPackageInstallModal.test.ts +++ b/packages/frontend/editor-ui/src/components/CommunityPackageInstallModal.test.ts @@ -4,7 +4,7 @@ import { createTestingPinia } from '@pinia/testing'; import { COMMUNITY_PACKAGE_INSTALL_MODAL_KEY } from '@/constants'; import { STORES } from '@n8n/stores'; import userEvent from '@testing-library/user-event'; -import { cleanupAppModals, createAppModals, retry } from '@/__tests__/utils'; +import { retry } from '@/__tests__/utils'; const renderComponent = createComponentRenderer(CommunityPackageInstallModal, { props: { @@ -34,13 +34,6 @@ const renderComponent = createComponentRenderer(CommunityPackageInstallModal, { }); describe('CommunityPackageInstallModal', () => { - beforeEach(() => { - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); - }); it('should disable install button until user agrees', async () => { const { getByTestId } = renderComponent(); diff --git a/packages/frontend/editor-ui/src/components/CommunityPackageManageConfirmModal.test.ts b/packages/frontend/editor-ui/src/components/CommunityPackageManageConfirmModal.test.ts index ae695a4919..163e7e4327 100644 --- a/packages/frontend/editor-ui/src/components/CommunityPackageManageConfirmModal.test.ts +++ b/packages/frontend/editor-ui/src/components/CommunityPackageManageConfirmModal.test.ts @@ -1,7 +1,7 @@ import { useNodeTypesStore } from '@/stores/nodeTypes.store'; import { createComponentRenderer } from '@/__tests__/render'; import CommunityPackageManageConfirmModal from './CommunityPackageManageConfirmModal.vue'; -import { cleanupAppModals, createAppModals, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; +import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; import { useSettingsStore } from '@/stores/settings.store'; import { defaultSettings } from '@/__tests__/defaults'; import { mockNodeTypeDescription } from '@/__tests__/mocks'; @@ -65,15 +65,9 @@ describe('CommunityPackageManageConfirmModal', () => { let nodeTypesStore: ReturnType; beforeEach(() => { - createAppModals(); - nodeTypesStore = useNodeTypesStore(); }); - afterEach(() => { - cleanupAppModals(); - }); - it('should call nodeTypesStore methods and update latestVerifiedVersion on mount', async () => { nodeTypesStore.loadNodeTypesIfNotLoaded = vi.fn().mockResolvedValue(undefined); nodeTypesStore.getCommunityNodeAttributes = vi.fn().mockResolvedValue({ npmVersion: '2.0.0' }); diff --git a/packages/frontend/editor-ui/src/components/CredentialEdit/__tests__/CredentialEdit.test.ts b/packages/frontend/editor-ui/src/components/CredentialEdit/__tests__/CredentialEdit.test.ts index 4b68d78f08..451ab466d9 100644 --- a/packages/frontend/editor-ui/src/components/CredentialEdit/__tests__/CredentialEdit.test.ts +++ b/packages/frontend/editor-ui/src/components/CredentialEdit/__tests__/CredentialEdit.test.ts @@ -3,7 +3,7 @@ import CredentialEdit from '@/components/CredentialEdit/CredentialEdit.vue'; import { createTestingPinia } from '@pinia/testing'; import { CREDENTIAL_EDIT_MODAL_KEY } from '@/constants'; import { STORES } from '@n8n/stores'; -import { cleanupAppModals, createAppModals, retry, mockedStore } from '@/__tests__/utils'; +import { retry, mockedStore } from '@/__tests__/utils'; import { useCredentialsStore } from '@/stores/credentials.store'; import type { ICredentialsResponse } from '@/Interface'; import { within } from '@testing-library/vue'; @@ -212,12 +212,7 @@ const renderComponent = createComponentRenderer(CredentialEdit, { }), }); describe('CredentialEdit', () => { - beforeEach(() => { - createAppModals(); - }); - afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/DynamicModalLoader.test.ts b/packages/frontend/editor-ui/src/components/DynamicModalLoader.test.ts index 37fa85dbae..2881247669 100644 --- a/packages/frontend/editor-ui/src/components/DynamicModalLoader.test.ts +++ b/packages/frontend/editor-ui/src/components/DynamicModalLoader.test.ts @@ -5,7 +5,6 @@ import DynamicModalLoader from '@/components/DynamicModalLoader.vue'; import * as modalRegistry from '@/moduleInitializer/modalRegistry'; import type { ModalDefinition } from '@/moduleInitializer/module.types'; import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; // Mock the modalRegistry module vi.mock('@/moduleInitializer/modalRegistry', () => ({ @@ -54,14 +53,9 @@ describe('DynamicModalLoader', () => { const mockAsyncModalComponent = vi.fn(async () => await Promise.resolve(mockModalComponent)); beforeEach(() => { - createAppModals(); vi.clearAllMocks(); }); - afterEach(() => { - cleanupAppModals(); - }); - it('should render empty div when no modals are registered', () => { mockModalRegistry.getAll.mockReturnValue(new Map()); mockModalRegistry.subscribe.mockReturnValue(vi.fn()); diff --git a/packages/frontend/editor-ui/src/components/ExpressionEditModal.test.ts b/packages/frontend/editor-ui/src/components/ExpressionEditModal.test.ts index b310e460be..4ab86d8b2e 100644 --- a/packages/frontend/editor-ui/src/components/ExpressionEditModal.test.ts +++ b/packages/frontend/editor-ui/src/components/ExpressionEditModal.test.ts @@ -1,5 +1,4 @@ import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; import ExpressionEditModal from '@/components/ExpressionEditModal.vue'; import { createTestingPinia } from '@pinia/testing'; import { waitFor, within } from '@testing-library/vue'; @@ -29,14 +28,12 @@ describe('ExpressionEditModal', () => { let pinia: Pinia; beforeEach(() => { - createAppModals(); pinia = createTestingPinia({ stubActions: false }); setActivePinia(pinia); useSettingsStore().setSettings(defaultSettings); }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/FilterConditions/FilterConditions.test.ts b/packages/frontend/editor-ui/src/components/FilterConditions/FilterConditions.test.ts index 1e7ae800b1..67fec90555 100644 --- a/packages/frontend/editor-ui/src/components/FilterConditions/FilterConditions.test.ts +++ b/packages/frontend/editor-ui/src/components/FilterConditions/FilterConditions.test.ts @@ -1,5 +1,5 @@ import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; +import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; import FilterConditions from '@/components/FilterConditions/FilterConditions.vue'; import { STORES } from '@n8n/stores'; import { useNDVStore } from '@/stores/ndv.store'; @@ -36,13 +36,8 @@ const DEFAULT_SETUP = { const renderComponent = createComponentRenderer(FilterConditions, DEFAULT_SETUP); describe('FilterConditions.vue', () => { - beforeEach(() => { - createAppModals(); - }); - afterEach(() => { vi.clearAllMocks(); - cleanupAppModals(); }); it('renders default state properly', async () => { diff --git a/packages/frontend/editor-ui/src/components/FixedCollectionParameter.test.ts b/packages/frontend/editor-ui/src/components/FixedCollectionParameter.test.ts index 9937535018..97cf5d40ec 100644 --- a/packages/frontend/editor-ui/src/components/FixedCollectionParameter.test.ts +++ b/packages/frontend/editor-ui/src/components/FixedCollectionParameter.test.ts @@ -1,5 +1,5 @@ import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; +import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; import FixedCollectionParameter, { type Props } from '@/components/FixedCollectionParameter.vue'; import { STORES } from '@n8n/stores'; import { createTestingPinia } from '@pinia/testing'; @@ -57,14 +57,6 @@ describe('FixedCollectionParameter.vue', () => { }; const renderComponent = createComponentRenderer(FixedCollectionParameter, { props }); - beforeEach(() => { - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); - }); - it('renders the component', () => { const { getByTestId } = renderComponent(); expect(getByTestId('fixed-collection-rules')).toBeInTheDocument(); diff --git a/packages/frontend/editor-ui/src/components/Folders/MoveToFolderModal.test.ts b/packages/frontend/editor-ui/src/components/Folders/MoveToFolderModal.test.ts index 556fae82be..7c20e2c98f 100644 --- a/packages/frontend/editor-ui/src/components/Folders/MoveToFolderModal.test.ts +++ b/packages/frontend/editor-ui/src/components/Folders/MoveToFolderModal.test.ts @@ -5,8 +5,6 @@ import { faker } from '@faker-js/faker'; import { createComponentRenderer } from '@/__tests__/render'; import { createProjectListItem, createProjectSharingData } from '@/__tests__/data/projects'; import { - cleanupAppModals, - createAppModals, getDropdownItems, getSelectedDropdownValue, mockedStore, @@ -140,7 +138,6 @@ const mockEventBus = { describe('MoveToFolderModal', () => { beforeEach(() => { - createAppModals(); createTestingPinia(); uiStore = mockedStore(useUIStore); uiStore.modalsById = { @@ -183,7 +180,6 @@ describe('MoveToFolderModal', () => { }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/ImportCurlModal.test.ts b/packages/frontend/editor-ui/src/components/ImportCurlModal.test.ts index ce2beab6ea..f8cc216235 100644 --- a/packages/frontend/editor-ui/src/components/ImportCurlModal.test.ts +++ b/packages/frontend/editor-ui/src/components/ImportCurlModal.test.ts @@ -2,7 +2,7 @@ import { createComponentRenderer } from '@/__tests__/render'; import ImportCurlModal from './ImportCurlModal.vue'; import { createTestingPinia } from '@pinia/testing'; import { IMPORT_CURL_MODAL_KEY } from '@/constants'; -import { cleanupAppModals, createAppModals, mockedStore } from '@/__tests__/utils'; +import { mockedStore } from '@/__tests__/utils'; import { nextTick } from 'vue'; import { useUIStore } from '@/stores/ui.store'; import { useNDVStore } from '@/stores/ndv.store'; @@ -43,11 +43,6 @@ const testNode = { describe('ImportCurlModal', () => { beforeEach(() => { vi.clearAllMocks(); - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); }); it('should show empty input when no curl command exists for active node', async () => { diff --git a/packages/frontend/editor-ui/src/components/NodeDetailsView.test.ts b/packages/frontend/editor-ui/src/components/NodeDetailsView.test.ts index 24cac4d2f5..bcdee2ddad 100644 --- a/packages/frontend/editor-ui/src/components/NodeDetailsView.test.ts +++ b/packages/frontend/editor-ui/src/components/NodeDetailsView.test.ts @@ -17,7 +17,6 @@ import { defaultNodeDescriptions, mockNodes, } from '@/__tests__/mocks'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; vi.mock('vue-router', () => { return { @@ -68,12 +67,7 @@ describe('NodeDetailsView', () => { server = setupServer(); }); - beforeEach(() => { - createAppModals(); - }); - afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/NodeDetailsViewV2.test.ts b/packages/frontend/editor-ui/src/components/NodeDetailsViewV2.test.ts index c9c555108f..e9e061de80 100644 --- a/packages/frontend/editor-ui/src/components/NodeDetailsViewV2.test.ts +++ b/packages/frontend/editor-ui/src/components/NodeDetailsViewV2.test.ts @@ -17,7 +17,6 @@ import { defaultNodeDescriptions, mockNodes, } from '@/__tests__/mocks'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; vi.mock('vue-router', () => { return { @@ -74,12 +73,7 @@ describe('NodeDetailsViewV2', () => { server = setupServer(); }); - beforeEach(() => { - createAppModals(); - }); - afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.test.ts b/packages/frontend/editor-ui/src/components/ParameterInput.test.ts index 322b0b56ff..5e8e243afd 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInput.test.ts +++ b/packages/frontend/editor-ui/src/components/ParameterInput.test.ts @@ -8,7 +8,7 @@ import { waitFor, within } from '@testing-library/vue'; import userEvent from '@testing-library/user-event'; import type { useNodeTypesStore } from '@/stores/nodeTypes.store'; import { useSettingsStore } from '@/stores/settings.store'; -import { cleanupAppModals, createAppModals, mockedStore } from '@/__tests__/utils'; +import { mockedStore } from '@/__tests__/utils'; import { createEventBus } from '@n8n/utils/event-bus'; import { createMockEnterpriseSettings } from '@/__tests__/mocks'; import { useWorkflowsStore } from '@/stores/workflows.store'; @@ -51,7 +51,6 @@ beforeEach(() => { mockNdvState = getNdvStateMock(); mockNodeTypesState = getNodeTypesStateMock(); mockCompletionResult = {}; - createAppModals(); }); vi.mock('@/stores/ndv.store', () => { @@ -117,12 +116,10 @@ describe('ParameterInput.vue', () => { allNodeTypes: [], getNodeType: vi.fn().mockReturnValue(null), }; - createAppModals(); settingsStore.settings.enterprise = createMockEnterpriseSettings(); }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/ParameterInputFull.test.ts b/packages/frontend/editor-ui/src/components/ParameterInputFull.test.ts index 5a735b8d23..92760e9308 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInputFull.test.ts +++ b/packages/frontend/editor-ui/src/components/ParameterInputFull.test.ts @@ -3,7 +3,6 @@ import type { useNDVStore } from '@/stores/ndv.store'; import { createTestingPinia } from '@pinia/testing'; import type { useNodeTypesStore } from '@/stores/nodeTypes.store'; import type { useSettingsStore } from '@/stores/settings.store'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; import ParameterInputFull from './ParameterInputFull.vue'; import { FROM_AI_AUTO_GENERATED_MARKER } from 'n8n-workflow'; import { fireEvent } from '@testing-library/vue'; @@ -44,7 +43,6 @@ beforeEach(() => { } as never, isEnterpriseFeatureEnabled: { externalSecrets: false } as never, }; - createAppModals(); }); vi.mock('@/stores/ndv.store', () => { @@ -81,11 +79,6 @@ const renderComponent = createComponentRenderer(ParameterInputFull, { describe('ParameterInputFull.vue', () => { beforeEach(() => { vi.clearAllMocks(); - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); }); it('should render basic parameter', async () => { diff --git a/packages/frontend/editor-ui/src/components/ParameterInputOverrides/ParameterOverrideSelectableList.test.ts b/packages/frontend/editor-ui/src/components/ParameterInputOverrides/ParameterOverrideSelectableList.test.ts index d1ba575136..2261a9d5fa 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInputOverrides/ParameterOverrideSelectableList.test.ts +++ b/packages/frontend/editor-ui/src/components/ParameterInputOverrides/ParameterOverrideSelectableList.test.ts @@ -3,7 +3,6 @@ import { createComponentRenderer } from '@/__tests__/render'; import ParameterOverrideSelectableList from './ParameterOverrideSelectableList.vue'; import { createTestingPinia } from '@pinia/testing'; import { ref } from 'vue'; -import { createAppModals } from '@/__tests__/utils'; import { STORES } from '@n8n/stores'; import { waitFor } from '@testing-library/vue'; @@ -18,10 +17,6 @@ vi.mock('vue-router', () => { }; }); -beforeEach(() => { - createAppModals(); -}); - const renderComponent = createComponentRenderer(ParameterOverrideSelectableList, { pinia: createTestingPinia({ initialState: { diff --git a/packages/frontend/editor-ui/src/components/ParameterInputWrapper.test.ts b/packages/frontend/editor-ui/src/components/ParameterInputWrapper.test.ts index 6f1e5c0269..393542a803 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInputWrapper.test.ts +++ b/packages/frontend/editor-ui/src/components/ParameterInputWrapper.test.ts @@ -2,7 +2,7 @@ import { renderComponent } from '@/__tests__/render'; import { createTestingPinia } from '@pinia/testing'; import ParameterInputWrapper from './ParameterInputWrapper.vue'; import { STORES } from '@n8n/stores'; -import { cleanupAppModals, createAppModals, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; +import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; import { waitFor } from '@testing-library/vue'; vi.mock('@/composables/useWorkflowHelpers', () => { @@ -10,14 +10,6 @@ vi.mock('@/composables/useWorkflowHelpers', () => { }); describe('ParameterInputWrapper.vue', () => { - beforeEach(() => { - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); - }); - test('should resolve expression', async () => { const { getByTestId } = renderComponent(ParameterInputWrapper, { pinia: createTestingPinia({ diff --git a/packages/frontend/editor-ui/src/components/ResourceMapper.test.ts b/packages/frontend/editor-ui/src/components/ResourceMapper.test.ts index f8beff377e..5baf660bb2 100644 --- a/packages/frontend/editor-ui/src/components/ResourceMapper.test.ts +++ b/packages/frontend/editor-ui/src/components/ResourceMapper.test.ts @@ -5,7 +5,7 @@ import { } from './__tests__/utils/ResourceMapper.utils'; import { useNodeTypesStore } from '@/stores/nodeTypes.store'; import type { MockedStore } from '@/__tests__/utils'; -import { cleanupAppModals, createAppModals, mockedStore, waitAllPromises } from '@/__tests__/utils'; +import { mockedStore, waitAllPromises } from '@/__tests__/utils'; import ResourceMapper from '@/components/ResourceMapper/ResourceMapper.vue'; import userEvent from '@testing-library/user-event'; import { createComponentRenderer } from '@/__tests__/render'; @@ -28,14 +28,12 @@ describe('ResourceMapper.vue', () => { }); beforeEach(() => { - createAppModals(); projectsStore = mockedStore(useProjectsStore); projectsStore.currentProjectId = 'aProjectId'; }); afterEach(() => { vi.clearAllMocks(); - cleanupAppModals(); }); it('renders default configuration properly', async () => { diff --git a/packages/frontend/editor-ui/src/components/RunDataJsonActions.test.ts b/packages/frontend/editor-ui/src/components/RunDataJsonActions.test.ts index 9397f570e9..3cf4cdf20c 100644 --- a/packages/frontend/editor-ui/src/components/RunDataJsonActions.test.ts +++ b/packages/frontend/editor-ui/src/components/RunDataJsonActions.test.ts @@ -129,7 +129,6 @@ describe('RunDataJsonActions', () => { beforeEach(cleanup); beforeAll(() => { - document.body.innerHTML = '
'; server = setupServer(); }); diff --git a/packages/frontend/editor-ui/src/components/WhatsNewModal.test.ts b/packages/frontend/editor-ui/src/components/WhatsNewModal.test.ts index 032f47d893..fc953bfe24 100644 --- a/packages/frontend/editor-ui/src/components/WhatsNewModal.test.ts +++ b/packages/frontend/editor-ui/src/components/WhatsNewModal.test.ts @@ -2,12 +2,7 @@ import userEvent from '@testing-library/user-event'; import { createTestingPinia } from '@pinia/testing'; import { waitFor, screen } from '@testing-library/vue'; import { createComponentRenderer } from '@/__tests__/render'; -import { - cleanupAppModals, - createAppModals, - mockedStore, - type MockedStore, -} from '@/__tests__/utils'; +import { mockedStore, type MockedStore } from '@/__tests__/utils'; import { useUIStore } from '@/stores/ui.store'; import { WHATS_NEW_MODAL_KEY, VERSIONS_MODAL_KEY } from '@/constants'; import { useVersionsStore } from '@/stores/versions.store'; @@ -63,7 +58,6 @@ const currentVersion: Version = { describe('WhatsNewModal', () => { beforeEach(() => { - createAppModals(); createTestingPinia(); uiStore = mockedStore(useUIStore); uiStore.modalsById = { @@ -132,7 +126,6 @@ describe('WhatsNewModal', () => { }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/WorkflowSelectorParameterInput/WorkflowSelectorParameterInput.test.ts b/packages/frontend/editor-ui/src/components/WorkflowSelectorParameterInput/WorkflowSelectorParameterInput.test.ts index b520558600..56cdf71578 100644 --- a/packages/frontend/editor-ui/src/components/WorkflowSelectorParameterInput/WorkflowSelectorParameterInput.test.ts +++ b/packages/frontend/editor-ui/src/components/WorkflowSelectorParameterInput/WorkflowSelectorParameterInput.test.ts @@ -9,7 +9,7 @@ import WorkflowSelectorParameterInput, { type Props, } from '@/components/WorkflowSelectorParameterInput/WorkflowSelectorParameterInput.vue'; import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals, mockedStore } from '@/__tests__/utils'; +import { mockedStore } from '@/__tests__/utils'; import { useProjectsStore } from '@/stores/projects.store'; import { useWorkflowsStore } from '@/stores/workflows.store'; @@ -56,7 +56,6 @@ const workflowsStore = mockedStore(useWorkflowsStore); describe('WorkflowSelectorParameterInput', () => { beforeEach(() => { - createAppModals(); // Mock store methods to prevent unhandled errors workflowsStore.fetchWorkflowsPage.mockResolvedValue([]); workflowsStore.totalWorkflowCount = 0; @@ -71,7 +70,6 @@ describe('WorkflowSelectorParameterInput', () => { }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); }); diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.test.ts b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.test.ts index 9be53baad0..77180b9839 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.test.ts +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalNodeDetailsDrawer.test.ts @@ -1,6 +1,5 @@ import { createTestNode } from '@/__tests__/mocks'; import { createComponentRenderer } from '@/__tests__/render'; -import { cleanupAppModals, createAppModals } from '@/__tests__/utils'; import { SET_NODE_TYPE } from '@/constants'; import { useNDVStore } from '@/stores/ndv.store'; import { useNodeTypesStore } from '@/stores/nodeTypes.store'; @@ -51,11 +50,6 @@ describe('ExperimentalNodeDetailsDrawer', () => { }, ]); ndvStore = useNDVStore(); - createAppModals(); - }); - - afterEach(() => { - cleanupAppModals(); }); it('should show updated parameter after closing NDV', async () => { diff --git a/packages/frontend/editor-ui/src/composables/useToast.test.ts b/packages/frontend/editor-ui/src/composables/useToast.test.ts index 1abba8eb8b..f12f5038b0 100644 --- a/packages/frontend/editor-ui/src/composables/useToast.test.ts +++ b/packages/frontend/editor-ui/src/composables/useToast.test.ts @@ -13,7 +13,6 @@ describe('useToast', () => { let toast: ReturnType; beforeEach(() => { - document.body.innerHTML = '
'; createTestingPinia(); toast = useToast(); diff --git a/packages/frontend/editor-ui/src/plugins/codemirror/completions/completions.test.ts b/packages/frontend/editor-ui/src/plugins/codemirror/completions/completions.test.ts index 466a960dec..16e3568690 100644 --- a/packages/frontend/editor-ui/src/plugins/codemirror/completions/completions.test.ts +++ b/packages/frontend/editor-ui/src/plugins/codemirror/completions/completions.test.ts @@ -357,8 +357,6 @@ describe('Resolution-based completions', () => { describe('secrets', () => { const { $input } = mockProxy; - beforeEach(() => {}); - test('should return completions for: {{ $secrets.| }}', () => { const provider = 'infisical'; const secrets = ['SECRET']; diff --git a/packages/frontend/editor-ui/src/views/Evaluations.ee/tests/EvaluationsView.test.ts b/packages/frontend/editor-ui/src/views/Evaluations.ee/tests/EvaluationsView.test.ts index 0f9a7b3d2b..44c922c025 100644 --- a/packages/frontend/editor-ui/src/views/Evaluations.ee/tests/EvaluationsView.test.ts +++ b/packages/frontend/editor-ui/src/views/Evaluations.ee/tests/EvaluationsView.test.ts @@ -3,7 +3,7 @@ import { createTestingPinia } from '@pinia/testing'; import { createComponentRenderer } from '@/__tests__/render'; import EvaluationsView from '@/views/Evaluations.ee/EvaluationsView.vue'; -import { cleanupAppModals, createAppModals, mockedStore } from '@/__tests__/utils'; +import { mockedStore } from '@/__tests__/utils'; import { useEvaluationStore } from '@/stores/evaluation.store.ee'; import userEvent from '@testing-library/user-event'; import type { TestRunRecord } from '@/api/evaluation.ee'; @@ -49,12 +49,10 @@ describe('EvaluationsView', () => { beforeEach(() => { createTestingPinia(); - createAppModals(); }); afterEach(() => { vi.clearAllMocks(); - cleanupAppModals(); }); describe('Test Runs functionality', () => { diff --git a/packages/frontend/editor-ui/src/views/SettingsUsersView.test.ts b/packages/frontend/editor-ui/src/views/SettingsUsersView.test.ts index 8c463fff70..fec75c863a 100644 --- a/packages/frontend/editor-ui/src/views/SettingsUsersView.test.ts +++ b/packages/frontend/editor-ui/src/views/SettingsUsersView.test.ts @@ -13,12 +13,7 @@ import { import SettingsUsersView from '@/views/SettingsUsersView.vue'; import { createComponentRenderer } from '@/__tests__/render'; import { useEmitters } from '@/__tests__/utils'; -import { - cleanupAppModals, - createAppModals, - mockedStore, - type MockedStore, -} from '@/__tests__/utils'; +import { mockedStore, type MockedStore } from '@/__tests__/utils'; import { useUsersStore } from '@/stores/users.store'; import { useUIStore } from '@/stores/ui.store'; import { useSettingsStore } from '@/stores/settings.store'; @@ -112,7 +107,6 @@ let ssoStore: MockedStore; describe('SettingsUsersView', () => { beforeEach(() => { - createAppModals(); renderComponent = createComponentRenderer(SettingsUsersView, { pinia: createTestingPinia(), }); @@ -151,7 +145,6 @@ describe('SettingsUsersView', () => { }); afterEach(() => { - cleanupAppModals(); vi.clearAllMocks(); });