ci(editor): Run e2e tests in parallel and improve build caching (#5445)
* WIP: Cypress parallel CI run test * Trigger action on branch push * Change build artifacts path * Make sure to checkout the repo for testing job * Use Cypress action for installing * Lock cypress action userd version * Skip node install step since we're using cypress node16 container * Let Cypress handle pnpm install * Use setup-node action for caching pnpm * Set CYPRESS_CACHE_FOLDER * Set CYPRESS_CACHE_FOLDER * Manually cache pnpm store * Dont fix pnpm version * Use caching action also in testing job * Zip packages dist before uploading the artifacts and change caching key * Use absolute build paths for zipping job * Use zip command in action * Use tar for zipping packages * Debuggin directory ls * Debugging caching of modules * Attempt to fix permissions issue * Porivde Cypress executable via `CYPRESS_RUN_BINARY` * Cache /github/home * Adjust caching keys * Debug: search for cypress exec * Debugging: List dirs * Use pnpm install action to install node_modules * Do not log /home/runner * Use node_modules/.bin Cypress binary * Use absolute path to nodue modules * Run Cypress via custom command * Try with patched cypress action * Revert logging * Manually specify cypress config file * Use absolute paths * Fix cypress config name * Debug print cypress config * Remove debugging, increase to 4 containers * Increase amount of containers * Add env-version matrix * Replace node14 with node18 in testing matrix * Remove debugging and add node 14 * Use just node14 * Use cypress:base and remove browser req * Give more general timeouts * Try with node16 * Change cache directive position * Replace zip artifact upload with cache * Cache full packages not just dist * Test with variable inputs * Add commit info message * Remove wrongly commited code * Allow WF API dispatch * Try Chrome browser again for comparison * Include Monaco in the build * Make e2e workflow re-usable * Comment out invalid reusable workflow args * Use electron and add node 14 run * Fix env arg * Provide custom ci-build-id * Refactor remaining e2e workflow to use reusable action * Remove single matrix directive * Refactor ci-pull-req * Make lint job dependant on test jobs * Disable debugging job * Make containers dynamic * Cleanup & install git for linting action * Use regular buntu image for PR linting * Debugging failing tests * Remove fixed spec name * Debug e2e env var * Do not use realkeypress which crashes electron runner * Debugging * chore: remove console * chore: remove console * test: remove node 14 tests * test: replace test branch with master * test: use tests in current branch * test: use relative path * chore: clean up * test: only trigger on approval * ci: update test PR * ci: use curr branch * ci: only run 14 on schedule, not for slack command * ci: only run test on approval * ci: clean up branch, rename step * ci: rename steps * ci: clean up cancel * ci: clean up env var * ci: set var * ci: use chromef * ci: use electron * chore: add console log * chore: add console log * ci: update to string * ci: set all env options * test: build * ci: fix step issue * Fix failing tests & upgrade to Cypress 12 * Allow WF dispatch of e2e reusable * Fix wrong naming in e2e-tests workflow * Redeploy * Fix tests * Fix NDV tests and remove skipping of webhooks execution tests * Fix clipboard read command * Fix execution failing tests * Reset before each 15 and 3 * Fix flaky tests * Cleanup and log envs * Test fixes * Default owner spec fixes * Get rid of CYPRESS_RUN_ENV * Increase amount of containers, cleanup and add mock for credentials test call * Cleanup & fix PR tests unit tests * Wait for WF to loade in sharing spec * Do linting and unit tests first * Use frozen lockfile * Revert back ci pull request jobs order * Refine credential input selector and move cy.waitForLoad to correct position in 15-scheduler spec * test: build * Wait for WF execution instead of arbitraty timeout in WF execution spec, change order of jobs for ci pull request * Fix flaky 3-default owner spec and wait for execution list to load in 20-workflow-executions * Use setup node action * Remove caching for lint/unit tests * Experiment with parallel test & lint on ci * Provide cache key dynamically * Run e2e in parallel on pr * Only run node14 e2e on daily schedule * Make sure to generate generate new ci-build-id on re-runs * Remove debugging prints * Address PR comments * Rename custom onBeforeUnload handler * Make sure 19-execution spec waits for wf to load properly before import fixtures --------- Co-authored-by: Mutasem <mutdmour@gmail.com>
This commit is contained in:
@@ -63,11 +63,9 @@ describe('Log Streaming Settings', () => {
|
||||
settingsLogStreamingPage.getters.getSelectDestinationType().click();
|
||||
settingsLogStreamingPage.getters.getSelectDestinationTypeItems().eq(0).click();
|
||||
settingsLogStreamingPage.getters.getSelectDestinationButton().click();
|
||||
settingsLogStreamingPage.getters
|
||||
.getDestinationNameInput()
|
||||
.click()
|
||||
.clear()
|
||||
.type('Destination 0');
|
||||
settingsLogStreamingPage.getters.getDestinationNameInput().click()
|
||||
|
||||
settingsLogStreamingPage.getters.getDestinationNameInput().find('input').clear().type('Destination 0');
|
||||
settingsLogStreamingPage.getters.getDestinationSaveButton().click();
|
||||
cy.wait(100);
|
||||
settingsLogStreamingPage.getters.getDestinationModal().click(1, 1);
|
||||
@@ -88,11 +86,8 @@ describe('Log Streaming Settings', () => {
|
||||
settingsLogStreamingPage.getters.getSelectDestinationType().click();
|
||||
settingsLogStreamingPage.getters.getSelectDestinationTypeItems().eq(0).click();
|
||||
settingsLogStreamingPage.getters.getSelectDestinationButton().click();
|
||||
settingsLogStreamingPage.getters
|
||||
.getDestinationNameInput()
|
||||
.click()
|
||||
.clear()
|
||||
.type('Destination 1');
|
||||
settingsLogStreamingPage.getters.getDestinationNameInput().click()
|
||||
settingsLogStreamingPage.getters.getDestinationNameInput().find('input').clear().type('Destination 1');
|
||||
settingsLogStreamingPage.getters.getDestinationSaveButton().should('not.have.attr', 'disabled');
|
||||
settingsLogStreamingPage.getters.getDestinationSaveButton().click();
|
||||
cy.wait(100);
|
||||
|
||||
@@ -17,6 +17,7 @@ describe('Inline expression editor', () => {
|
||||
});
|
||||
|
||||
it('should resolve primitive resolvables', () => {
|
||||
WorkflowPage.getters.inlineExpressionEditorInput().clear();
|
||||
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
|
||||
WorkflowPage.getters.inlineExpressionEditorInput().type('1 + 2');
|
||||
WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^3$/);
|
||||
@@ -35,6 +36,7 @@ describe('Inline expression editor', () => {
|
||||
});
|
||||
|
||||
it('should resolve object resolvables', () => {
|
||||
WorkflowPage.getters.inlineExpressionEditorInput().clear();
|
||||
WorkflowPage.getters.inlineExpressionEditorInput().type('{{');
|
||||
WorkflowPage.getters
|
||||
.inlineExpressionEditorInput()
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('Data transformation expressions', () => {
|
||||
cy.window()
|
||||
// @ts-ignore
|
||||
.then(
|
||||
(win) => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload),
|
||||
(win) => win.onBeforeUnloadNodeView && win.removeEventListener('beforeunload', win.onBeforeUnloadNodeView),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -80,19 +80,18 @@ describe('Data transformation expressions', () => {
|
||||
ndv.getters.outputDataContainer().contains(output);
|
||||
});
|
||||
|
||||
it('$json + native array methods', () => {
|
||||
it('$json + native array access', () => {
|
||||
wf.actions.addInitialNodeToCanvas('Schedule Trigger', { keepNdvOpen: true });
|
||||
ndv.actions.setPinnedData([{ myArr: [1, 2, 3] }]);
|
||||
ndv.actions.close();
|
||||
addSet();
|
||||
|
||||
const input = '{{$json.myArr.includes(1) + " " + $json.myArr.at(2)';
|
||||
const input = '{{$json.myArr.includes(1) + " " + $json.myArr[2]';
|
||||
const output = 'true 3';
|
||||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().should('be.visible');
|
||||
ndv.getters.outputDataContainer().contains(output);
|
||||
ndv.getters.outputDataContainer().find('[class*=value_]').should('exist')
|
||||
ndv.getters.outputDataContainer().find('[class*=value_]').should('contain', output);
|
||||
});
|
||||
|
||||
it('$json + n8n array methods', () => {
|
||||
@@ -106,7 +105,8 @@ describe('Data transformation expressions', () => {
|
||||
|
||||
ndv.getters.inlineExpressionEditorInput().clear().type(input);
|
||||
ndv.actions.execute();
|
||||
ndv.getters.outputDataContainer().should('be.visible').contains(output);
|
||||
ndv.getters.outputDataContainer().find('[class*=value_]').should('exist')
|
||||
ndv.getters.outputDataContainer().find('[class*=value_]').should('contain', output);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ describe('Data mapping', () => {
|
||||
cy.window()
|
||||
// @ts-ignore
|
||||
.then(
|
||||
(win) => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload),
|
||||
(win) => win.onBeforeUnloadNodeView && win.removeEventListener('beforeunload', win.onBeforeUnloadNodeView),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@ const workflowPage = new WorkflowPage();
|
||||
const ndv = new NDV();
|
||||
|
||||
describe('Schedule Trigger node', async () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
cy.visit(workflowsPage.url);
|
||||
});
|
||||
|
||||
it('should execute and return the execution timestamp', () => {
|
||||
cy.visit(workflowsPage.url);
|
||||
|
||||
workflowsPage.actions.createWorkflowFromCard();
|
||||
cy.waitForLoad();
|
||||
workflowPage.actions.addInitialNodeToCanvas('Schedule Trigger');
|
||||
workflowPage.actions.openNode('Schedule Trigger');
|
||||
ndv.actions.execute();
|
||||
@@ -22,9 +22,8 @@ describe('Schedule Trigger node', async () => {
|
||||
});
|
||||
|
||||
it('should execute once per second when activated', () => {
|
||||
cy.visit(workflowsPage.url);
|
||||
|
||||
workflowsPage.actions.createWorkflowFromCard();
|
||||
cy.waitForLoad();
|
||||
workflowPage.actions.renameWorkflow('Schedule Trigger Workflow');
|
||||
workflowPage.actions.addInitialNodeToCanvas('Schedule Trigger');
|
||||
workflowPage.actions.openNode('Schedule Trigger');
|
||||
|
||||
@@ -103,7 +103,7 @@ describe('Webhook Trigger node', async () => {
|
||||
cy.window()
|
||||
// @ts-ignore
|
||||
.then(
|
||||
(win) => win.onBeforeUnload && win.removeEventListener('beforeunload', win.onBeforeUnload),
|
||||
(win) => win.onBeforeUnloadNodeView && win.removeEventListener('beforeunload', win.onBeforeUnloadNodeView),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ describe('Sharing', () => {
|
||||
|
||||
cy.visit(workflowsPage.url);
|
||||
workflowsPage.getters.newWorkflowButtonCard().click();
|
||||
cy.waitForLoad();
|
||||
workflowPage.actions.setWorkflowName('Workflow W1');
|
||||
workflowPage.actions.addInitialNodeToCanvas('Manual Trigger');
|
||||
workflowPage.actions.addNodeToCanvas('Notion', true, true);
|
||||
|
||||
@@ -5,12 +5,9 @@ const wf = new WorkflowPage();
|
||||
const TEST_TAGS = ['Tag 1', 'Tag 2', 'Tag 3'];
|
||||
|
||||
describe('Workflow tags', () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
wf.actions.visit();
|
||||
cy.waitForLoad();
|
||||
});
|
||||
|
||||
@@ -6,18 +6,15 @@ const workflowPage = new WorkflowPageClass();
|
||||
const ndv = new NDV();
|
||||
|
||||
describe('Execution', () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
// Import workflow
|
||||
workflowsPage.getters.newWorkflowButtonCard().click();
|
||||
cy.waitForLoad();
|
||||
});
|
||||
|
||||
it('should test manual workflow', () => {
|
||||
// Import workflow
|
||||
workflowsPage.getters.newWorkflowButtonCard().click();
|
||||
cy.createFixtureWorkflow('Manual_wait_set.json', `Manual wait set ${uuid()}`);
|
||||
|
||||
// Check workflow buttons
|
||||
@@ -40,14 +37,14 @@ describe('Execution', () => {
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Manual')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
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');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Set')
|
||||
.within(() => cy.get('.fa-check').should('not.exist'));
|
||||
@@ -58,15 +55,15 @@ describe('Execution', () => {
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Manual')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Wait')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Set')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
|
||||
// Clear execution data
|
||||
workflowPage.getters.clearExecutionDataButton().should('be.visible');
|
||||
@@ -78,8 +75,6 @@ describe('Execution', () => {
|
||||
});
|
||||
|
||||
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
|
||||
@@ -102,14 +97,14 @@ describe('Execution', () => {
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Manual')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
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');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Set')
|
||||
.within(() => cy.get('.fa-check').should('not.exist'));
|
||||
@@ -121,11 +116,11 @@ describe('Execution', () => {
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Manual')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Wait')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Wait')
|
||||
.within(() => cy.get('.fa-sync-alt').should('not.visible'));
|
||||
@@ -143,8 +138,6 @@ describe('Execution', () => {
|
||||
});
|
||||
|
||||
it('should test webhook workflow', () => {
|
||||
// Import workflow
|
||||
workflowsPage.getters.newWorkflowButtonCard().click();
|
||||
cy.createFixtureWorkflow('Webhook_wait_set.json', `Webhook wait set ${uuid()}`);
|
||||
|
||||
// Check workflow buttons
|
||||
@@ -184,14 +177,14 @@ describe('Execution', () => {
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Webhook')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
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');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Set')
|
||||
.within(() => cy.get('.fa-check').should('not.exist'));
|
||||
@@ -202,15 +195,15 @@ describe('Execution', () => {
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Webhook')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Wait')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Set')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
|
||||
// Clear execution data
|
||||
workflowPage.getters.clearExecutionDataButton().should('be.visible');
|
||||
@@ -222,8 +215,6 @@ describe('Execution', () => {
|
||||
});
|
||||
|
||||
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
|
||||
@@ -259,34 +250,33 @@ describe('Execution', () => {
|
||||
});
|
||||
});
|
||||
|
||||
workflowPage.getters.stopExecutionButton().click();
|
||||
// Check canvas nodes after 1st step (workflow passed the manual trigger node
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Webhook')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
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');
|
||||
.should('exist');
|
||||
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');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Wait')
|
||||
.within(() => cy.get('.fa-check'))
|
||||
.should('be.visible');
|
||||
.should('exist');
|
||||
workflowPage.getters
|
||||
.canvasNodeByName('Wait')
|
||||
.within(() => cy.get('.fa-sync-alt').should('not.visible'));
|
||||
|
||||
@@ -32,6 +32,14 @@ describe('Credentials', () => {
|
||||
before(() => {
|
||||
cy.resetAll();
|
||||
cy.setup({ email, firstName, lastName, password });
|
||||
|
||||
// Always intercept the request to test credentials and return a success
|
||||
cy.intercept('POST', '/rest/credentials/test', {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
data: { status: 'success', message: 'Tested successfully' },
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -53,7 +61,6 @@ describe('Credentials', () => {
|
||||
credentialsModal.getters.newCredentialTypeOption('Notion API').click();
|
||||
|
||||
credentialsModal.getters.newCredentialTypeButton().click();
|
||||
|
||||
credentialsModal.getters.connectionParameter('API Key').type('1234567890');
|
||||
|
||||
credentialsModal.actions.setName('My awesome Notion account');
|
||||
@@ -71,7 +78,7 @@ describe('Credentials', () => {
|
||||
credentialsModal.getters.newCredentialTypeOption('Airtable API').click();
|
||||
|
||||
credentialsModal.getters.newCredentialTypeButton().click();
|
||||
|
||||
credentialsModal.getters.editCredentialModal().should('be.visible');
|
||||
credentialsModal.getters.connectionParameter('API Key').type('1234567890');
|
||||
|
||||
credentialsModal.actions.setName('Airtable Account');
|
||||
|
||||
@@ -19,7 +19,13 @@ describe('Current Workflow Executions', () => {
|
||||
});
|
||||
|
||||
it('should render executions tab correctly', () => {
|
||||
cy.waitForLoad();
|
||||
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');
|
||||
cy.intercept('GET', '/rest/executions-current?filter=*').as('getCurrentExecutions');
|
||||
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
|
||||
cy.wait(['@getExecutions', '@getCurrentExecutions']);
|
||||
|
||||
executionsTab.getters.executionListItems().should('have.length', 11);
|
||||
executionsTab.getters.successfulExecutionListItems().should('have.length', 9);
|
||||
executionsTab.getters.failedExecutionListItems().should('have.length', 2);
|
||||
@@ -40,6 +46,4 @@ const createMockExecutions = () => {
|
||||
// Then add some more successful ones
|
||||
executionsTab.actions.toggleNodeEnabled('Error');
|
||||
executionsTab.actions.createManualExecutions(4);
|
||||
executionsTab.actions.switchToExecutionsTab();
|
||||
cy.waitForLoad();
|
||||
};
|
||||
|
||||
@@ -34,26 +34,19 @@ const firstName = randFirstName();
|
||||
const lastName = randLastName();
|
||||
|
||||
describe('Default owner', () => {
|
||||
before(() => {
|
||||
cy.resetAll();
|
||||
});
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
it('should skip owner setup', () => {
|
||||
cy.skipSetup();
|
||||
});
|
||||
|
||||
it('should be able to create workflows', () => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
cy.visit('/');
|
||||
workflowsPage.getters.newWorkflowButtonCard().should('be.visible');
|
||||
workflowsPage.getters.newWorkflowButtonCard().click();
|
||||
|
||||
cy.waitForLoad();
|
||||
cy.createFixtureWorkflow('Test_workflow_1.json', `Test workflow`);
|
||||
|
||||
// reload page, ensure owner still has access
|
||||
cy.reload();
|
||||
|
||||
cy.waitForLoad();
|
||||
workflowPage.getters.workflowNameInput().should('contain.value', 'Test workflow');
|
||||
});
|
||||
|
||||
@@ -82,6 +75,7 @@ describe('Default owner', () => {
|
||||
});
|
||||
|
||||
it('should be able to setup UM from settings', () => {
|
||||
cy.visit('/');
|
||||
mainSidebar.getters.settings().should('be.visible');
|
||||
mainSidebar.actions.goToSettings();
|
||||
cy.url().should('include', settingsUsagePage.url);
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import { NodeCreator } from '../pages/features/node-creator';
|
||||
import { DEFAULT_USER_EMAIL, DEFAULT_USER_PASSWORD } from '../constants';
|
||||
import { randFirstName, randLastName } from '@ngneat/falso';
|
||||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||
import { NDV } from '../pages/ndv';
|
||||
|
||||
const email = DEFAULT_USER_EMAIL;
|
||||
const password = DEFAULT_USER_PASSWORD;
|
||||
const firstName = randFirstName();
|
||||
const lastName = randLastName();
|
||||
const nodeCreatorFeature = new NodeCreator();
|
||||
const WorkflowPage = new WorkflowPageClass();
|
||||
const NDVModal = new NDV();
|
||||
@@ -15,12 +9,10 @@ const NDVModal = new NDV();
|
||||
describe('Node Creator', () => {
|
||||
before(() => {
|
||||
cy.resetAll();
|
||||
cy.setup({ email, firstName, lastName, password });
|
||||
cy.skipSetup();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.signin({ email, password });
|
||||
|
||||
cy.visit(nodeCreatorFeature.url);
|
||||
cy.waitForLoad();
|
||||
});
|
||||
@@ -105,58 +97,52 @@ describe('Node Creator', () => {
|
||||
it('should search through actions and confirm added action', () => {
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('ftp');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').realPress('{rightarrow}');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').type('{rightarrow}');
|
||||
nodeCreatorFeature.getters.activeSubcategory().should('have.text', 'FTP');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('file');
|
||||
// Navigate to rename action which should be the 4th item
|
||||
nodeCreatorFeature.getters.searchBar().find('input').realPress('{downarrow}');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').realPress('{downarrow}');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').realPress('{downarrow}');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').realPress('{rightarrow}');
|
||||
nodeCreatorFeature.getters.searchBar().find('input').type('{downarrow} {downarrow} {downarrow} {rightarrow}');
|
||||
NDVModal.getters.parameterInput('operation').should('contain.text', 'Rename');
|
||||
})
|
||||
|
||||
it('should render and select community node', () => {
|
||||
cy.intercept('GET', '/types/nodes.json').as('nodesIntercept');
|
||||
cy.wait('@nodesIntercept').then(() => {
|
||||
const customNode = 'E2E Node';
|
||||
const customNode = 'E2E Node';
|
||||
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type(customNode);
|
||||
nodeCreatorFeature.actions.openNodeCreator();
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type(customNode);
|
||||
|
||||
nodeCreatorFeature.getters
|
||||
.getCreatorItem(customNode)
|
||||
.findChildByTestId('node-creator-item-tooltip')
|
||||
.should('exist');
|
||||
nodeCreatorFeature.actions.selectNode(customNode);
|
||||
nodeCreatorFeature.getters
|
||||
.getCreatorItem(customNode)
|
||||
.findChildByTestId('node-creator-item-tooltip')
|
||||
.should('exist');
|
||||
nodeCreatorFeature.actions.selectNode(customNode);
|
||||
|
||||
// TODO: Replace once we have canvas feature utils
|
||||
cy.get('.data-display .node-name').contains(customNode).should('exist');
|
||||
// TODO: Replace once we have canvas feature utils
|
||||
cy.get('.data-display .node-name').contains(customNode).should('exist');
|
||||
|
||||
const nodeParameters = () => cy.getByTestId('node-parameters');
|
||||
const firstParameter = () => nodeParameters().find('.parameter-item').eq(0);
|
||||
const secondParameter = () => nodeParameters().find('.parameter-item').eq(1);
|
||||
const nodeParameters = () => cy.getByTestId('node-parameters');
|
||||
const firstParameter = () => nodeParameters().find('.parameter-item').eq(0);
|
||||
const secondParameter = () => nodeParameters().find('.parameter-item').eq(1);
|
||||
|
||||
// Check correct fields are rendered
|
||||
nodeParameters().should('exist');
|
||||
// Test property text input
|
||||
firstParameter().contains('Test property').should('exist');
|
||||
firstParameter().find('input.el-input__inner').should('have.value', 'Some default');
|
||||
// Resource select input
|
||||
secondParameter().find('label').contains('Resource').should('exist');
|
||||
secondParameter().find('input.el-input__inner').should('have.value', 'option2');
|
||||
secondParameter().find('.el-select').click();
|
||||
secondParameter().find('.el-select-dropdown__list').should('exist');
|
||||
// Check if all options are rendered and select the fourth one
|
||||
secondParameter().find('.el-select-dropdown__list').children().should('have.length', 4);
|
||||
secondParameter()
|
||||
.find('.el-select-dropdown__list')
|
||||
.children()
|
||||
.eq(3)
|
||||
.contains('option4')
|
||||
.should('exist')
|
||||
.click();
|
||||
secondParameter().find('input.el-input__inner').should('have.value', 'option4');
|
||||
});
|
||||
// Check correct fields are rendered
|
||||
nodeParameters().should('exist');
|
||||
// Test property text input
|
||||
firstParameter().contains('Test property').should('exist');
|
||||
firstParameter().find('input.el-input__inner').should('have.value', 'Some default');
|
||||
// Resource select input
|
||||
secondParameter().find('label').contains('Resource').should('exist');
|
||||
secondParameter().find('input.el-input__inner').should('have.value', 'option2');
|
||||
secondParameter().find('.el-select').click();
|
||||
secondParameter().find('.el-select-dropdown__list').should('exist');
|
||||
// Check if all options are rendered and select the fourth one
|
||||
secondParameter().find('.el-select-dropdown__list').children().should('have.length', 4);
|
||||
secondParameter()
|
||||
.find('.el-select-dropdown__list')
|
||||
.children()
|
||||
.eq(3)
|
||||
.contains('option4')
|
||||
.should('exist')
|
||||
.click();
|
||||
secondParameter().find('input.el-input__inner').should('have.value', 'option4');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import { WorkflowsPage, WorkflowPage, NDV } from '../pages';
|
||||
import { WorkflowPage, NDV } from '../pages';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
const workflowsPage = new WorkflowsPage();
|
||||
const workflowPage = new WorkflowPage();
|
||||
const ndv = new NDV();
|
||||
|
||||
describe('NDV', () => {
|
||||
before(() => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
workflowsPage.actions.createWorkflowFromCard();
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
cy.visit(workflowPage.url)
|
||||
cy.waitForLoad();
|
||||
workflowPage.actions.renameWorkflow(uuid());
|
||||
workflowPage.actions.saveWorkflowOnButtonClick();
|
||||
});
|
||||
|
||||
it('should show up when double clicked on a node and close when Back to canvas clicked', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas('Manual');
|
||||
workflowPage.getters.canvasNodes().first().dblclick();
|
||||
@@ -52,11 +49,12 @@ describe('NDV', () => {
|
||||
workflowPage.getters.canvasNodes().last().dblclick();
|
||||
ndv.getters.inputSelect().click();
|
||||
ndv.getters.inputOption().last().click();
|
||||
ndv.getters.inputDataContainer().find('[class*=schema_]').should('exist')
|
||||
ndv.getters.inputDataContainer().should('contain', 'start');
|
||||
});
|
||||
|
||||
it('should show correct validation state for resource locator params', () => {
|
||||
workflowPage.actions.addNodeToCanvas('Typeform', true, false);
|
||||
workflowPage.actions.addNodeToCanvas('Typeform', true, true);
|
||||
ndv.getters.container().should('be.visible');
|
||||
cy.get('.has-issues').should('have.length', 0);
|
||||
cy.get('[class*=hasIssues]').should('have.length', 0);
|
||||
|
||||
@@ -112,6 +112,9 @@ describe('Workflow Actions', () => {
|
||||
});
|
||||
|
||||
it('should update workflow settings', () => {
|
||||
cy.resetAll();
|
||||
cy.skipSetup();
|
||||
WorkflowPage.actions.visit();
|
||||
// Open settings dialog
|
||||
WorkflowPage.actions.saveWorkflowOnButtonClick();
|
||||
WorkflowPage.getters.workflowMenu().should('be.visible');
|
||||
|
||||
Reference in New Issue
Block a user