Browse Source

test: CY basic tests for Kanban

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>
pull/3818/head
Raju Udava 2 years ago
parent
commit
f44e6d2e1e
  1. 13
      packages/nc-gui/components/smartsheet-toolbar/KanbanStackEditOrAdd.vue
  2. 6
      packages/nc-gui/components/smartsheet-toolbar/StackedBy.vue
  3. 248
      scripts/cypress/integration/common/4g_kanban.js
  4. 21
      scripts/cypress/integration/test/restViews.js
  5. 74
      scripts/cypress/support/commands.js
  6. 23
      scripts/cypress/support/page_objects/mainPage.js

13
packages/nc-gui/components/smartsheet-toolbar/KanbanStackEditOrAdd.vue

@ -23,9 +23,18 @@ provide(IsKanbanInj, ref(true))
</script>
<template>
<a-dropdown v-if="isUIAllowed('edit-column')" v-model:visible="addOrEditStackDropdown" :trigger="['click']">
<a-dropdown
v-if="isUIAllowed('edit-column')"
v-model:visible="addOrEditStackDropdown"
:trigger="['click']"
overlay-class-name="nc-dropdown-kanban-add-edit-stack-menu"
>
<div class="nc-kanban-btn">
<a-button v-e="['c:kanban-stack-edit-or-add']" class="nc-fields-menu-btn nc-toolbar-btn" :disabled="isLocked">
<a-button
v-e="['c:kanban-stack-edit-or-add']"
class="nc-kanban-add-edit-stack-menu-btn nc-toolbar-btn"
:disabled="isLocked"
>
<div class="flex items-center gap-1">
<mdi-plus-circle-outline />
<span class="text-capitalize !text-sm font-weight-normal">

6
packages/nc-gui/components/smartsheet-toolbar/StackedBy.vue

