mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix: fix workflows and credentials e2e tests
This commit is contained in:
parent
197efef03b
commit
971fb3949a
|
@ -4,8 +4,6 @@ import {
|
|||
PIPEDRIVE_NODE_NAME,
|
||||
HTTP_REQUEST_NODE_NAME,
|
||||
NEW_QUERY_AUTH_ACCOUNT_NAME,
|
||||
} from './../constants';
|
||||
import {
|
||||
GMAIL_NODE_NAME,
|
||||
NEW_GOOGLE_ACCOUNT_NAME,
|
||||
NEW_TRELLO_ACCOUNT_NAME,
|
||||
|
@ -13,6 +11,7 @@ import {
|
|||
TRELLO_NODE_NAME,
|
||||
} from '../constants';
|
||||
import { CredentialsPage, CredentialsModal, WorkflowPage, NDV } from '../pages';
|
||||
import { getVisibleSelect } from '../utils';
|
||||
|
||||
const credentialsPage = new CredentialsPage();
|
||||
const credentialsModal = new CredentialsModal();
|
||||
|
@ -90,13 +89,16 @@ describe('Credentials', () => {
|
|||
workflowPage.getters.canvasNodes().last().click();
|
||||
cy.get('body').type('{enter}');
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.getters.credentialsEditModal().should('be.visible');
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().should('have.length', 2);
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().first().click();
|
||||
credentialsModal.actions.fillCredentialsForm();
|
||||
cy.get('.el-message-box').find('button').contains('Close').click();
|
||||
workflowPage.getters.nodeCredentialsSelect().should('contain', NEW_GOOGLE_ACCOUNT_NAME);
|
||||
workflowPage.getters
|
||||
.nodeCredentialsSelect()
|
||||
.find('input')
|
||||
.should('have.value', NEW_GOOGLE_ACCOUNT_NAME);
|
||||
});
|
||||
|
||||
it('should show multiple credential types in the same dropdown', () => {
|
||||
|
@ -107,7 +109,7 @@ describe('Credentials', () => {
|
|||
cy.get('body').type('{enter}');
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
// Add oAuth credentials
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.getters.credentialsEditModal().should('be.visible');
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().should('have.length', 2);
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().first().click();
|
||||
|
@ -115,13 +117,14 @@ describe('Credentials', () => {
|
|||
cy.get('.el-message-box').find('button').contains('Close').click();
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
// Add Service account credentials
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.getters.credentialsEditModal().should('be.visible');
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().should('have.length', 2);
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().last().click();
|
||||
credentialsModal.actions.fillCredentialsForm();
|
||||
// Both (+ the 'Create new' option) should be in the dropdown
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').should('have.length.greaterThan', 3);
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
getVisibleSelect().find('li').should('have.length.greaterThan', 2);
|
||||
});
|
||||
|
||||
it('should correctly render required and optional credentials', () => {
|
||||
|
@ -132,18 +135,18 @@ describe('Credentials', () => {
|
|||
// Select incoming authentication
|
||||
nodeDetailsView.getters.parameterInput('incomingAuthentication').should('exist');
|
||||
nodeDetailsView.getters.parameterInput('incomingAuthentication').click();
|
||||
nodeDetailsView.getters.parameterInput('incomingAuthentication').find('li').first().click();
|
||||
getVisibleSelect().find('li').first().click();
|
||||
// There should be two credential fields
|
||||
workflowPage.getters.nodeCredentialsSelect().should('have.length', 2);
|
||||
|
||||
workflowPage.getters.nodeCredentialsSelect().first().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().first().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
// This one should show auth type selector
|
||||
credentialsModal.getters.credentialAuthTypeRadioButtons().should('have.length', 2);
|
||||
cy.get('body').type('{esc}');
|
||||
|
||||
workflowPage.getters.nodeCredentialsSelect().last().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().last().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
// This one should not show auth type selector
|
||||
credentialsModal.getters.credentialsAuthTypeSelector().should('not.exist');
|
||||
});
|
||||
|
@ -155,10 +158,13 @@ describe('Credentials', () => {
|
|||
workflowPage.getters.canvasNodes().last().click();
|
||||
cy.get('body').type('{enter}');
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.getters.credentialsAuthTypeSelector().should('not.exist');
|
||||
credentialsModal.actions.fillCredentialsForm();
|
||||
workflowPage.getters.nodeCredentialsSelect().should('contain', NEW_TRELLO_ACCOUNT_NAME);
|
||||
workflowPage.getters
|
||||
.nodeCredentialsSelect()
|
||||
.find('input')
|
||||
.should('have.value', NEW_TRELLO_ACCOUNT_NAME);
|
||||
});
|
||||
|
||||
it('should delete credentials from NDV', () => {
|
||||
|
@ -168,16 +174,22 @@ describe('Credentials', () => {
|
|||
workflowPage.getters.canvasNodes().last().click();
|
||||
cy.get('body').type('{enter}');
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.actions.fillCredentialsForm();
|
||||
workflowPage.getters.nodeCredentialsSelect().should('contain', NEW_NOTION_ACCOUNT_NAME);
|
||||
workflowPage.getters
|
||||
.nodeCredentialsSelect()
|
||||
.find('input')
|
||||
.should('have.value', NEW_NOTION_ACCOUNT_NAME);
|
||||
|
||||
workflowPage.getters.nodeCredentialsEditButton().click();
|
||||
credentialsModal.getters.credentialsEditModal().should('be.visible');
|
||||
credentialsModal.getters.deleteButton().click();
|
||||
cy.get('.el-message-box').find('button').contains('Yes').click();
|
||||
workflowPage.getters.successToast().contains('Credential deleted');
|
||||
workflowPage.getters.nodeCredentialsSelect().should('not.contain', NEW_TRELLO_ACCOUNT_NAME);
|
||||
workflowPage.getters
|
||||
.nodeCredentialsSelect()
|
||||
.find('input')
|
||||
.should('not.have.value', NEW_TRELLO_ACCOUNT_NAME);
|
||||
});
|
||||
|
||||
it('should rename credentials from NDV', () => {
|
||||
|
@ -187,17 +199,18 @@ describe('Credentials', () => {
|
|||
workflowPage.getters.canvasNodes().last().click();
|
||||
cy.get('body').type('{enter}');
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.actions.fillCredentialsForm();
|
||||
workflowPage.getters.nodeCredentialsSelect().should('contain', NEW_TRELLO_ACCOUNT_NAME);
|
||||
|
||||
workflowPage.getters.nodeCredentialsEditButton().click();
|
||||
credentialsModal.getters.credentialsEditModal().should('be.visible');
|
||||
credentialsModal.getters.name().click();
|
||||
credentialsModal.actions.renameCredential(NEW_CREDENTIAL_NAME);
|
||||
credentialsModal.getters.saveButton().click();
|
||||
credentialsModal.getters.closeButton().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().should('contain', NEW_CREDENTIAL_NAME);
|
||||
workflowPage.getters
|
||||
.nodeCredentialsSelect()
|
||||
.find('input')
|
||||
.should('have.value', NEW_CREDENTIAL_NAME);
|
||||
});
|
||||
|
||||
it('should setup generic authentication for HTTP node', () => {
|
||||
|
@ -207,20 +220,20 @@ describe('Credentials', () => {
|
|||
workflowPage.getters.canvasNodes().last().click();
|
||||
cy.get('body').type('{enter}');
|
||||
nodeDetailsView.getters.parameterInput('authentication').click();
|
||||
nodeDetailsView.getters.parameterInput('authentication').find('li').should('have.length', 3);
|
||||
nodeDetailsView.getters.parameterInput('authentication').find('li').last().click();
|
||||
getVisibleSelect().find('li').should('have.length', 3);
|
||||
getVisibleSelect().find('li').last().click();
|
||||
nodeDetailsView.getters.parameterInput('genericAuthType').should('exist');
|
||||
nodeDetailsView.getters.parameterInput('genericAuthType').click();
|
||||
nodeDetailsView.getters
|
||||
.parameterInput('genericAuthType')
|
||||
.find('li')
|
||||
.should('have.length.greaterThan', 0);
|
||||
nodeDetailsView.getters.parameterInput('genericAuthType').find('li').last().click();
|
||||
getVisibleSelect().find('li').should('have.length.greaterThan', 0);
|
||||
getVisibleSelect().find('li').last().click();
|
||||
|
||||
workflowPage.getters.nodeCredentialsSelect().should('exist');
|
||||
workflowPage.getters.nodeCredentialsSelect().click();
|
||||
workflowPage.getters.nodeCredentialsSelect().find('li').last().click();
|
||||
getVisibleSelect().find('li').last().click();
|
||||
credentialsModal.actions.fillCredentialsForm();
|
||||
workflowPage.getters.nodeCredentialsSelect().should('contain', NEW_QUERY_AUTH_ACCOUNT_NAME);
|
||||
workflowPage.getters
|
||||
.nodeCredentialsSelect()
|
||||
.find('input')
|
||||
.should('have.value', NEW_QUERY_AUTH_ACCOUNT_NAME);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -85,10 +85,10 @@ describe('Node Creator', () => {
|
|||
nodeCreatorFeature.getters.getCreatorItem(editImageNode).click();
|
||||
nodeCreatorFeature.getters.activeSubcategory().should('have.text', editImageNode);
|
||||
nodeCreatorFeature.getters.getCreatorItem('Crop Image').click();
|
||||
NDVModal.getters.parameterInput('operation').should('contain.text', 'Crop');
|
||||
NDVModal.getters.parameterInput('operation').find('input').should('have.value', 'Crop');
|
||||
});
|
||||
|
||||
it('should search through actions and confirm added action', () => {
|
||||
it.only('should search through actions and confirm added action', () => {
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('ftp');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').type('{rightarrow}');
|
||||
|
@ -96,8 +96,8 @@ describe('Node Creator', () => {
|
|||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('file');
|
||||
// Navigate to rename action which should be the 4th item
|
||||
nodeCreatorFeature.getters.searchBar().find('input').type('{uparrow}{uparrow}{rightarrow}');
|
||||
NDVModal.getters.parameterInput('operation').should('contain.text', 'Rename');
|
||||
})
|
||||
NDVModal.getters.parameterInput('operation').find('input').should('have.value', 'Rename');
|
||||
});
|
||||
|
||||
it('should not show actions for single action nodes', () => {
|
||||
const singleActionNodes = [
|
||||
|
@ -110,19 +110,22 @@ describe('Node Creator', () => {
|
|||
'Spontit',
|
||||
'Vonage',
|
||||
'Send Email',
|
||||
'Toggl Trigger'
|
||||
]
|
||||
const doubleActionNode = 'OpenWeatherMap'
|
||||
'Toggl Trigger',
|
||||
];
|
||||
const doubleActionNode = 'OpenWeatherMap';
|
||||
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
singleActionNodes.forEach((node) => {
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type(node);
|
||||
nodeCreatorFeature.getters.getCreatorItem(node).find('button[class*="panelIcon"]').should('not.exist');
|
||||
})
|
||||
nodeCreatorFeature.getters
|
||||
.getCreatorItem(node)
|
||||
.find('button[class*="panelIcon"]')
|
||||
.should('not.exist');
|
||||
});
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type(doubleActionNode);
|
||||
nodeCreatorFeature.getters.getCreatorItem(doubleActionNode).click();
|
||||
nodeCreatorFeature.getters.creatorItem().should('have.length', 4);
|
||||
})
|
||||
});
|
||||
|
||||
it('should have "Actions" section collapsed when opening actions view from Trigger root view', () => {
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
|
@ -131,10 +134,19 @@ describe('Node Creator', () => {
|
|||
nodeCreatorFeature.getters.getCategoryItem('Actions').should('exist');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Triggers').should('exist');
|
||||
|
||||
nodeCreatorFeature.getters.getCategoryItem('Triggers').parent().should('not.have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').parent().should('have.attr', 'data-category-collapsed', 'true');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').click()
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').parent().should('not.have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Triggers')
|
||||
.parent()
|
||||
.should('not.have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Actions')
|
||||
.parent()
|
||||
.should('have.attr', 'data-category-collapsed', 'true');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').click();
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Actions')
|
||||
.parent()
|
||||
.should('not.have.attr', 'data-category-collapsed');
|
||||
});
|
||||
|
||||
it('should have "Triggers" section collapsed when opening actions view from Regular root view', () => {
|
||||
|
@ -145,17 +157,33 @@ describe('Node Creator', () => {
|
|||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('n8n');
|
||||
nodeCreatorFeature.getters.getCreatorItem('n8n').click();
|
||||
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').parent().should('not.have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').click()
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').parent().should('have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Triggers').parent().should('have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Triggers').click()
|
||||
nodeCreatorFeature.getters.getCategoryItem('Triggers').parent().should('not.have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Actions')
|
||||
.parent()
|
||||
.should('not.have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').click();
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Actions')
|
||||
.parent()
|
||||
.should('have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Triggers')
|
||||
.parent()
|
||||
.should('have.attr', 'data-category-collapsed');
|
||||
nodeCreatorFeature.getters.getCategoryItem('Triggers').click();
|
||||
nodeCreatorFeature.getters
|
||||
.getCategoryItem('Triggers')
|
||||
.parent()
|
||||
.should('not.have.attr', 'data-category-collapsed');
|
||||
});
|
||||
|
||||
it('should show callout and two suggested nodes if node has no trigger actions', () => {
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters
|
||||
.searchBar()
|
||||
.find('input')
|
||||
.clear()
|
||||
.type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters.getCreatorItem('Customer Datastore (n8n training)').click();
|
||||
|
||||
cy.getByTestId('actions-panel-no-triggers-callout').should('be.visible');
|
||||
|
@ -165,12 +193,16 @@ describe('Node Creator', () => {
|
|||
|
||||
it('should show intro callout if user has not made a production execution', () => {
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters
|
||||
.searchBar()
|
||||
.find('input')
|
||||
.clear()
|
||||
.type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters.getCreatorItem('Customer Datastore (n8n training)').click();
|
||||
|
||||
cy.getByTestId('actions-panel-activation-callout').should('be.visible');
|
||||
nodeCreatorFeature.getters.activeSubcategory().find('button').click();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear()
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear();
|
||||
|
||||
nodeCreatorFeature.getters.getCreatorItem('On a schedule').click();
|
||||
|
||||
|
@ -186,7 +218,11 @@ describe('Node Creator', () => {
|
|||
NDVModal.actions.close();
|
||||
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters
|
||||
.searchBar()
|
||||
.find('input')
|
||||
.clear()
|
||||
.type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters.getCreatorItem('Customer Datastore (n8n training)').click();
|
||||
nodeCreatorFeature.getters.getCreatorItem('Get All People').click();
|
||||
NDVModal.actions.close();
|
||||
|
@ -197,11 +233,15 @@ describe('Node Creator', () => {
|
|||
|
||||
// Wait for schedule 1s execution to mark user as having made a production execution
|
||||
cy.wait(1500);
|
||||
cy.reload()
|
||||
cy.reload();
|
||||
|
||||
// Action callout should not be visible after user has made a production execution
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters
|
||||
.searchBar()
|
||||
.find('input')
|
||||
.clear()
|
||||
.type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters.getCreatorItem('Customer Datastore (n8n training)').click();
|
||||
|
||||
cy.getByTestId('actions-panel-activation-callout').should('not.exist');
|
||||
|
@ -210,7 +250,11 @@ describe('Node Creator', () => {
|
|||
it('should show Trigger and Actions sections during search', () => {
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters
|
||||
.searchBar()
|
||||
.find('input')
|
||||
.clear()
|
||||
.type('Customer Datastore (n8n training)');
|
||||
nodeCreatorFeature.getters.getCreatorItem('Customer Datastore (n8n training)').click();
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Non existent action name');
|
||||
|
@ -228,7 +272,8 @@ describe('Node Creator', () => {
|
|||
{
|
||||
name: 'canvas add button',
|
||||
handler: () => nodeCreatorFeature.getters.canvasAddButton().click(),
|
||||
}, {
|
||||
},
|
||||
{
|
||||
name: 'plus button',
|
||||
handler: () => nodeCreatorFeature.getters.plusButton().click(),
|
||||
},
|
||||
|
@ -238,10 +283,10 @@ describe('Node Creator', () => {
|
|||
// name: 'tab key',
|
||||
// handler: () => cy.realPress('Tab'),
|
||||
// },
|
||||
]
|
||||
];
|
||||
sourcesWithAppend.forEach((source) => {
|
||||
it(`should append manual trigger when source is ${source.name}`, () => {
|
||||
source.handler()
|
||||
source.handler();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('n8n');
|
||||
nodeCreatorFeature.getters.getCreatorItem('n8n').click();
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').click();
|
||||
|
@ -258,8 +303,8 @@ describe('Node Creator', () => {
|
|||
nodeCreatorFeature.getters.getCategoryItem('Actions').click();
|
||||
nodeCreatorFeature.getters.getCreatorItem('Create a credential').click();
|
||||
NDVModal.actions.close();
|
||||
WorkflowPage.actions.deleteNode('When clicking "Execute Workflow"')
|
||||
WorkflowPage.getters.canvasNodePlusEndpointByName('n8n').click()
|
||||
WorkflowPage.actions.deleteNode('When clicking "Execute Workflow"');
|
||||
WorkflowPage.getters.canvasNodePlusEndpointByName('n8n').click();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('n8n');
|
||||
nodeCreatorFeature.getters.getCreatorItem('n8n').click();
|
||||
nodeCreatorFeature.getters.getCategoryItem('Actions').click();
|
||||
|
@ -267,8 +312,8 @@ describe('Node Creator', () => {
|
|||
NDVModal.actions.close();
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 2);
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
WorkflowPage.actions.addNodeBetweenNodes('n8n', 'n8n1', 'Item Lists', 'Summarize')
|
||||
WorkflowPage.actions.addNodeBetweenNodes('n8n', 'n8n1', 'Item Lists', 'Summarize');
|
||||
WorkflowPage.getters.canvasNodes().should('have.length', 3);
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,6 +6,10 @@ before(() => {
|
|||
owner: INSTANCE_OWNER,
|
||||
members: INSTANCE_MEMBERS,
|
||||
});
|
||||
|
||||
Cypress.on('uncaught:exception', (err) => {
|
||||
return !err.message.includes('ResizeObserver');
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
1
cypress/utils/index.ts
Normal file
1
cypress/utils/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './popper';
|
7
cypress/utils/popper.ts
Normal file
7
cypress/utils/popper.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export function getVisiblePopper() {
|
||||
return cy.get('.el-popper').filter(':visible');
|
||||
}
|
||||
|
||||
export function getVisibleSelect() {
|
||||
return getVisiblePopper().filter('.el-select__popper');
|
||||
}
|
3
packages/editor-ui/src/components/Fragment.vue
Normal file
3
packages/editor-ui/src/components/Fragment.vue
Normal file
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<slot />
|
||||
</template>
|
|
@ -206,14 +206,13 @@ const OrderSwitcher = defineComponent({
|
|||
},
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
const triggers = slots.triggers?.();
|
||||
const actions = slots.actions?.();
|
||||
|
||||
return () =>
|
||||
h(
|
||||
'div',
|
||||
{},
|
||||
props.rootView === REGULAR_NODE_CREATOR_VIEW ? [actions, triggers] : [triggers, actions],
|
||||
props.rootView === REGULAR_NODE_CREATOR_VIEW
|
||||
? [slots.actions?.(), slots.triggers?.()]
|
||||
: [slots.triggers?.(), slots.actions?.()],
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -237,32 +236,30 @@ onMounted(() => {
|
|||
@selected="onSelected"
|
||||
>
|
||||
<!-- Empty state -->
|
||||
<template #empty>
|
||||
<template v-if="hasNoTriggerActions">
|
||||
<n8n-callout
|
||||
theme="info"
|
||||
iconless
|
||||
slim
|
||||
data-test-id="actions-panel-no-triggers-callout"
|
||||
>
|
||||
<span
|
||||
v-html="
|
||||
$locale.baseText('nodeCreator.actionsCallout.noTriggerItems', {
|
||||
interpolate: { nodeName: subcategory },
|
||||
})
|
||||
"
|
||||
/>
|
||||
</n8n-callout>
|
||||
<ItemsRenderer @selected="onSelected" :elements="placeholderTriggerActions" />
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<p
|
||||
:class="$style.resetSearch"
|
||||
v-html="$locale.baseText('nodeCreator.actionsCategory.noMatchingTriggers')"
|
||||
@click="resetSearch"
|
||||
<template #empty v-if="hasNoTriggerActions">
|
||||
<n8n-callout
|
||||
v-if="hasNoTriggerActions"
|
||||
theme="info"
|
||||
iconless
|
||||
slim
|
||||
data-test-id="actions-panel-no-triggers-callout"
|
||||
>
|
||||
<span
|
||||
v-html="
|
||||
$locale.baseText('nodeCreator.actionsCallout.noTriggerItems', {
|
||||
interpolate: { nodeName: subcategory },
|
||||
})
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
</n8n-callout>
|
||||
<ItemsRenderer @selected="onSelected" :elements="placeholderTriggerActions" />
|
||||
</template>
|
||||
<template #empty v-else>
|
||||
<p
|
||||
:class="$style.resetSearch"
|
||||
v-html="$locale.baseText('nodeCreator.actionsCategory.noMatchingTriggers')"
|
||||
@click="resetSearch"
|
||||
/>
|
||||
</template>
|
||||
</CategorizedItemsRenderer>
|
||||
</template>
|
||||
|
@ -295,14 +292,13 @@ onMounted(() => {
|
|||
"
|
||||
/>
|
||||
</n8n-info-tip>
|
||||
<template v-else>
|
||||
<p
|
||||
:class="$style.resetSearch"
|
||||
v-html="$locale.baseText('nodeCreator.actionsCategory.noMatchingActions')"
|
||||
@click="resetSearch"
|
||||
data-test-id="actions-panel-no-matching-actions"
|
||||
/>
|
||||
</template>
|
||||
<p
|
||||
v-else
|
||||
:class="$style.resetSearch"
|
||||
v-html="$locale.baseText('nodeCreator.actionsCategory.noMatchingActions')"
|
||||
@click="resetSearch"
|
||||
data-test-id="actions-panel-no-matching-actions"
|
||||
/>
|
||||
</template>
|
||||
</CategorizedItemsRenderer>
|
||||
</template>
|
||||
|
|
|
@ -125,7 +125,7 @@ watch(
|
|||
:data-keyboard-nav-id="item.uuid"
|
||||
@click="wrappedEmit('selected', item)"
|
||||
>
|
||||
<template v-if="renderedItems.includes(item)">
|
||||
<Fragment v-if="renderedItems.includes(item)">
|
||||
<label-item v-if="item.type === 'label'" :item="item" />
|
||||
<subcategory-item v-if="item.type === 'subcategory'" :item="item.properties" />
|
||||
|
||||
|
@ -148,7 +148,7 @@ watch(
|
|||
:view="item.properties"
|
||||
:class="$style.viewItem"
|
||||
/>
|
||||
</template>
|
||||
</Fragment>
|
||||
|
||||
<n8n-loading :loading="true" :rows="1" variant="p" :class="$style.itemSkeleton" v-else />
|
||||
</div>
|
||||
|
|
|
@ -7,12 +7,14 @@ import { ElLoading, ElMessageBox } from 'element-plus';
|
|||
import { N8nPlugin } from 'n8n-design-system';
|
||||
import { useMessage } from '@/composables/useMessage';
|
||||
import EnterpriseEdition from '@/components/EnterpriseEdition.ee.vue';
|
||||
import Fragment from '@/components/Fragment.vue';
|
||||
|
||||
export const GlobalComponentsPlugin: Plugin<{}> = {
|
||||
install(app) {
|
||||
const messageService = useMessage();
|
||||
|
||||
app.component('enterprise-edition', EnterpriseEdition);
|
||||
app.component('fragment', Fragment);
|
||||
|
||||
app.use(ElementPlus);
|
||||
app.use(N8nPlugin);
|
||||
|
|
|
@ -1916,7 +1916,7 @@ export default defineComponent({
|
|||
newNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, position);
|
||||
}
|
||||
|
||||
const localizedName = this.localizeNodeName(newNodeData.name, newNodeData.type);
|
||||
const localizedName = this.locale.localizeNodeName(newNodeData.name, newNodeData.type);
|
||||
|
||||
newNodeData.name = this.uniqueNodeName(localizedName);
|
||||
|
||||
|
@ -2728,7 +2728,7 @@ export default defineComponent({
|
|||
const newNodeData = deepCopy(this.getNodeDataToSave(node));
|
||||
newNodeData.id = uuid();
|
||||
|
||||
const localizedName = this.localizeNodeName(newNodeData.name, newNodeData.type);
|
||||
const localizedName = this.locale.localizeNodeName(newNodeData.name, newNodeData.type);
|
||||
|
||||
newNodeData.name = this.uniqueNodeName(localizedName);
|
||||
|
||||
|
@ -3380,7 +3380,7 @@ export default defineComponent({
|
|||
|
||||
oldName = node.name;
|
||||
|
||||
const localized = this.localizeNodeName(node.name, node.type);
|
||||
const localized = this.locale.localizeNodeName(node.name, node.type);
|
||||
|
||||
newName = this.uniqueNodeName(localized, newNodeNames);
|
||||
|
||||
|
|
Loading…
Reference in a new issue