diff --git a/cypress/composables/folders.ts b/cypress/composables/folders.ts
index 496e1602e9..41e94f9611 100644
--- a/cypress/composables/folders.ts
+++ b/cypress/composables/folders.ts
@@ -76,7 +76,11 @@ export function getVisibleListBreadcrumbs() {
}
export function getCurrentBreadcrumb() {
- return getListBreadcrumbs().findChildByTestId('breadcrumbs-item-current');
+ return getListBreadcrumbs().findChildByTestId('breadcrumbs-item-current').find('input');
+}
+
+export function getCurrentBreadcrumbText() {
+ return getCurrentBreadcrumb().invoke('val');
}
export function getMainBreadcrumbsEllipsis() {
@@ -117,6 +121,11 @@ export function getListActionsToggle() {
return cy.getByTestId('folder-breadcrumbs-actions');
}
+export function getCanvasBreadcrumbs() {
+ cy.getByTestId('canvas-breadcrumbs').should('exist');
+ return cy.getByTestId('canvas-breadcrumbs').findChildByTestId('folder-breadcrumbs');
+}
+
export function getListActionItem(name: string) {
return cy
.getByTestId('folder-breadcrumbs-actions')
@@ -127,6 +136,10 @@ export function getListActionItem(name: string) {
});
}
+export function getInlineEditInput() {
+ return cy.getByTestId('inline-edit-input');
+}
+
export function getFolderCardActionToggle(folderName: string) {
return getFolderCard(folderName).find('[data-test-id="folder-card-actions"]');
}
@@ -303,7 +316,9 @@ export function renameFolderFromListActions(folderName: string, newName: string)
getFolderCard(folderName).click();
getListActionsToggle().click();
getListActionItem('rename').click();
- renameFolder(newName);
+ getInlineEditInput().should('be.visible');
+ getInlineEditInput().type(newName, { delay: 50 });
+ successToast().should('exist');
}
export function renameFolderFromCardActions(folderName: string, newName: string) {
@@ -372,12 +387,9 @@ export function deleteAndTransferFolderContentsFromCardDropdown(
export function deleteAndTransferFolderContentsFromListDropdown(destinationName: string) {
getListActionsToggle().click();
getListActionItem('delete').click();
- getCurrentBreadcrumb()
- .find('span')
- .invoke('text')
- .then((currentFolderName) => {
- deleteFolderAndMoveContents(currentFolderName, destinationName);
- });
+ getCurrentBreadcrumbText().then((currentFolderName) => {
+ deleteFolderAndMoveContents(String(currentFolderName), destinationName);
+ });
}
export function createNewProject(projectName: string, options: { openAfterCreate?: boolean } = {}) {
diff --git a/cypress/e2e/49-folders.cy.ts b/cypress/e2e/49-folders.cy.ts
index 00ebc00259..061ddcb7dc 100644
--- a/cypress/e2e/49-folders.cy.ts
+++ b/cypress/e2e/49-folders.cy.ts
@@ -19,7 +19,8 @@ import {
duplicateWorkflowFromCardActions,
duplicateWorkflowFromWorkflowPage,
getAddResourceDropdown,
- getCurrentBreadcrumb,
+ getCanvasBreadcrumbs,
+ getCurrentBreadcrumbText,
getFolderCard,
getFolderCardActionItem,
getFolderCardActionToggle,
@@ -75,7 +76,7 @@ describe('Folders', () => {
getFolderCards().should('have.length.greaterThan', 0);
// Clicking on the success toast should navigate to the folder
successToast().find('a').click();
- getCurrentBreadcrumb().should('contain.text', 'My Folder');
+ getCurrentBreadcrumbText().should('equal', 'My Folder');
// 2. In a folder
createFolderFromListHeaderButton('My Folder 2');
getFolderCard('My Folder 2').should('exist');
@@ -116,7 +117,7 @@ describe('Folders', () => {
getFolderCards().should('have.length.greaterThan', 0);
// Clicking on the success toast should navigate to the folder
successToast().contains('My Folder 2').find('a').contains('Open folder').click();
- getCurrentBreadcrumb().should('contain.text', 'My Folder 2');
+ getCurrentBreadcrumbText().should('equal', 'My Folder 2');
});
it('should create folder from the list header dropdown', () => {
@@ -137,7 +138,7 @@ describe('Folders', () => {
successToast().should('exist');
// Should be automatically navigated to the new folder
getFolderCard('Child Folder').should('exist');
- getCurrentBreadcrumb().should('contain.text', 'Created from card dropdown');
+ getCurrentBreadcrumbText().should('equal', 'Created from card dropdown');
});
it('should navigate folders using breadcrumbs and dropdown menu', () => {
@@ -146,15 +147,15 @@ describe('Folders', () => {
// Open folder using menu item
getFolderCardActionToggle('Navigate Test').click();
getFolderCardActionItem('Navigate Test', 'open').click();
- getCurrentBreadcrumb().should('contain.text', 'Navigate Test');
+ getCurrentBreadcrumbText().should('equal', 'Navigate Test');
// Create new child folder and navigate to it
createFolderFromListHeaderButton('Child Folder');
getFolderCard('Child Folder').should('exist');
getFolderCard('Child Folder').click();
- getCurrentBreadcrumb().should('contain.text', 'Child Folder');
+ getCurrentBreadcrumbText().should('equal', 'Child Folder');
// Navigate back to parent folder using breadcrumbs
getVisibleListBreadcrumbs().contains('Navigate Test').click();
- getCurrentBreadcrumb().should('contain.text', 'Navigate Test');
+ getCurrentBreadcrumbText().should('equal', 'Navigate Test');
// Go back to home project using breadcrumbs
getHomeProjectBreadcrumb().click();
getListBreadcrumbs().should('not.exist');
@@ -168,14 +169,14 @@ describe('Folders', () => {
// One level deep:
// - Breadcrumbs should only show home project and current folder
getHomeProjectBreadcrumb().should('exist');
- getCurrentBreadcrumb().should('contain.text', 'Multi-level Test');
+ getCurrentBreadcrumbText().should('equal', 'Multi-level Test');
getFolderCard('Child Folder').should('exist');
createFolderInsideFolder('Child Folder 2', 'Child Folder');
// Two levels deep:
// - Breadcrumbs should also show parent folder, without hidden ellipsis
getHomeProjectBreadcrumb().should('exist');
- getCurrentBreadcrumb().should('contain.text', 'Child Folder');
+ getCurrentBreadcrumbText().should('equal', 'Child Folder');
getVisibleListBreadcrumbs().should('have.length', 1);
getMainBreadcrumbsEllipsis().should('not.exist');
@@ -202,7 +203,7 @@ describe('Folders', () => {
cy.reload();
// Main list breadcrumbs should show home project, parent, grandparent, with one hidden element
getHomeProjectBreadcrumb().should('exist');
- getCurrentBreadcrumb().should('contain.text', 'Child Folder 2');
+ getCurrentBreadcrumbText().should('equal', 'Child Folder 2');
getVisibleListBreadcrumbs().should('have.length', 1);
getVisibleListBreadcrumbs().first().should('contain.text', 'Child Folder');
getMainBreadcrumbsEllipsis().should('exist');
@@ -290,6 +291,24 @@ describe('Folders', () => {
getFolderCard('Workflows go here').click();
getWorkflowCard('Created from list breadcrumbs').should('exist');
});
+
+ it('should show new workflow breadcrumbs correctly', () => {
+ goToPersonalProject();
+ createFolderFromProjectHeader('Workflow breadcrumbs test');
+ getFolderCard('Workflow breadcrumbs test').should('exist').click();
+ getFolderEmptyState().find('button').contains('Create Workflow').click();
+ // Should show breadcrumbs before and after saving new workflow
+ getCanvasBreadcrumbs().should('exist');
+ getCanvasBreadcrumbs().findChildByTestId('home-project').should('contain.text', 'Personal');
+ getCanvasBreadcrumbs().find('li[data-test-id="breadcrumbs-item"]').should('have.length', 1);
+ // Save workflow and reload
+ cy.getByTestId('workflow-save-button').click();
+ cy.reload();
+ // Should still show the same breadcrumbs
+ getCanvasBreadcrumbs().should('exist');
+ getCanvasBreadcrumbs().findChildByTestId('home-project').should('contain.text', 'Personal');
+ getCanvasBreadcrumbs().find('li[data-test-id="breadcrumbs-item"]').should('have.length', 1);
+ });
});
describe('Rename and delete folders', () => {
@@ -298,7 +317,7 @@ describe('Folders', () => {
createFolderFromProjectHeader('Rename Me');
getFolderCard('Rename Me').should('exist');
renameFolderFromListActions('Rename Me', 'Renamed');
- getCurrentBreadcrumb().should('contain.text', 'Renamed');
+ getCurrentBreadcrumbText().should('equal', 'Renamed');
});
it('should rename folder from card dropdown', () => {
@@ -416,7 +435,7 @@ describe('Folders', () => {
createFolderFromProjectHeader('Destination 5');
moveFolderFromListActions('Move me too - I am empty', 'Destination 5');
// Since we moved the current folder, we should be in the destination folder
- getCurrentBreadcrumb().should('contain.text', 'Destination 5');
+ getCurrentBreadcrumbText().should('equal', 'Destination 5');
});
it('should move folder with contents to another folder - from list dropdown', () => {
@@ -432,7 +451,7 @@ describe('Folders', () => {
// Move the folder
moveFolderFromListActions('Move me - I have family 2', 'Destination 6');
// Since we moved the current folder, we should be in the destination folder
- getCurrentBreadcrumb().should('contain.text', 'Destination 6');
+ getCurrentBreadcrumbText().should('equal', 'Destination 6');
// Moved folder should be there
getFolderCard('Move me - I have family 2').should('exist').click();
// After navigating to the moved folder, both the workflow and the folder should be there
@@ -456,7 +475,7 @@ describe('Folders', () => {
getFolderCard('Move me to root').click();
getHomeProjectBreadcrumb().should('contain.text', 'Personal');
getListBreadcrumbs().findChildByTestId('breadcrumbs-item').should('not.exist');
- getCurrentBreadcrumb().should('contain.text', 'Move me to root');
+ getCurrentBreadcrumbText().should('equal', 'Move me to root');
});
it('should move workflow from project root to folder', () => {
diff --git a/packages/frontend/@n8n/design-system/src/components/N8nBreadcrumbs/Breadcrumbs.vue b/packages/frontend/@n8n/design-system/src/components/N8nBreadcrumbs/Breadcrumbs.vue
index 32dac9db47..f5d3b2e600 100644
--- a/packages/frontend/@n8n/design-system/src/components/N8nBreadcrumbs/Breadcrumbs.vue
+++ b/packages/frontend/@n8n/design-system/src/components/N8nBreadcrumbs/Breadcrumbs.vue
@@ -235,17 +235,15 @@ const handleTooltipClose = () => {
:class="{
[$style.item]: true,
[$style.current]: props.highlightLastItem && index === items.length - 1,
- [$style.dragging]: props.dragActive && index !== items.length - 1,
+ [$style.dragging]: props.dragActive,
}"
:title="item.label"
- :data-test-id="
- index === items.length - 1 ? 'breadcrumbs-item-current' : 'breadcrumbs-item'
- "
:data-resourceid="item.id"
+ data-test-id="breadcrumbs-item"
data-target="folder-breadcrumb-item"
@click.prevent="emitItemSelected(item.id)"
@mouseenter="emitItemHover(item.id)"
- @mouseup="index !== items.length - 1 ? onItemMouseUp(item) : {}"
+ @mouseup="onItemMouseUp(item)"
>