@ -70,9 +70,9 @@ const handleChange = () => {
</script>
<template>
<a-dropdown v-model:visible="stackedByDropdown" :trigger="['click']">
<a-dropdown v-model:visible="stackedByDropdown" :trigger="['click']" overlay-class-name="nc-dropdown-kanban-stacked-by-menu">
<div class="nc-kanban-btn">
<a-button v-e="['c:stacked-by']" class="nc-fields-menu-btn nc-toolbar-btn" :disabled="isLocked">
<a-button v-e="['c:stacked-by']" class="nc-kanban-stacked-by-menu-btn nc-toolbar-btn" :disabled="isLocked">
<div class="flex items-center gap-1">
<mdi-arrow-down-drop-circle-outline />
<!-- TODO: i18n -->
@ -97,7 +97,7 @@ const handleChange = () => {
<div class="grouping-field">
<a-select
v-model:value="groupingFieldColumnId"
class="w-full"
class="w-full nc-kanban-grouping-field-select"
:options="singleSelectFieldOptions"
placeholder="Select a Grouping Field"
@change="handleChange"

248
scripts/cypress/integration/common/4g_kanban.js

@ -0,0 +1,248 @@
import { mainPage } from "../../support/page_objects/mainPage";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import {loginPage} from "../../support/page_objects/navigation";
// kanban grouping field configuration
//
function configureGroupingField(field, closeMenu = true) {
cy.get(".nc-kanban-stacked-by-menu-btn").click();
cy.getActiveMenu('.nc-dropdown-kanban-stacked-by-menu')
.should('exist')
.find('.nc-kanban-grouping-field-select')
.click();
cy.get('.ant-select-dropdown:visible')
.should('exist')
.find(`.ant-select-item`)
.contains(new RegExp("^" + field + "$", "g"))
.should('exist')
.click();
if (closeMenu) {
cy.get('.nc-kanban-stacked-by-menu-btn').click();
}
cy.get('.nc-kanban-stacked-by-menu-btn')
.contains(`Stacked By ${field}`)
.should('exist');
}
// number of kanban stacks altogether
//
function verifyKanbanStackCount(count) {
cy.get('.nc-kanban-stack').should('have.length', count);
}
// order of kanban stacks
//
function verifyKanbanStackOrder(order) {
cy.get('.nc-kanban-stack').each(($el, index) => {
cy.wrap($el).should('contain', order[index]);
});
}
// kanban stack footer numbers
//
function verifyKanbanStackFooterCount(count) {
cy.get('.nc-kanban-stack').each(($el, index) => {
cy.wrap($el).find('.nc-kanban-data-count').should('contain', `${count[index]} records`);
});
}
// kanban card count in a stack
//
function verifyKanbanStackCardCount(count) {
cy.get('.nc-kanban-stack').each(($el, index) => {
if(count[index] > 0) {
cy.wrap($el).find('.nc-kanban-item').should('exist').should('have.length', count[index]);
}
});
}
// order of cards within a stack
//
function verifyKanbanStackCardOrder(order, stackIndex, cardIndex) {
cy.get('.nc-kanban-stack').eq(stackIndex).find('.nc-kanban-item').eq(cardIndex).should('contain', order);
}
// drag drop kanban card
//
function dragAndDropKanbanCard(srcCard, dstCard) {
cy.get(`.nc-kanban-item :contains("${srcCard}")`).drag(`.nc-kanban-item :contains("${dstCard}")`);
}
// drag drop kanban stack
//
function dragAndDropKanbanStack(srcStack, dstStack) {
cy.get(`.nc-kanban-stack-head :contains("${srcStack}")`).drag(`.nc-kanban-stack-head :contains("${dstStack}")`);
}
// test suite
//
export const genTest = (apiType, dbType) => {
if (!isTestSuiteActive(apiType, dbType)) return;
describe(`${apiType.toUpperCase()} api - Kanban`, () => {
before(() => {
// for standalone tests
// cy.restoreLocalStorage();
// loginPage.loginAndOpenProject(apiType, dbType);
});
beforeEach(() => {
cy.restoreLocalStorage();
});
afterEach(() => {
cy.saveLocalStorage();
});
after(() => {
});
// class name specific to kanban
// .nc-kanban-stacked-by-menu-btn
// .nc-dropdown-kanban-stacked-by-menu
// .nc-kanban-add-edit-stack-menu-btn
// .nc-dropdown-kanban-add-edit-stack-menu
// .nc-kanban-grouping-field-select
//
it("Create Kanban view", () => {
cy.openTableTab("Film", 25);
cy.viewCreate("kanban");
});
it("Rename Kanban view", () => {
cy.viewRename("kanban", 0, "Film Kanban");
})
it("Configure grouping field", () => {
configureGroupingField("Rating");
})
it("Verify kanban stacks", () => {
verifyKanbanStackCount(6);
verifyKanbanStackOrder(["Uncategorized", "G", "PG", "PG-13", "R", "NC-17"]);
verifyKanbanStackFooterCount(["0", "178", "194", "223", "195", "210"]);
verifyKanbanStackCardCount([0, 25, 25, 25, 25, 25]);
})
it("Hide fields", () => {
mainPage.hideAllColumns();
mainPage.unhideField("Title", 'kanban');
verifyKanbanStackCardCount([0, 25, 25, 25, 25, 25]);
})
it("Verify card order", () => {
// verify 3 cards from each stack
verifyKanbanStackCardOrder("ACE GOLDFINGER", 1, 0);
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 1);
verifyKanbanStackCardOrder("AFRICAN EGG", 1, 2);
verifyKanbanStackCardOrder("ACADEMY DINOSAUR", 2, 0);
verifyKanbanStackCardOrder("AGENT TRUMAN", 2, 1);
verifyKanbanStackCardOrder("ALASKA PHANTOM", 2, 2);
verifyKanbanStackCardOrder("AIRPLANE SIERRA", 3, 0);
verifyKanbanStackCardOrder("ALABAMA DEVIL", 3, 1);
verifyKanbanStackCardOrder("ALTER VICTORY", 3, 2);
verifyKanbanStackCardOrder("AIRPORT POLLOCK", 4, 0);
verifyKanbanStackCardOrder("ALONE TRIP", 4, 1);
verifyKanbanStackCardOrder("AMELIE HELLFIGHTERS", 4, 2);
verifyKanbanStackCardOrder("ADAPTATION HOLES", 5, 0);
verifyKanbanStackCardOrder("ALADDIN CALENDAR", 5, 1);
verifyKanbanStackCardOrder("ALICE FANTASIA", 5, 2);
})
it("Verify inter-stack drag and drop", () => {
dragAndDropKanbanCard("ACE GOLDFINGER", "ACADEMY DINOSAUR");
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 0);
verifyKanbanStackCardOrder("ACE GOLDFINGER", 2, 0);
verifyKanbanStackCardOrder("ACADEMY DINOSAUR", 2, 1);
dragAndDropKanbanCard("ACE GOLDFINGER", "AFFAIR PREJUDICE");
verifyKanbanStackCardOrder("ACE GOLDFINGER", 1, 0);
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 1);
verifyKanbanStackCardOrder("ACADEMY DINOSAUR", 2, 0);
})
it("Verify intra-stack drag and drop", () => {
dragAndDropKanbanCard("ACE GOLDFINGER", "AFFAIR PREJUDICE");
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 0);
verifyKanbanStackCardOrder("ACE GOLDFINGER", 1, 1);
dragAndDropKanbanCard("ACE GOLDFINGER", "AFFAIR PREJUDICE");
verifyKanbanStackCardOrder("ACE GOLDFINGER", 1, 0);
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 1);
})
it("Verify stack drag drop", () => {
verifyKanbanStackOrder(["Uncategorized", "G", "PG", "PG-13", "R", "NC-17"]);
dragAndDropKanbanStack("PG-13", "R");
verifyKanbanStackOrder(["Uncategorized", "G", "PG", "R", "PG-13", "NC-17"]);
dragAndDropKanbanStack("PG-13", "R");
verifyKanbanStackOrder(["Uncategorized", "G", "PG", "PG-13", "R", "NC-17"]);
})
it("Verify Sort", () => {
mainPage.sortField("Title", "Z → A");
verifyKanbanStackCardOrder("YOUNG LANGUAGE", 1, 0);
verifyKanbanStackCardOrder("WEST LION", 1, 1);
verifyKanbanStackCardOrder("WORST BANGER", 2, 0);
verifyKanbanStackCardOrder("WORDS HUNTER", 2, 1);
mainPage.clearSort();
verifyKanbanStackCardOrder("ACE GOLDFINGER", 1, 0);
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 1);
verifyKanbanStackCardOrder("ACADEMY DINOSAUR", 2, 0);
verifyKanbanStackCardOrder("AGENT TRUMAN", 2, 1);
})
it("Verify Filter", () => {
mainPage.filterField("Title", "is like", "BA");
verifyKanbanStackCardOrder("BAKED CLEOPATRA", 1, 0);
verifyKanbanStackCardOrder("BALLROOM MOCKINGBIRD", 1, 1);
verifyKanbanStackCardOrder("ARIZONA BANG", 2, 0);
verifyKanbanStackCardOrder("EGYPT TENENBAUMS", 2, 1);
mainPage.filterReset();
verifyKanbanStackCardOrder("ACE GOLDFINGER", 1, 0);
verifyKanbanStackCardOrder("AFFAIR PREJUDICE", 1, 1);
verifyKanbanStackCardOrder("ACADEMY DINOSAUR", 2, 0);
verifyKanbanStackCardOrder("AGENT TRUMAN", 2, 1);
})
it("Delete Kanban view", () => {
cy.viewDelete(0);
cy.closeTableTab("Film");
});
});
};
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Pranav C Balan <pranavxc@gmail.com>
* @author Raju Udava <sivadstala@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

