Files
alighasami 3d5eaf9445
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
first commit
2026-03-17 16:22:57 +03:30

295 lines
12 KiB
TypeScript

import { test, expect } from '../../../fixtures/base';
test.describe('Folders - Operations', {
annotation: [
{ type: 'owner', description: 'Identity & Access' },
],
}, () => {
test.describe('Rename and delete folders', () => {
test('should rename folder from breadcrumb dropdown', async ({ n8n }) => {
await n8n.start.fromNewProject();
const folderName = await n8n.workflows.addFolder();
const folderCard = n8n.workflows.cards.getFolder(folderName);
await n8n.workflows.cards.openCardActions(folderCard);
await n8n.workflows.cards.getCardAction('open').click();
await n8n.breadcrumbs.renameCurrentBreadcrumb('Renamed');
await n8n.breadcrumbs.getHomeProjectBreadcrumb().click();
await expect(n8n.workflows.cards.getFolder('Renamed')).toBeVisible();
});
test('should rename folder from card dropdown', async ({ n8n }) => {
await n8n.start.fromNewProject();
const folderName = await n8n.workflows.addFolder();
const folderCard = n8n.workflows.cards.getFolder(folderName);
await n8n.workflows.cards.openCardActions(folderCard);
await n8n.workflows.cards.getCardAction('rename').click();
await n8n.workflows.fillFolderModal('Renamed', 'Rename');
await expect(n8n.workflows.cards.getFolder('Renamed')).toBeVisible();
});
test('should delete empty folder from card dropdown', async ({ n8n }) => {
await n8n.start.fromNewProject();
const folderName = await n8n.workflows.addFolder();
await n8n.workflows.cards.deleteFolder(folderName);
await expect(n8n.workflows.cards.getFolder(folderName)).toBeHidden();
});
test('should delete empty folder from breadcrumb dropdown', async ({ n8n }) => {
await n8n.start.fromNewProject();
const folderName = await n8n.workflows.addFolder();
await n8n.workflows.cards.openFolder(folderName);
await n8n.breadcrumbs.getFolderBreadcrumbsActionToggle().click();
await n8n.breadcrumbs.getActionToggleDropdown('delete').click();
await expect(n8n.workflows.cards.getFolder(folderName)).toBeHidden();
});
test('should warn before deleting non-empty folder from breadcrumb dropdown', async ({
n8n,
}) => {
const { id: projectId } = await n8n.api.projects.createProject();
const folder = await n8n.api.projects.createFolder(projectId);
await n8n.api.workflows.createInProject(projectId, {
folder: folder.id,
});
await n8n.navigate.toFolder(folder.id, projectId);
await n8n.breadcrumbs.getFolderBreadcrumbsActionToggle().click();
await n8n.breadcrumbs.getActionToggleDropdown('delete').click();
await expect(n8n.workflows.deleteFolderModal()).toBeVisible();
await expect(n8n.workflows.deleteModalConfirmButton()).toBeDisabled();
});
test('should warn before deleting non-empty folder from card dropdown', async ({ n8n }) => {
const { id: projectId } = await n8n.api.projects.createProject();
const folder = await n8n.api.projects.createFolder(projectId);
await n8n.api.workflows.createInProject(projectId, {
folder: folder.id,
});
await n8n.navigate.toProject(projectId);
const folderCard = n8n.workflows.cards.getFolder(folder.name);
await n8n.workflows.cards.openCardActions(folderCard);
await n8n.workflows.cards.getCardAction('delete').click();
await expect(n8n.workflows.deleteFolderModal()).toBeVisible();
await expect(n8n.workflows.deleteModalConfirmButton()).toBeDisabled();
});
test('should transfer contents when deleting non-empty folder - from card dropdown', async ({
n8n,
}) => {
const { id: projectId } = await n8n.api.projects.createProject();
const folderToDelete = await n8n.api.projects.createFolder(projectId);
await n8n.api.workflows.createInProject(projectId, {
folder: folderToDelete.id,
});
const destinationFolder = await n8n.api.projects.createFolder(projectId);
await n8n.navigate.toProject(projectId);
const folderCard = n8n.workflows.cards.getFolder(folderToDelete.name);
await n8n.workflows.cards.openCardActions(folderCard);
await n8n.workflows.cards.getCardAction('delete').click();
await n8n.workflows.deleteModalTransferRadioButton().click();
await n8n.workflows.transferFolderDropdown().click();
await n8n.workflows.transferFolderOption(destinationFolder.name).click();
await n8n.workflows.deleteModalConfirmButton().click();
await expect(
n8n.notifications.getNotificationByTitleOrContent('Folder deleted'),
).toBeVisible();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getWorkflows()).toBeVisible();
});
});
test.describe('Move folders and workflows', () => {
test('should move empty folder to another folder - from folder card action', async ({
n8n,
}) => {
const { id: projectId } = await n8n.api.projects.createProject();
const sourceFolder = await n8n.api.projects.createFolder(projectId);
const destinationFolder = await n8n.api.projects.createFolder(projectId);
await n8n.navigate.toProject(projectId);
const sourceFolderCard = n8n.workflows.cards.getFolder(sourceFolder.name);
await n8n.workflows.cards.openCardActions(sourceFolderCard);
await n8n.workflows.cards.getCardAction('move').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
await n8n.workflows.moveFolderOption(destinationFolder.name).click();
await n8n.workflows.moveFolderConfirmButton().click();
await expect(
n8n.notifications.getNotificationByTitleOrContent('Successfully moved folder'),
).toBeVisible();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getFolder(sourceFolder.name)).toBeVisible();
});
test('should move folder with contents to another folder - from folder card action', async ({
n8n,
}) => {
const { id: projectId } = await n8n.api.projects.createProject();
const sourceFolder = await n8n.api.projects.createFolder(projectId);
const destinationFolder = await n8n.api.projects.createFolder(projectId);
await n8n.api.workflows.createInProject(projectId, {
folder: sourceFolder.id,
});
await n8n.navigate.toProject(projectId);
const sourceFolderCard = n8n.workflows.cards.getFolder(sourceFolder.name);
await n8n.workflows.cards.openCardActions(sourceFolderCard);
await n8n.workflows.cards.getCardAction('move').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
await n8n.workflows.moveFolderOption(destinationFolder.name).click();
await n8n.workflows.moveFolderConfirmButton().click();
await expect(
n8n.notifications.getNotificationByTitleOrContent('Successfully moved folder'),
).toBeVisible();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getFolder(sourceFolder.name)).toBeVisible();
await n8n.workflows.cards.openFolder(sourceFolder.name);
await expect(n8n.workflows.cards.getWorkflows()).toBeVisible();
});
test('should move empty folder to another folder - from list breadcrumbs', async ({ n8n }) => {
const { id: projectId } = await n8n.api.projects.createProject();
const sourceFolder = await n8n.api.projects.createFolder(projectId);
const destinationFolder = await n8n.api.projects.createFolder(projectId);
await n8n.navigate.toFolder(sourceFolder.id, projectId);
await n8n.breadcrumbs.getFolderBreadcrumbsActionToggle().click();
await n8n.breadcrumbs.getActionToggleDropdown('move').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
await n8n.workflows.moveFolderOption(destinationFolder.name).click();
await n8n.workflows.moveFolderConfirmButton().click();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getFolder(sourceFolder.name)).toBeVisible();
});
test('should move folder with contents to another folder - from list dropdown', async ({
n8n,
}) => {
const { id: projectId } = await n8n.api.projects.createProject();
const sourceFolder = await n8n.api.projects.createFolder(projectId);
const destinationFolder = await n8n.api.projects.createFolder(projectId);
await n8n.api.workflows.createInProject(projectId, {
folder: sourceFolder.id,
});
await n8n.navigate.toFolder(sourceFolder.id, projectId);
await n8n.breadcrumbs.getFolderBreadcrumbsActionToggle().click();
await n8n.breadcrumbs.getActionToggleDropdown('move').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
await n8n.workflows.moveFolderOption(destinationFolder.name).click();
await n8n.workflows.moveFolderConfirmButton().click();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getFolder(sourceFolder.name)).toBeVisible();
await n8n.workflows.cards.openFolder(sourceFolder.name);
await expect(n8n.workflows.cards.getWorkflows()).toBeVisible();
});
test('should move folder to project root - from folder card action', async ({ n8n }) => {
const project = await n8n.api.projects.createProject();
const parentFolder = await n8n.api.projects.createFolder(project.id);
const childFolderName = 'Child Folder';
const childFolder = await n8n.api.projects.createFolder(
project.id,
childFolderName,
parentFolder.id,
);
await n8n.navigate.toFolder(parentFolder.id, project.id);
const childFolderCard = n8n.workflows.cards.getFolder(childFolder.name);
await n8n.workflows.cards.openCardActions(childFolderCard);
await n8n.workflows.cards.getCardAction('move').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
const rootOption = 'No folder (project root)';
await n8n.workflows.moveFolderOption(rootOption).click();
await n8n.workflows.moveFolderConfirmButton().click();
await expect(
n8n.notifications.getNotificationByTitleOrContent('Successfully moved folder'),
).toBeVisible();
await n8n.navigate.toProject(project.id);
await expect(n8n.workflows.cards.getFolder(childFolder.name)).toBeVisible();
});
test('should move workflow from project root to folder', async ({ n8n }) => {
const { id: projectId } = await n8n.api.projects.createProject();
const destinationFolder = await n8n.api.projects.createFolder(projectId);
await n8n.api.workflows.createInProject(projectId);
await n8n.navigate.toProject(projectId);
const workflowCard = n8n.workflows.cards.getWorkflows().first();
await n8n.workflows.cards.openCardActions(workflowCard);
await n8n.workflows.cards.getCardAction('moveToFolder').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
await n8n.workflows.moveFolderOption(destinationFolder.name).click();
await n8n.workflows.moveFolderConfirmButton().click();
await expect(
n8n.notifications.getNotificationByTitleOrContent('Successfully moved workflow'),
).toBeVisible();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getWorkflows()).toBeVisible();
});
test('should move workflow to another folder', async ({ n8n }) => {
const { id: projectId } = await n8n.api.projects.createProject();
const sourceFolder = await n8n.api.projects.createFolder(projectId);
const destinationFolder = await n8n.api.projects.createFolder(projectId);
const { name: workflowName } = await n8n.api.workflows.createInProject(projectId, {
folder: sourceFolder.id,
});
await n8n.navigate.toFolder(sourceFolder.id, projectId);
const workflowCard = n8n.workflows.cards.getWorkflow(workflowName);
await n8n.workflows.cards.openCardActions(workflowCard);
await n8n.workflows.cards.getCardAction('moveToFolder').click();
await expect(n8n.workflows.moveFolderModal()).toBeVisible();
await n8n.workflows.moveFolderDropdown().click();
await n8n.workflows.moveFolderOption(destinationFolder.name).click();
await n8n.workflows.moveFolderConfirmButton().click();
await expect(
n8n.notifications.getNotificationByTitleOrContent('Successfully moved workflow'),
).toBeVisible();
await n8n.navigate.toFolder(destinationFolder.id, projectId);
await expect(n8n.workflows.cards.getWorkflow(workflowName)).toBeVisible();
await n8n.navigate.toFolder(sourceFolder.id, projectId);
await expect(n8n.workflows.cards.getWorkflow(workflowName)).toBeHidden();
});
});
});