feat: Add variables e2e tests (no-changelog) (#6027)

* fix: fix n8n-checkbox alignment

* fix: use css variables in checkbox inner margin-top

* test: update snapshots

* feat: add variables e2e tests (no-changelog)

* test: update snapshot
This commit is contained in:
Alex Grozav 2023-04-20 15:08:13 +03:00 committed by GitHub
parent 9b59f1df9c
commit 723f81bab0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 201 additions and 4 deletions

View file

@ -0,0 +1,126 @@
import { VariablesPage } from '../pages/variables';
import { DEFAULT_USER_EMAIL, DEFAULT_USER_PASSWORD } from '../constants';
import { randFirstName, randLastName } from '@ngneat/falso';
const variablesPage = new VariablesPage();
const email = DEFAULT_USER_EMAIL;
const password = DEFAULT_USER_PASSWORD;
const firstName = randFirstName();
const lastName = randLastName();
describe('Variables', () => {
before(() => {
cy.resetAll();
cy.setup({ email, firstName, lastName, password });
});
it('should show the unlicensed action box when the feature is disabled', () => {
cy.signin({ email, password });
cy.visit(variablesPage.url);
variablesPage.getters.unavailableResourcesList().should('be.visible');
variablesPage.getters.resourcesList().should('not.exist');
});
describe('licensed', () => {
before(() => {
cy.enableFeature('feat:variables');
});
beforeEach(() => {
cy.signin({ email, password });
cy.visit(variablesPage.url);
});
it('should show the licensed action box when the feature is enabled', () => {
variablesPage.getters.emptyResourcesList().should('be.visible');
variablesPage.getters.createVariableButton().should('be.visible');
});
it('should create a new variable using empty state row', () => {
const key = 'ENV_VAR';
const value = 'value';
variablesPage.actions.createVariableFromEmptyState(key, value);
variablesPage.getters.variableRow(key).should('contain', value).should('be.visible');
variablesPage.getters.variablesRows().should('have.length', 1);
});
it('should create a new variable using pre-existing state', () => {
const key = 'ENV_VAR_NEW';
const value = 'value2';
variablesPage.actions.createVariable(key, value);
variablesPage.getters.variableRow(key).should('contain', value).should('be.visible');
variablesPage.getters.variablesRows().should('have.length', 2);
const otherKey = 'ENV_EXAMPLE';
const otherValue = 'value3';
variablesPage.actions.createVariable(otherKey, otherValue);
variablesPage.getters
.variableRow(otherKey)
.should('contain', otherValue)
.should('be.visible');
variablesPage.getters.variablesRows().should('have.length', 3);
});
it('should get validation errors and cancel variable creation', () => {
const key = 'ENV_VAR_NEW$';
const value = 'value3';
variablesPage.getters.createVariableButton().click();
const editingRow = variablesPage.getters.variablesEditableRows().eq(0);
variablesPage.actions.setRowValue(editingRow, 'key', key);
variablesPage.actions.setRowValue(editingRow, 'value', value);
editingRow.should('contain', 'This field may contain only letters');
variablesPage.getters.editableRowSaveButton(editingRow).should('be.disabled');
variablesPage.actions.cancelRowEditing(editingRow);
variablesPage.getters.variablesRows().should('have.length', 3);
});
it('should edit a variable', () => {
const key = 'ENV_VAR_NEW';
const newValue = 'value4';
variablesPage.actions.editRow(key);
const editingRow = variablesPage.getters.variablesEditableRows().eq(0);
variablesPage.actions.setRowValue(editingRow, 'value', newValue);
variablesPage.actions.saveRowEditing(editingRow);
variablesPage.getters.variableRow(key).should('contain', newValue).should('be.visible');
variablesPage.getters.variablesRows().should('have.length', 3);
});
it('should delete a variable', () => {
const key = 'TO_DELETE';
const value = 'xxx';
variablesPage.actions.createVariable(key, value);
variablesPage.actions.deleteVariable(key);
});
it('should search for a variable', () => {
// One Result
variablesPage.getters.searchBar().type('NEW');
variablesPage.getters.variablesRows().should('have.length', 1);
variablesPage.getters.variableRow('NEW').should('contain.text', 'ENV_VAR_NEW');
// Multiple Results
variablesPage.getters.searchBar().clear().type('ENV_VAR');
variablesPage.getters.variablesRows().should('have.length', 2);
// All Results
variablesPage.getters.searchBar().clear().type('ENV');
variablesPage.getters.variablesRows().should('have.length', 3);
// No Results
variablesPage.getters.searchBar().clear().type('Some non-existent variable');
variablesPage.getters.variablesRows().should('not.exist');
cy.contains('No variables found').should('be.visible');
});
});
});

View file

@ -0,0 +1,71 @@
import { BasePage } from './base';
import Chainable = Cypress.Chainable;
export class VariablesPage extends BasePage {
url = '/variables';
getters = {
unavailableResourcesList: () => cy.getByTestId('unavailable-resources-list'),
emptyResourcesList: () => cy.getByTestId('empty-resources-list'),
resourcesList: () => cy.getByTestId('resources-list'),
goToUpgrade: () => cy.getByTestId('go-to-upgrade'),
actionBox: () => cy.getByTestId('action-box'),
emptyResourcesListNewVariableButton: () => this.getters.emptyResourcesList().find('button'),
searchBar: () => cy.getByTestId('resources-list-search').find('input'),
createVariableButton: () => cy.getByTestId('resources-list-add'),
variablesRows: () => cy.getByTestId('variables-row'),
variablesEditableRows: () =>
cy.getByTestId('variables-row').filter((index, row) => !!row.querySelector('input')),
variableRow: (key: string) =>
this.getters.variablesRows().contains(key).parents('[data-test-id="variables-row"]'),
editableRowCancelButton: (row: Chainable<JQuery<HTMLElement>>) =>
row.getByTestId('variable-row-cancel-button'),
editableRowSaveButton: (row: Chainable<JQuery<HTMLElement>>) =>
row.getByTestId('variable-row-save-button'),
};
actions = {
createVariable: (key: string, value: string) => {
this.getters.createVariableButton().click();
const editingRow = this.getters.variablesEditableRows().eq(0);
this.actions.setRowValue(editingRow, 'key', key);
this.actions.setRowValue(editingRow, 'value', value);
this.actions.saveRowEditing(editingRow);
},
deleteVariable: (key: string) => {
const row = this.getters.variableRow(key);
row.within(() => {
cy.getByTestId('variable-row-delete-button').click();
});
const modal = cy.get('[role="dialog"]');
modal.should('be.visible');
modal.get('.btn--confirm').click();
},
createVariableFromEmptyState: (key: string, value: string) => {
this.getters.emptyResourcesListNewVariableButton().click();
const editingRow = this.getters.variablesEditableRows().eq(0);
this.actions.setRowValue(editingRow, 'key', key);
this.actions.setRowValue(editingRow, 'value', value);
this.actions.saveRowEditing(editingRow);
},
editRow: (key: string) => {
const row = this.getters.variableRow(key);
row.within(() => {
cy.getByTestId('variable-row-edit-button').click();
});
},
setRowValue: (row: Chainable<JQuery<HTMLElement>>, field: 'key' | 'value', value: string) => {
row.within(() => {
cy.getByTestId(`variable-row-${field}-input`).type('{selectAll}{del}').type(value);
});
},
cancelRowEditing: (row: Chainable<JQuery<HTMLElement>>) => {
this.getters.editableRowCancelButton(row).click();
},
saveRowEditing: (row: Chainable<JQuery<HTMLElement>>) => {
this.getters.editableRowSaveButton(row).click();
},
};
}

View file

@ -130,7 +130,7 @@ function focusFirstInput() {
</script> </script>
<template> <template>
<tr :class="$style.variablesRow"> <tr :class="$style.variablesRow" data-test-id="variables-row">
<td class="variables-key-column"> <td class="variables-key-column">
<div> <div>
<span v-if="!editing">{{ data.key }}</span> <span v-if="!editing">{{ data.key }}</span>

View file

@ -1,7 +1,7 @@
// Vitest Snapshot v1 // Vitest Snapshot v1
exports[`VariablesRow > should render correctly 1`] = ` exports[`VariablesRow > should render correctly 1`] = `
"<tr class=\\"variablesRow\\"> "<tr data-test-id=\\"variables-row\\" class=\\"variablesRow\\">
<td class=\\"variables-key-column\\"> <td class=\\"variables-key-column\\">
<div><span>key</span></div> <div><span>key</span></div>
</td> </td>
@ -29,7 +29,7 @@ exports[`VariablesRow > should render correctly 1`] = `
`; `;
exports[`VariablesRow > should show key and value inputs in edit mode 1`] = ` exports[`VariablesRow > should show key and value inputs in edit mode 1`] = `
"<tr class=\\"variablesRow\\"> "<tr data-test-id=\\"variables-row\\" class=\\"variablesRow\\">
<td class=\\"variables-key-column\\"> <td class=\\"variables-key-column\\">
<div> <div>
<div class=\\"container\\" data-test-id=\\"variable-row-key-input\\"> <div class=\\"container\\" data-test-id=\\"variable-row-key-input\\">

View file

@ -259,7 +259,7 @@ function displayName(resource: EnvironmentVariable) {
</template> </template>
<template v-if="!isFeatureEnabled" #empty> <template v-if="!isFeatureEnabled" #empty>
<n8n-action-box <n8n-action-box
data-test-id="empty-resources-list" data-test-id="unavailable-resources-list"
emoji="👋" emoji="👋"
:heading="$locale.baseText(contextBasedTranslationKeys.variables.unavailable.title)" :heading="$locale.baseText(contextBasedTranslationKeys.variables.unavailable.title)"
:description=" :description="