21
scripts/cypress/integration/test/restViews.js

@ -6,21 +6,24 @@ let t4c = require("../common/4c_form_view_detailed");
let t4d = require("../common/4d_table_view_grid_locked");
let t4e = require("../common/4e_form_view_share");
let t4f = require("../common/4f_grid_view_share");
let t4g = require("../common/4g_kanban");
const {
setCurrentMode,
} = require("../../support/page_objects/projectConstants");
const nocoTestSuite = (apiType, dbType) => {
setCurrentMode(apiType, dbType);
t01.genTest(apiType, dbType);
// place plugin related activities at top
t4c.genTest(apiType, dbType);
t4a.genTest(apiType, dbType);
t4b.genTest(apiType, dbType);
t4d.genTest(apiType, dbType);
t4e.genTest(apiType, dbType);
t4f.genTest(apiType, dbType);
// t01.genTest(apiType, dbType);
//
// // place plugin related activities at top
// t4c.genTest(apiType, dbType);
// t4a.genTest(apiType, dbType);
// t4b.genTest(apiType, dbType);
// t4d.genTest(apiType, dbType);
// t4e.genTest(apiType, dbType);
// t4f.genTest(apiType, dbType);
t4g.genTest(apiType, dbType);
};
nocoTestSuite("rest", "mysql");

