test(editor): Execution testing from UI perspective (no-changelog) (#5429)

* test(editor): Execution testing from UI perspective

* test(editor): Execution testing from UI perspective

* test(editor): Execution test rename

* test(editor): Execution test rename and add stop test

* test(editor): Execution test with webhook

* test(editor): Execution test with webhook
This commit is contained in:
Csaba Tuncsik 2023-02-16 11:41:25 +01:00 committed by GitHub
parent a2c6ea9e11
commit 593b5d299a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 393 additions and 0 deletions

View file

@ -0,0 +1,225 @@
import { v4 as uuid } from 'uuid';
import { NDV, WorkflowPage as WorkflowPageClass, WorkflowsPage } from '../pages';
const workflowsPage = new WorkflowsPage();
const workflowPage = new WorkflowPageClass();
const ndv = new NDV();
describe('Execution',() => {
beforeEach(() => {
cy.resetAll();
cy.skipSetup();
cy.visit('/');
});
it('should test manual workflow', () => {
// Import workflow
workflowsPage.getters.newWorkflowButtonCard().click();
cy.createFixtureWorkflow('Manual_wait_set.json', `Manual wait set ${uuid()}`);
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('not.exist');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('not.exist');
// Execute the workflow
workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().get('.n8n-spinner').should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('be.visible');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('not.exist');
// Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters.canvasNodeByName('Manual').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check').should('not.exist'));
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-sync-alt')).should('be.visible');
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check').should('not.exist'));
cy.wait(2000);
// Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start)
workflowPage.getters.canvasNodeByName('Manual').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check')).should('be.visible');
// Clear execution data
workflowPage.getters.clearExecutionDataButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().click();
workflowPage.getters.clearExecutionDataButton().should('not.exist');
// Check success toast (works because Cypress waits enough for the element to show after the http request node has finished)
workflowPage.getters.successToast().should('be.visible');
});
it('should test manual workflow stop', () => {
// Import workflow
workflowsPage.getters.newWorkflowButtonCard().click();
cy.createFixtureWorkflow('Manual_wait_set.json', `Manual wait set ${uuid()}`);
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('not.exist');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('not.exist');
// Execute the workflow
workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().get('.n8n-spinner').should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('be.visible');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('not.exist');
// Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters.canvasNodeByName('Manual').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check').should('not.exist'));
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-sync-alt')).should('be.visible');
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check').should('not.exist'));
cy.wait(1000);
workflowPage.getters.stopExecutionButton().click();
// Check canvas nodes after workflow stopped
workflowPage.getters.canvasNodeByName('Manual').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-sync-alt').should('not.visible'));
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check').should('not.exist'));
// Clear execution data
workflowPage.getters.clearExecutionDataButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().click();
workflowPage.getters.clearExecutionDataButton().should('not.exist');
// Check success toast (works because Cypress waits enough for the element to show after the http request node has finished)
workflowPage.getters.successToast().should('be.visible');
});
it('should test webhook workflow', () => {
// Import workflow
workflowsPage.getters.newWorkflowButtonCard().click();
cy.createFixtureWorkflow('Webhook_wait_set.json', `Webhook wait set ${uuid()}`);
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('not.exist');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('not.exist');
// Execute the workflow
workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().get('.n8n-spinner').should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('not.exist');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('be.visible');
workflowPage.getters.canvasNodes().first().dblclick();
ndv.getters.copyInput().click();
cy.grantBrowserPermissions('clipboardReadWrite', 'clipboardSanitizedWrite');
ndv.getters.backToCanvas().click();
cy.readClipboard().then((url) => {
cy.request({
method: 'GET',
url,
}).then((resp) => {
expect(resp.status).to.eq(200);
});
});
// Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters.canvasNodeByName('Webhook').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check').should('not.exist'));
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-sync-alt')).should('be.visible');
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check').should('not.exist'));
cy.wait(2000);
// Check canvas nodes after 2nd step (waiting node finished its execution and the http request node is about to start)
workflowPage.getters.canvasNodeByName('Webhook').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check')).should('be.visible');
// Clear execution data
workflowPage.getters.clearExecutionDataButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().click();
workflowPage.getters.clearExecutionDataButton().should('not.exist');
// Check success toast (works because Cypress waits enough for the element to show after the http request node has finished)
workflowPage.getters.successToast().should('be.visible');
});
it('should test webhook workflow stop', () => {
// Import workflow
workflowsPage.getters.newWorkflowButtonCard().click();
cy.createFixtureWorkflow('Webhook_wait_set.json', `Webhook wait set ${uuid()}`);
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('not.exist');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('not.exist');
// Execute the workflow
workflowPage.getters.zoomToFitButton().click();
workflowPage.getters.executeWorkflowButton().click();
// Check workflow buttons
workflowPage.getters.executeWorkflowButton().get('.n8n-spinner').should('be.visible');
workflowPage.getters.clearExecutionDataButton().should('not.exist');
workflowPage.getters.stopExecutionButton().should('not.exist');
workflowPage.getters.stopExecutionWaitingForWebhookButton().should('be.visible');
workflowPage.getters.canvasNodes().first().dblclick();
ndv.getters.copyInput().click();
cy.grantBrowserPermissions('clipboardReadWrite', 'clipboardSanitizedWrite');
ndv.getters.backToCanvas().click();
cy.readClipboard().then((url) => {
cy.request({
method: 'GET',
url,
}).then((resp) => {
expect(resp.status).to.eq(200);
});
});
// Check canvas nodes after 1st step (workflow passed the manual trigger node
workflowPage.getters.canvasNodeByName('Webhook').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check').should('not.exist'));
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-sync-alt')).should('be.visible');
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check').should('not.exist'));
cy.wait(1000);
workflowPage.getters.stopExecutionWaitingForWebhookButton().click();
// Check canvas nodes after workflow stopped
workflowPage.getters.canvasNodeByName('Webhook').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-check')).should('be.visible');
workflowPage.getters.canvasNodeByName('Wait').within(() => cy.get('.fa-sync-alt').should('not.visible'));
workflowPage.getters.canvasNodeByName('Set').within(() => cy.get('.fa-check').should('not.exist'));
// Clear execution data
workflowPage.getters.clearExecutionDataButton().should('be.visible');
workflowPage.getters.clearExecutionDataButton().click();
workflowPage.getters.clearExecutionDataButton().should('not.exist');
// Check success toast (works because Cypress waits enough for the element to show after the http request node has finished)
workflowPage.getters.successToast().should('be.visible');
});
});

View file

@ -0,0 +1,81 @@
{
"name": "Manual wait set",
"nodes": [
{
"parameters": {
"amount": 2,
"unit": "seconds"
},
"id": "ed6e0168-1145-43d0-9082-970b8a8f3cb5",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [
900,
580
],
"webhookId": "0f6f94a4-c28d-46f9-8468-6ab315a9fec9"
},
{
"parameters": {},
"id": "59467b99-4e7c-4f19-8fc2-4329788f0951",
"name": "Manual",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
680,
580
]
},
{
"parameters": {
"options": {}
},
"id": "6ddf089f-4d01-4691-928f-6de168e3b089",
"name": "Set",
"type": "n8n-nodes-base.set",
"typeVersion": 1,
"position": [
1120,
580
]
}
],
"pinData": {},
"connections": {
"Wait": {
"main": [
[
{
"node": "Set",
"type": "main",
"index": 0
}
]
]
},
"Manual": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"saveExecutionProgress": true,
"saveManualExecutions": true,
"callerPolicy": "workflowsFromSameOwner"
},
"versionId": "f11ff1bf-4273-46cb-bbec-65c7b2fa13cb",
"id": "1037",
"meta": {
"instanceId": "8a47b83b4479b11330fdf21ccc96d4a8117035a968612e452b4c87bfd09c16c7"
},
"tags": []
}