74
scripts/cypress/support/commands.js

@ -482,6 +482,80 @@ Cypress.Commands.add('signOut', () => {
});
// View basic routines
//
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
// viewCreate
// : viewType: grid, gallery, kanban, form
// : creates view with default name
//
Cypress.Commands.add('viewCreate', (viewType) => {
// click on 'Grid/Gallery/Form/Kanban' button on Views bar
cy.get(`.nc-create-${viewType}-view`).click();
// Pop up window, click Submit (accepting default name for view)
cy.getActiveModal(".nc-modal-view-create")
.find(".ant-btn-primary").click();
cy.toastWait("View created successfully");
// validate if view was created && contains default name 'Country1'
cy.get(`.nc-${viewType}-view-item`)
.contains(`${capitalizeFirstLetter(viewType)}-1`)
.should("exist");
})
// viewDelete
// : delete view by index (0-based, exclude default view)
//
Cypress.Commands.add('viewDelete', (viewIndex) => {
// click on delete icon (becomes visible on hovering mouse)
cy.get(".nc-view-delete-icon")
.eq(viewIndex)
.click({ force: true });
cy.wait(300)
// click on 'Delete' button on confirmation modal
cy.getActiveModal(".nc-modal-view-delete")
.find('.ant-btn-dangerous')
.click();
cy.toastWait("View deleted successfully");
})
// viewRename
// : rename view by index (0-based, exclude default view)
//
Cypress.Commands.add('viewRename', (viewType, viewIndex, newName) => {
// click on edit-icon (becomes visible on hovering mouse)
cy.get(`.nc-${viewType}-view-item`).eq(viewIndex).dblclick();
// feed new name
cy.get(`.nc-${viewType}-view-item input`)
.clear()
.type(`${newName}{enter}`);
cy.toastWait("View renamed successfully");
// validate
cy.get(`.nc-${viewType}-view-item`)
.contains(`${newName}`)
.should("exist");
})
// openTableView
// : open view by type & name
//
Cypress.Commands.add('openTableView', (viewType, viewName) => {
cy.get(`.nc-${viewType}-view-item`)
.contains(`${viewName}`)
.click();
})
// Drag n Drop
// refer: https://stackoverflow.com/a/55409853
/*

23
scripts/cypress/support/page_objects/mainPage.js

@ -288,6 +288,18 @@ export class _mainPage {
return cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-item').contains('Webhooks');
};
hideAllColumns = () => {
cy.get(".nc-fields-menu-btn").should('exist').click();
cy.getActiveMenu(".nc-dropdown-fields-menu").find('.ant-btn').contains('Hide all').click();
cy.get(".nc-fields-menu-btn").should('exist').click();
}
showAllColumns = () => {
cy.get(".nc-fields-menu-btn").should('exist').click();
cy.getActiveMenu(".nc-dropdown-fields-menu").find('.ant-btn').contains('Show all').click();
cy.get(".nc-fields-menu-btn").should('exist').click();
}
hideField = (field) => {
cy.get(`th[data-title="${field}"]`).should("be.visible");
cy.get(".nc-fields-menu-btn").click();
@ -299,15 +311,20 @@ export class _mainPage {
cy.get(`th[data-title="${field}"]`).should("not.exist");
};
unhideField = (field) => {
cy.get(`th[data-title="${field}"]`).should("not.exist");
unhideField = (field, viewType = 'grid') => {
if(viewType === 'grid') {
cy.get(`th[data-title="${field}"]`).should("not.exist");
}
cy.get(".nc-fields-menu-btn").click();
cy.wait(500)
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`.nc-fields-list label:contains(${field}):visible`).click();
cy.wait(500)
cy.get(".nc-fields-menu-btn").click();
cy.wait(500)
cy.get(`th[data-title="${field}"]`).should("be.visible");
if(viewType === 'grid') {
cy.get(`th[data-title="${field}"]`).should("be.visible");
}
};
sortField = (field, criteria) => {

Loading…
Cancel
Save