View file

@ -0,0 +1,81 @@
{
"name": "Webhook wait set",
"nodes": [
{
"parameters": {
"path": "23fc3930-b8f9-41d9-89db-b647291a2201",
"options": {}
},
"id": "70d84fe7-e221-4978-a15e-3984f2df645f",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
500,
580
],
"webhookId": "23fc3930-b8f9-41d9-89db-b647291a2201"
},
{
"parameters": {
"amount": 2,
"unit": "seconds"
},
"id": "7f15f650-99bc-400b-8db8-67be53003fa3",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [
720,
580
],
"webhookId": "18a12605-1fbd-49da-854e-268ab6db1ea3"
},
{
"parameters": {
"options": {}
},
"id": "5bdafae4-e297-463f-991f-b8ea14983026",
"name": "Set",
"type": "n8n-nodes-base.set",
"typeVersion": 1,
"position": [
940,
580
]
}
],
"pinData": {},
"connections": {
"Webhook": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Set",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"versionId": "0c67e557-1faf-446e-881e-3245228c627e",
"id": "1038",
"meta": {
"instanceId": "8a47b83b4479b11330fdf21ccc96d4a8117035a968612e452b4c87bfd09c16c7"
},
"tags": []
}

View file

@ -90,6 +90,9 @@ export class WorkflowPage extends BasePage {
zoomOutButton: () => cy.getByTestId('zoom-out-button'),
resetZoomButton: () => cy.getByTestId('reset-zoom-button'),
executeWorkflowButton: () => cy.getByTestId('execute-workflow-button'),
clearExecutionDataButton: () => cy.getByTestId('clear-execution-data-button'),
stopExecutionButton: () => cy.getByTestId('stop-execution-button'),
stopExecutionWaitingForWebhookButton: () => cy.getByTestId('stop-execution-waiting-for-webhook-button'),
nodeCredentialsSelect: () => cy.getByTestId('node-credentials-select'),
nodeCredentialsEditButton: () => cy.getByTestId('credential-edit-button'),
nodeCreatorItems: () => cy.getByTestId('item-iterator-item'),

View file

@ -133,6 +133,7 @@
"
:loading="stopExecutionInProgress"
@click.stop="stopExecution"
data-test-id="stop-execution-button"
/>
<n8n-icon-button
@ -143,6 +144,7 @@
:title="$locale.baseText('nodeView.stopWaitingForWebhookCall')"
type="secondary"
@click.stop="stopWaitingForWebhook"
data-test-id="stop-execution-waiting-for-webhook-button"
/>
<n8n-icon-button
@ -151,6 +153,7 @@
icon="trash"
size="large"
@click.stop="clearExecutionData"
data-test-id="clear-execution-data-button"
/>
</div>
</div>