Browse Source

chore: code formatting corrections applied (prettier)

Signed-off-by: Raju Udava <sivadstala@gmail.com>
pull/865/head
Raju Udava 3 years ago
parent
commit
4ef9a6bcad
  1. 128
      scripts/cypress/integration/common/1a_table_operations.js
  2. 163
      scripts/cypress/integration/common/1b_table_column_operations.js
  3. 72
      scripts/cypress/integration/common/2a_table_with_belongs_to_colulmn.js
  4. 106
      scripts/cypress/integration/common/2b_table_with_m2m_column.js
  5. 259
      scripts/cypress/integration/common/3a_filter_sort_fields_operations.js
  6. 395
      scripts/cypress/integration/common/3b_formula_column.js
  7. 171
      scripts/cypress/integration/common/3c_lookup_column.js
  8. 138
      scripts/cypress/integration/common/3d_rollup_column.js
  9. 72
      scripts/cypress/integration/common/4a_table_view_grid_gallery_form.js
  10. 184
      scripts/cypress/integration/common/4b_table_view_share.js
  11. 722
      scripts/cypress/integration/common/4c_form_view_detailed.js
  12. 135
      scripts/cypress/integration/common/4d_table_view_grid_locked.js
  13. 361
      scripts/cypress/integration/common/4e_form_view_share.js
  14. 757
      scripts/cypress/integration/common/4f_grid_view_share.js
  15. 313
      scripts/cypress/integration/common/5a_user_role.js
  16. 189
      scripts/cypress/integration/common/5b_preview_role.js
  17. 71
      scripts/cypress/integration/common/6b_downloadCsv.js
  18. 406
      scripts/cypress/integration/common/6c_swagger_api.js
  19. 118
      scripts/cypress/integration/common/6d_language_validation.js
  20. 89
      scripts/cypress/integration/common/6e_project_operations.js
  21. 137
      scripts/cypress/integration/common/6f_attachments.js
  22. 247
      scripts/cypress/integration/common/6g_base_share.js
  23. 539
      scripts/cypress/integration/common/7a_create_project_from_excel.js
  24. 324
      scripts/cypress/integration/spec/roleValidation.spec.js
  25. 35
      scripts/cypress/integration/test/explicitLogin.js
  26. 56
      scripts/cypress/integration/test/gqlMisc.js
  27. 34
      scripts/cypress/integration/test/gqlRoles.js
  28. 62
      scripts/cypress/integration/test/gqlTableOps.js
  29. 54
      scripts/cypress/integration/test/gqlViews.js
  30. 110
      scripts/cypress/integration/test/masterSuiteGql.js
  31. 110
      scripts/cypress/integration/test/masterSuiteRest.js
  32. 66
      scripts/cypress/integration/test/restMisc.js
  33. 34
      scripts/cypress/integration/test/restRoles.js
  34. 62
      scripts/cypress/integration/test/restTableOps.js
  35. 54
      scripts/cypress/integration/test/restViews.js
  36. 35
      scripts/cypress/plugins/index.js
  37. 34
      scripts/cypress/plugins/read-xlsx.js
  38. 341
      scripts/cypress/support/commands.js
  39. 17
      scripts/cypress/support/index.js
  40. 685
      scripts/cypress/support/page_objects/mainPage.js
  41. 524
      scripts/cypress/support/page_objects/navigation.js
  42. 198
      scripts/cypress/support/page_objects/projectConstants.js

128
scripts/cypress/integration/common/1a_table_operations.js

@ -1,98 +1,100 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
import { mainPage } from "../../support/page_objects/mainPage"; import { mainPage } from "../../support/page_objects/mainPage";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${xcdb ? 'Meta - ' : ''}${type.toUpperCase()} api - Table`, () => {
describe(`${xcdb ? "Meta - " : ""}${type.toUpperCase()} api - Table`, () => {
before(() => { before(() => {
cy.get('.mdi-close').click({ multiple: true }) cy.get(".mdi-close").click({ multiple: true });
}) });
after(() => { after(() => {
cy.get('.mdi-close').click({ multiple: true }) cy.get(".mdi-close").click({ multiple: true });
}) });
const name = 'tablex' const name = "tablex";
// create a new random table // create a new random table
it('Create Table', () => { it("Create Table", () => {
cy.createTable(name) cy.createTable(name);
}) });
// delete newly created table // delete newly created table
it('Delete Table', () => { it("Delete Table", () => {
cy.deleteTable(name) cy.deleteTable(name);
}) });
const getAuditCell = (row, col) => { const getAuditCell = (row, col) => {
return cy.get('table > tbody > tr').eq(row).find('td').eq(col) return cy.get("table > tbody > tr").eq(row).find("td").eq(col);
} };
it('Open Audit tab', ()=> { it("Open Audit tab", () => {
mainPage.navigationDraw(mainPage.AUDIT).click() mainPage.navigationDraw(mainPage.AUDIT).click();
// wait for column headers to appear // wait for column headers to appear
// //
cy.get('thead > tr > th.caption').should('have.length', 5) cy.get("thead > tr > th.caption").should("have.length", 5);
// Audit table entries // Audit table entries
// [Header] Operation Type, Operation Sub Type, Description, User, Created // [Header] Operation Type, Operation Sub Type, Description, User, Created
// [0] TABLE, DELETED, delete table table-x, user@nocodb.com, ... // [0] TABLE, DELETED, delete table table-x, user@nocodb.com, ...
// [1] TABLE, Created, created table table-x, user@nocodb.com, ... // [1] TABLE, Created, created table table-x, user@nocodb.com, ...
getAuditCell(0,0).contains('TABLE').should('exist') getAuditCell(0, 0).contains("TABLE").should("exist");
getAuditCell(0,1).contains('DELETED').should('exist') getAuditCell(0, 1).contains("DELETED").should("exist");
getAuditCell(0,3).contains('user@nocodb.com').should('exist') getAuditCell(0, 3).contains("user@nocodb.com").should("exist");
getAuditCell(1,0).contains('TABLE').should('exist') getAuditCell(1, 0).contains("TABLE").should("exist");
getAuditCell(1,1).contains('CREATED').should('exist') getAuditCell(1, 1).contains("CREATED").should("exist");
getAuditCell(1,3).contains('user@nocodb.com').should('exist') getAuditCell(1, 3).contains("user@nocodb.com").should("exist");
}) });
it('Table Rename operation', () => {
cy.renameTable('City', 'CityX') it("Table Rename operation", () => {
cy.renameTable("City", "CityX");
// verify // verify
// 1. Table name in project tree has changed // 1. Table name in project tree has changed
cy.get('.nc-project-tree') cy.get(".nc-project-tree").contains("CityX").should("exist");
.contains('CityX')
.should('exist')
// 2. Table tab name has changed // 2. Table tab name has changed
cy.get(`.project-tab:contains('CityX'):visible`) cy.get(`.project-tab:contains('CityX'):visible`).should("exist");
.should('exist')
// 3. contents of the table are valid // 3. contents of the table are valid
mainPage.getCell(`City`, 1) mainPage
.contains('A Corua (La Corua)') .getCell(`City`, 1)
.should('exist') .contains("A Corua (La Corua)")
.should("exist");
cy.closeTableTab('CityX')
cy.closeTableTab("CityX");
// 4. verify linked contents in other table // 4. verify linked contents in other table
// 4a. Address table, has many field // 4a. Address table, has many field
cy.openTableTab('Address', 25) cy.openTableTab("Address", 25);
mainPage.getCell('City <= Address', 1).scrollIntoView() mainPage.getCell("City <= Address", 1).scrollIntoView();
mainPage.getCell('City <= Address', 1).find('.name').contains('Lethbridge').should('exist') mainPage
cy.closeTableTab('Address') .getCell("City <= Address", 1)
.find(".name")
.contains("Lethbridge")
.should("exist");
cy.closeTableTab("Address");
// 4b. Country table, belongs to field // 4b. Country table, belongs to field
cy.openTableTab('Country', 25) cy.openTableTab("Country", 25);
mainPage.getCell('Country => City', 1).find('.name').contains('Kabul').should('exist') mainPage
cy.closeTableTab('Country') .getCell("Country => City", 1)
.find(".name")
.contains("Kabul")
.should("exist");
cy.closeTableTab("Country");
// revert re-name operation to not impact rest of test suite // revert re-name operation to not impact rest of test suite
cy.renameTable('CityX', 'City') cy.renameTable("CityX", "City");
}) });
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -115,4 +117,4 @@ export const genTest = (type, xcdb) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

163
scripts/cypress/integration/common/1b_table_column_operations.js

@ -1,121 +1,135 @@
import { mainPage } from "../../support/page_objects/mainPage";
import { mainPage } from "../../support/page_objects/mainPage" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Table Column`, () => { describe(`${type.toUpperCase()} api - Table Column`, () => {
const name = 'tablex' const name = "tablex";
const colName = 'column_name_a' const colName = "column_name_a";
const updatedColName = 'updated_column_name' const updatedColName = "updated_column_name";
const randVal = 'Test@1234.com' const randVal = "Test@1234.com";
const updatedRandVal = 'Updated@1234.com' const updatedRandVal = "Updated@1234.com";
before(() => { before(() => {
cy.createTable(name) cy.createTable(name);
}); });
// delete table // delete table
after(() => { after(() => {
cy.deleteTable(name) cy.deleteTable(name);
}); });
it('Create Table Column', () => { it("Create Table Column", () => {
cy.get(`.project-tab:contains(${name}):visible`).should('exist') cy.get(`.project-tab:contains(${name}):visible`).should("exist");
mainPage.addColumn(colName, name) mainPage.addColumn(colName, name);
cy.get(`th:contains(${colName})`).should('exist'); cy.get(`th:contains(${colName})`).should("exist");
}) });
// edit the newly created column // edit the newly created column
it('Edit table column - change datatype', () => { it("Edit table column - change datatype", () => {
cy.get(`th:contains(${colName}) .mdi-menu-down`) cy.get(`th:contains(${colName}) .mdi-menu-down`)
.trigger('mouseover', {force: true}) .trigger("mouseover", { force: true })
.click({force: true}) .click({ force: true });
cy.get('.nc-column-edit').click() cy.get(".nc-column-edit").click();
// change column type and verify // change column type and verify
cy.get('.nc-ui-dt-dropdown').click() cy.get(".nc-ui-dt-dropdown").click();
cy.contains('LongText').click() cy.contains("LongText").click();
cy.get('.nc-col-create-or-edit-card').contains('Save').click() cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.toastWait('Update table.tablex successful') cy.toastWait("Update table.tablex successful");
cy.get(`th[data-col="${colName}"] .mdi-text-subject`).should('exist') cy.get(`th[data-col="${colName}"] .mdi-text-subject`).should("exist");
cy.get(`th:contains(${colName}) .mdi-menu-down`) cy.get(`th:contains(${colName}) .mdi-menu-down`)
.trigger('mouseover', {force: true}) .trigger("mouseover", { force: true })
.click({force: true}) .click({ force: true });
cy.get('.nc-column-edit').click() cy.get(".nc-column-edit").click();
}) });
// edit the newly created column // edit the newly created column
it('Edit table column - rename', () => { it("Edit table column - rename", () => {
cy.get(`th:contains(${colName}) .mdi-menu-down`) cy.get(`th:contains(${colName}) .mdi-menu-down`)
.trigger('mouseover', {force: true}) .trigger("mouseover", { force: true })
.click({force: true}) .click({ force: true });
cy.get('.nc-column-edit').click() cy.get(".nc-column-edit").click();
// rename column and verify // rename column and verify
cy.get('.nc-column-name-input input').clear().type(updatedColName) cy.get(".nc-column-name-input input").clear().type(updatedColName);
cy.get('.nc-col-create-or-edit-card').contains('Save').click() cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.toastWait('Update table.tablex successful') cy.toastWait("Update table.tablex successful");
cy.get(`th:contains(${colName})`).should('not.exist') cy.get(`th:contains(${colName})`).should("not.exist");
cy.get(`th:contains(${updatedColName})`).should('exist') cy.get(`th:contains(${updatedColName})`).should("exist");
}) });
// delete the newly created column // delete the newly created column
it('Delete table column', () => { it("Delete table column", () => {
cy.get(`th:contains(${updatedColName})`).should('exist'); cy.get(`th:contains(${updatedColName})`).should("exist");
cy.get(`th:contains(${updatedColName}) .mdi-menu-down`) cy.get(`th:contains(${updatedColName}) .mdi-menu-down`)
.trigger('mouseover') .trigger("mouseover")
.click() .click();
cy.get('.nc-column-delete').click()
cy.get('button:contains(Confirm)').click()
cy.toastWait('Update table.tablex successful')
cy.get(`th:contains(${updatedColName})`).should('not.exist');
})
it('Add new row', () => { cy.get(".nc-column-delete").click();
cy.get('.nc-add-new-row-btn:visible').should('exist') cy.get("button:contains(Confirm)").click();
cy.get('.nc-add-new-row-btn').click({force: true}); cy.toastWait("Update table.tablex successful");
cy.get('#data-table-form-Title > input').first().type(randVal);
cy.getActiveModal().find('button').contains('Save Row').click({ force: true })
cy.toastWait('updated successfully') cy.get(`th:contains(${updatedColName})`).should("not.exist");
mainPage.getCell('Title', 1).contains(randVal).should('exist') });
})
it('Update row', () => { it("Add new row", () => {
mainPage.getRow(1).find('.nc-row-expand-icon').click({force: true}) cy.get(".nc-add-new-row-btn:visible").should("exist");
cy.get('#data-table-form-Title > input').first().clear().type(updatedRandVal); cy.get(".nc-add-new-row-btn").click({ force: true });
cy.getActiveModal().find('button').contains('Save Row').click({force: true}) cy.get("#data-table-form-Title > input").first().type(randVal);
cy.getActiveModal()
.find("button")
.contains("Save Row")
.click({ force: true });
cy.toastWait("updated successfully");
mainPage.getCell("Title", 1).contains(randVal).should("exist");
});
cy.toastWait('updated successfully') it("Update row", () => {
mainPage.getRow(1).find(".nc-row-expand-icon").click({ force: true });
mainPage.getCell('Title', 1).contains(randVal).should('not.exist') cy.get("#data-table-form-Title > input")
mainPage.getCell('Title', 1).contains(updatedRandVal).should('exist') .first()
}) .clear()
.type(updatedRandVal);
cy.getActiveModal()
.find("button")
.contains("Save Row")
.click({ force: true });
cy.toastWait("updated successfully");
mainPage.getCell("Title", 1).contains(randVal).should("not.exist");
mainPage.getCell("Title", 1).contains(updatedRandVal).should("exist");
});
it('Delete row', () => { it("Delete row", () => {
mainPage.getCell('Title', 1).contains(updatedRandVal).rightclick({ force: true }) mainPage
.getCell("Title", 1)
.contains(updatedRandVal)
.rightclick({ force: true });
// delete row // delete row
cy.getActiveMenu().find('.v-list-item:contains("Delete Row")').first().click({force: true}) cy.getActiveMenu()
.find('.v-list-item:contains("Delete Row")')
.first()
.click({ force: true });
// cy.toastWait('Deleted row successfully') // cy.toastWait('Deleted row successfully')
cy.get('td').contains(randVal).should('not.exist'); cy.get("td").contains(randVal).should("not.exist");
}) });
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -139,4 +153,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

72
scripts/cypress/integration/common/2a_table_with_belongs_to_colulmn.js

@ -1,49 +1,61 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Table: belongs to, link record`, () => { describe(`${type.toUpperCase()} api - Table: belongs to, link record`, () => {
before(() => { before(() => {
cy.openTableTab('Country', 25) cy.openTableTab("Country", 25);
});
})
after(() => { after(() => {
cy.closeTableTab('Country') cy.closeTableTab("Country");
}) });
it('Table column header, URL validation', () => { it("Table column header, URL validation", () => {
// column name validation // column name validation
cy.get(`.project-tab:contains(Country):visible`).should('exist') cy.get(`.project-tab:contains(Country):visible`).should("exist");
// URL validation // URL validation
cy.url().should('contain', `name=Country`) cy.url().should("contain", `name=Country`);
}) });
it('Expand belongs-to column', () => { it("Expand belongs-to column", () => {
// expand first row // expand first row
cy.get('td[data-col="Country => City"] div:visible', {timeout: 12000}).first().click() cy.get('td[data-col="Country => City"] div:visible', { timeout: 12000 })
cy.get('td[data-col="Country => City"] div .mdi-arrow-expand:visible').first().click() .first()
}) .click();
cy.get('td[data-col="Country => City"] div .mdi-arrow-expand:visible')
.first()
.click();
});
it('Expand Link record, validate', () => { it("Expand Link record, validate", () => {
cy.getActiveModal().find('button:contains(Link to \'City\')').click() cy.getActiveModal()
.find("button:contains(Link to 'City')")
.click()
.then(() => { .then(() => {
// Link record form validation // Link record form validation
cy.getActiveModal().contains('Link Record').should('exist') cy.getActiveModal().contains("Link Record").should("exist");
cy.getActiveModal().find('button.mdi-reload').should('exist') cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.getActiveModal().find('button:contains("New Record")').should('exist') cy.getActiveModal()
cy.getActiveModal().find('.child-card').eq(0).contains('A Corua (La Corua)').should('exist') .find('button:contains("New Record")')
.should("exist");
cy.getActiveModal()
.find(".child-card")
.eq(0)
.contains("A Corua (La Corua)")
.should("exist");
cy.getActiveModal().find('button.mdi-close').click().then(() => { cy.getActiveModal()
cy.getActiveModal().find('button.mdi-close').click() .find("button.mdi-close")
}) .click()
}) .then(() => {
}) cy.getActiveModal().find("button.mdi-close").click();
}) });
} });
});
});
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

106
scripts/cypress/integration/common/2b_table_with_m2m_column.js

@ -1,66 +1,89 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - M2M Column validation`, () => { describe(`${type.toUpperCase()} api - M2M Column validation`, () => {
before(() => { before(() => {
cy.openTableTab('Actor', 25) cy.openTableTab("Actor", 25);
});
})
after(() => { after(() => {
cy.closeTableTab('Actor') cy.closeTableTab("Actor");
}) });
it('Table column header, URL validation', () => {
it("Table column header, URL validation", () => {
// column name validation // column name validation
cy.get(`.project-tab:contains(Actor):visible`).should('exist') cy.get(`.project-tab:contains(Actor):visible`).should("exist");
// URL validation // URL validation
cy.url().should('contain', `name=Actor`) cy.url().should("contain", `name=Actor`);
}) });
it('Expand m2m column', () => {
it("Expand m2m column", () => {
// expand first row // expand first row
cy.get('td[data-col="Actor <=> Film"] div', {timeout: 12000}).first().click({force: true}) cy.get('td[data-col="Actor <=> Film"] div', { timeout: 12000 })
cy.get('td[data-col="Actor <=> Film"] div .mdi-arrow-expand').first().click({force: true}) .first()
.click({ force: true });
cy.get('td[data-col="Actor <=> Film"] div .mdi-arrow-expand')
.first()
.click({ force: true });
// validations // validations
cy.getActiveModal().contains('Film').should('exist') cy.getActiveModal().contains("Film").should("exist");
cy.getActiveModal().find('button.mdi-reload').should('exist') cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.getActiveModal().find('button:contains(Link to \'Film\')').should('exist') cy.getActiveModal()
cy.getActiveModal().find('.child-card').eq(0).contains('ACADEMY DINOSAUR').should('exist') .find("button:contains(Link to 'Film')")
}) .should("exist");
cy.getActiveModal()
.find(".child-card")
.eq(0)
.contains("ACADEMY DINOSAUR")
.should("exist");
});
it('Expand "Link to" record, validate', () => { it('Expand "Link to" record, validate', () => {
cy.getActiveModal().find('button:contains(Link to \'Film\')').click() cy.getActiveModal()
.find("button:contains(Link to 'Film')")
.click()
.then(() => { .then(() => {
// Link record form validation // Link record form validation
cy.getActiveModal().contains('Link Record').should('exist') cy.getActiveModal().contains("Link Record").should("exist");
cy.getActiveModal().find('button.mdi-reload').should('exist') cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.getActiveModal().find('button:contains("New Record")').should('exist') cy.getActiveModal()
cy.getActiveModal().find('.child-card').eq(0).contains('ACE GOLDFINGER').should('exist') .find('button:contains("New Record")')
cy.get('body').type('{esc}') .should("exist");
}) cy.getActiveModal()
}) .find(".child-card")
.eq(0)
.contains("ACE GOLDFINGER")
.should("exist");
cy.get("body").type("{esc}");
});
});
it('Expand first linked card, validate', () => { it("Expand first linked card, validate", () => {
cy.getActiveModal().find('.child-card').eq(0).contains('ACADEMY DINOSAUR', {timeout: 2000}).click() cy.getActiveModal()
.find(".child-card")
.eq(0)
.contains("ACADEMY DINOSAUR", { timeout: 2000 })
.click()
.then(() => { .then(() => {
// Link card validation // Link card validation
cy.getActiveModal().find('h5').contains("ACADEMY DINOSAUR").should('exist') cy.getActiveModal()
cy.getActiveModal().find('button:contains("Save Row")').should('exist') .find("h5")
cy.getActiveModal().find('button:contains("Cancel")').should('exist') .contains("ACADEMY DINOSAUR")
.should("exist");
cy.getActiveModal()
.find('button:contains("Save Row")')
.should("exist");
cy.getActiveModal().find('button:contains("Cancel")').should("exist");
cy.getActiveModal().find('button:contains("Cancel")').click() cy.getActiveModal().find('button:contains("Cancel")').click();
cy.getActiveModal().find('button.mdi-close').click() cy.getActiveModal().find("button.mdi-close").click();
}) });
}) });
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -84,4 +107,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

259
scripts/cypress/integration/common/3a_filter_sort_fields_operations.js

@ -1,176 +1,205 @@
import { mainPage } from "../../support/page_objects/mainPage";
import { mainPage } from "../../support/page_objects/mainPage" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Filter, Fields, Sort`, () => { describe(`${type.toUpperCase()} api - Filter, Fields, Sort`, () => {
before(() => { before(() => {
// open country table // open country table
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
}) });
after(() => { after(() => {
cy.closeTableTab('Country') cy.closeTableTab("Country");
}) });
describe(`Pagination`, () => { describe(`Pagination`, () => {
// check pagination // check pagination
it('Check country table - Pagination', () => { it("Check country table - Pagination", () => {
cy.get('.nc-pagination').should('exist') cy.get(".nc-pagination").should("exist");
// verify > pagination option // verify > pagination option
mainPage.getPagination('>').click() mainPage.getPagination(">").click();
mainPage.getPagination(2).should('have.class', 'v-pagination__item--active') mainPage
.getPagination(2)
.should("have.class", "v-pagination__item--active");
// verify < pagination option // verify < pagination option
mainPage.getPagination('<').click() mainPage.getPagination("<").click();
mainPage.getPagination(1).should('have.class', 'v-pagination__item--active') mainPage
}) .getPagination(1)
}) .should("have.class", "v-pagination__item--active");
});
});
describe(`Row operations`, () => { describe(`Row operations`, () => {
// create new row using + button in header // create new row using + button in header
// //
it('Add row using tool header button', () => { it("Add row using tool header button", () => {
// add a row to end of Country table // add a row to end of Country table
cy.get('.nc-add-new-row-btn').click(); cy.get(".nc-add-new-row-btn").click();
cy.get('#data-table-form-Country > input').first().type('Test Country'); cy.get("#data-table-form-Country > input").first().type("Test Country");
cy.contains('Save Row').filter('button').click() cy.contains("Save Row").filter("button").click();
cy.toastWait('updated successfully') cy.toastWait("updated successfully");
// verify // verify
mainPage.getPagination(5).click() mainPage.getPagination(5).click();
mainPage.getCell("Country", 10).contains("Test Country").should('exist') mainPage
}) .getCell("Country", 10)
.contains("Test Country")
.should("exist");
});
// delete slingle row // delete slingle row
// //
it('Delete row', () => { it("Delete row", () => {
// delete row added in previous step // delete row added in previous step
mainPage.getCell("Country", 10).rightclick() mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains('Delete Row').click() cy.getActiveMenu().contains("Delete Row").click();
// cy.toastWait('Deleted row successfully') // cy.toastWait('Deleted row successfully')
// verify // verify
mainPage.getCell("Country", 10).should('not.exist') mainPage.getCell("Country", 10).should("not.exist");
}) });
// create new row using right click menu option // create new row using right click menu option
// //
it('Add row using rightclick menu option', () => { it("Add row using rightclick menu option", () => {
mainPage.getCell("Country", 9).rightclick({force: true}) mainPage.getCell("Country", 9).rightclick({ force: true });
cy.getActiveMenu().contains('Insert New Row').click({force: true}) cy.getActiveMenu().contains("Insert New Row").click({ force: true });
mainPage.getCell("Country", 10).dblclick().find('input').type('Test Country-1{enter}') mainPage
.getCell("Country", 10)
.dblclick()
.find("input")
.type("Test Country-1{enter}");
// cy.toastWait('saved successfully') // cy.toastWait('saved successfully')
mainPage.getCell("Country", 10).rightclick({force: true}) mainPage.getCell("Country", 10).rightclick({ force: true });
cy.getActiveMenu().contains('Insert New Row').click({force: true}) cy.getActiveMenu().contains("Insert New Row").click({ force: true });
mainPage.getCell("Country", 11).dblclick().find('input').type('Test Country-2{enter}') mainPage
.getCell("Country", 11)
.dblclick()
.find("input")
.type("Test Country-2{enter}");
// cy.toastWait('saved successfully') // cy.toastWait('saved successfully')
// verify // verify
mainPage.getCell("Country", 10).contains("Test Country-1").should('exist') mainPage
mainPage.getCell("Country", 11).contains("Test Country-2").should('exist') .getCell("Country", 10)
}) .contains("Test Country-1")
.should("exist");
mainPage
.getCell("Country", 11)
.contains("Test Country-2")
.should("exist");
});
// delete selected rows (multiple) // delete selected rows (multiple)
// //
it('Delete Selected', () => { it("Delete Selected", () => {
mainPage.getRow(10).find('.mdi-checkbox-blank-outline').click({force: true}) mainPage
mainPage.getRow(11).find('.mdi-checkbox-blank-outline').click({force: true}) .getRow(10)
.find(".mdi-checkbox-blank-outline")
mainPage.getCell("Country", 10).rightclick({force: true}) .click({ force: true });
cy.getActiveMenu().contains('Delete Selected Row').click({force: true}) mainPage
.getRow(11)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage.getCell("Country", 10).rightclick({ force: true });
cy.getActiveMenu()
.contains("Delete Selected Row")
.click({ force: true });
// cy.toastWait('Deleted 2 selected rows successfully') // cy.toastWait('Deleted 2 selected rows successfully')
// verify // verify
mainPage.getCell("Country", 10).should('not.exist') mainPage.getCell("Country", 10).should("not.exist");
mainPage.getCell("Country", 11).should('not.exist') mainPage.getCell("Country", 11).should("not.exist");
mainPage.getPagination(1).click() mainPage.getPagination(1).click();
}) });
});
})
describe(`Sort operations`, () => { describe(`Sort operations`, () => {
it('Enable sort', () => { it("Enable sort", () => {
// Sort menu operations (Country Column, Z->A) // Sort menu operations (Country Column, Z->A)
cy.get('.nc-sort-menu-btn').click() cy.get(".nc-sort-menu-btn").click();
cy.contains('Add Sort Option').click(); cy.contains("Add Sort Option").click();
cy.get('.nc-sort-field-select div').first().click() cy.get(".nc-sort-field-select div").first().click();
cy.get('.menuable__content__active .v-list-item:contains(Country)').click() cy.get(
cy.get('.nc-sort-dir-select div').first().click() ".menuable__content__active .v-list-item:contains(Country)"
cy.get('.menuable__content__active .v-list-item:contains("Z -> A")').click() ).click();
cy.get(".nc-sort-dir-select div").first().click();
cy.contains('Zambia').should('exist') cy.get(
}) '.menuable__content__active .v-list-item:contains("Z -> A")'
).click();
it('Disable sort', () => {
cy.contains("Zambia").should("exist");
});
it("Disable sort", () => {
// remove sort and validate // remove sort and validate
cy.get('.nc-sort-item-remove-btn').click() cy.get(".nc-sort-item-remove-btn").click();
cy.contains('Zambia').should('not.exist') cy.contains("Zambia").should("not.exist");
}) });
});
})
describe('Field Operation', () => {
it('Hide field', () => { describe("Field Operation", () => {
cy.get('th:contains(LastUpdate)').should('be.visible') it("Hide field", () => {
cy.get("th:contains(LastUpdate)").should("be.visible");
// toggle and confirm it's hidden // toggle and confirm it's hidden
cy.get('.nc-fields-menu-btn').click() cy.get(".nc-fields-menu-btn").click();
cy.get('.menuable__content__active .v-list-item label:contains(LastUpdate)').click() cy.get(
cy.get('.nc-fields-menu-btn').click() ".menuable__content__active .v-list-item label:contains(LastUpdate)"
cy.get('th:contains(LastUpdate)').should('not.be.visible') ).click();
}) cy.get(".nc-fields-menu-btn").click();
cy.get("th:contains(LastUpdate)").should("not.be.visible");
it('Show field', () => { });
cy.get('.nc-fields-menu-btn').click()
cy.get('.menuable__content__active .v-list-item label:contains(LastUpdate)').click() it("Show field", () => {
cy.get('.nc-fields-menu-btn').click() cy.get(".nc-fields-menu-btn").click();
cy.get('th:contains(LastUpdate)').should('be.visible') cy.get(
}) ".menuable__content__active .v-list-item label:contains(LastUpdate)"
}) ).click();
cy.get(".nc-fields-menu-btn").click();
cy.get("th:contains(LastUpdate)").should("be.visible");
describe('Filter operations', () => { });
it('Create Filter', () => { });
cy.get('.nc-filter-menu-btn').click()
cy.contains('Add Filter').click(); describe("Filter operations", () => {
it("Create Filter", () => {
cy.get('.nc-filter-field-select').last().click(); cy.get(".nc-filter-menu-btn").click();
cy.getActiveMenu().find('.v-list-item:contains(Country)').click() cy.contains("Add Filter").click();
cy.get('.nc-filter-operation-select').last().click();
cy.getActiveMenu().find('.v-list-item:contains("is equal")').click() cy.get(".nc-filter-field-select").last().click();
cy.get('.nc-filter-value-select input:text').last().type('India'); cy.getActiveMenu().find(".v-list-item:contains(Country)").click();
cy.get('.nc-filter-menu-btn').click() cy.get(".nc-filter-operation-select").last().click();
cy.getActiveMenu().find('.v-list-item:contains("is equal")').click();
cy.get(".nc-filter-value-select input:text").last().type("India");
cy.get(".nc-filter-menu-btn")
.click()
.then(() => { .then(() => {
cy.get('td:contains(India)').should('exist') cy.get("td:contains(India)").should("exist");
}) });
}) });
it('Delete Filter', () => { it("Delete Filter", () => {
// remove sort and check // remove sort and check
cy.get('.nc-filter-menu-btn').click() cy.get(".nc-filter-menu-btn").click();
cy.get('.nc-filter-item-remove-btn').click() cy.get(".nc-filter-item-remove-btn").click();
cy.get('.nc-filter-menu-btn').click() cy.get(".nc-filter-menu-btn").click();
cy.contains('td:contains(India)').should('not.exist') cy.contains("td:contains(India)").should("not.exist");
}) });
}) });
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -192,4 +221,4 @@ export const genTest = (type, xcdb) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

395
scripts/cypress/integration/common/3b_formula_column.js

@ -1,190 +1,214 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - FORMULA`, () => { describe(`${type.toUpperCase()} api - FORMULA`, () => {
// Run once before test- create project (rest/graphql)
// Run once before test- create project (rest/graphql) //
// before(() => {
before(() => { // open a table to work on views
// open a table to work on views //
// cy.openTableTab("City", 25);
cy.openTableTab('City', 25); });
})
after(() => {
after(() => { cy.closeTableTab("City");
cy.closeTableTab('City') });
})
// Given rowname & expected result for first 10 entries, validate
// Given rowname & expected result for first 10 entries, validate // NOTE: Scroll issue with Cypress automation, to fix
// NOTE: Scroll issue with Cypress automation, to fix // validating partial data, row number 5 to 9
// validating partial data, row number 5 to 9 //
// const rowValidation = (rowName, result) => {
const rowValidation = (rowName, result) => { // scroll back
cy.get(`tbody > :nth-child(1) > [data-col="City"]`).scrollIntoView();
// scroll back
cy.get(`tbody > :nth-child(1) > [data-col="City"]`).scrollIntoView() // for (let i = 0; i < 10; i++)
for (let i = 3; i < 6; i++)
// for (let i = 0; i < 10; i++) cy.get(`tbody > :nth-child(${i + 1}) > [data-col="${rowName}"]`)
for (let i = 3; i < 6; i++) .contains(result[i].toString())
cy.get(`tbody > :nth-child(${i + 1}) > [data-col="${rowName}"]`) .should("exist");
.contains(result[i].toString()) };
.should('exist')
} // Routine to create a new look up column
//
// Routine to create a new look up column const addFormulaBasedColumn = (columnName, formula) => {
// // (+) icon at end of column header (to add a new column)
const addFormulaBasedColumn = (columnName, formula) => { // opens up a pop up window
//
// (+) icon at end of column header (to add a new column) cy.get(".new-column-header").click();
// opens up a pop up window
// // Column name
cy.get('.new-column-header').click() cy.get(".nc-column-name-input input")
.clear()
// Column name .type(`${columnName}{enter}`);
cy.get('.nc-column-name-input input').clear().type(`${columnName}{enter}`)
// Column data type: to be set to formula in this context
// Column data type: to be set to formula in this context cy.get(".nc-ui-dt-dropdown").click().type("Formula");
cy.get('.nc-ui-dt-dropdown').click().type('Formula') cy.getActiveMenu().contains("Formula").click({ force: true });
cy.getActiveMenu().contains('Formula').click({ force: true })
// Configure formula
// Configure formula cy.get("label").contains("Formula").parent().click().type(formula);
cy.get('label').contains('Formula').parent().click().type(formula)
// click on Save
// click on Save cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.get('.nc-col-create-or-edit-card').contains('Save').click()
cy.toastWait("Formula column saved successfully");
cy.toastWait('Formula column saved successfully')
// Verify if column exists.
// Verify if column exists. //
// cy.get(`th:contains(${columnName})`).should("exist");
cy.get(`th:contains(${columnName})`) };
.should('exist');
} // routine to delete column
//
// routine to delete column const deleteColumnByName = (columnName) => {
// // verify if column exists before delete
const deleteColumnByName = (columnName) => { cy.get(`th:contains(${columnName})`).should("exist");
// verify if column exists before delete // delete opiton visible on mouse-over
cy.get(`th:contains(${columnName})`) cy.get(`th:contains(${columnName}) .mdi-menu-down`)
.should('exist'); .trigger("mouseover")
.click();
// delete opiton visible on mouse-over
cy.get(`th:contains(${columnName}) .mdi-menu-down`) // delete/ confirm on pop-up
.trigger('mouseover') cy.get(".nc-column-delete").click();
.click() cy.getActiveModal().find("button:contains(Confirm)").click();
// delete/ confirm on pop-up // validate if deleted (column shouldnt exist)
cy.get('.nc-column-delete').click() cy.get(`th:contains(${columnName})`).should("not.exist");
cy.getActiveModal().find('button:contains(Confirm)').click() };
// validate if deleted (column shouldnt exist) // routine to edit column
cy.get(`th:contains(${columnName})`) //
.should('not.exist'); const editColumnByName = (oldName, newName, newFormula) => {
} // verify if column exists before delete
cy.get(`th:contains(${oldName})`).should("exist");
// routine to edit column // delete opiton visible on mouse-over
// cy.get(`th:contains(${oldName}) .mdi-menu-down`)
const editColumnByName = (oldName, newName, newFormula) => { .trigger("mouseover")
.click();
// verify if column exists before delete
cy.get(`th:contains(${oldName})`) // edit/ save on pop-up
.should('exist'); cy.get(".nc-column-edit").click();
cy.get(".nc-column-name-input input").clear().type(newName);
// delete opiton visible on mouse-over
cy.get(`th:contains(${oldName}) .mdi-menu-down`) cy.get("label")
.trigger('mouseover') .contains("Formula")
.click() .parent()
.find("input")
// edit/ save on pop-up .clear()
cy.get('.nc-column-edit').click() .type(newFormula);
cy.get('.nc-column-name-input input').clear().type(newName)
cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.get('label')
.contains('Formula').parent().find('input').clear().type(newFormula) cy.toastWait("Formula column updated successfully");
cy.get('.nc-col-create-or-edit-card').contains('Save').click() // validate if deleted (column shouldnt exist)
cy.get(`th:contains(${oldName})`).should("not.exist");
cy.toastWait('Formula column updated successfully') cy.get(`th:contains(${newName})`).should("exist");
};
// validate if deleted (column shouldnt exist)
cy.get(`th:contains(${oldName})`) ///////////////////////////////////////////////////
.should('not.exist'); // Test case
cy.get(`th:contains(${newName})`)
.should('exist'); // On City table (from Sakila DB), first 10 entries recorded here for verification
let cityId = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
} let countryId = [87, 82, 101, 60, 97, 31, 107, 44, 44, 50];
let city = [
/////////////////////////////////////////////////// "A corua (La Corua)",
// Test case "Abha",
"Abu Dhabi",
// On City table (from Sakila DB), first 10 entries recorded here for verification "Acua",
let cityId = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] "Adana",
let countryId = [87, 82, 101, 60, 97, 31, 107, 44, 44, 50] "Addis Abeba",
let city = ['A corua (La Corua)', 'Abha', 'Abu Dhabi', 'Acua', 'Adana', 'Addis Abeba', 'Aden', 'Adoni', 'Ahmadnagar', 'Akishima'] "Aden",
"Adoni",
// Temporary locally computed expected results "Ahmadnagar",
let RESULT_STRING = [] "Akishima",
let RESULT_MATH_0 = [] ];
let RESULT_MATH_1 = []
let RESULT_MATH_2 = [] // Temporary locally computed expected results
let RESULT_STRING = [];
for (let i = 0; i < 10; i++) { let RESULT_MATH_0 = [];
let RESULT_MATH_1 = [];
// CONCAT, LOWER, UPPER, TRIM let RESULT_MATH_2 = [];
RESULT_STRING[i] = `${city[i].toUpperCase()}${city[i].toLowerCase()}trimmed`
for (let i = 0; i < 10; i++) {
// ADD, AVG, LEN // CONCAT, LOWER, UPPER, TRIM
RESULT_MATH_0[i] = ((cityId[i] + countryId[i]) + RESULT_STRING[i] = `${city[i].toUpperCase()}${city[
((cityId[i] + countryId[i]) / 2) + i
(city[i].length)) ].toLowerCase()}trimmed`;
// CEILING, FLOOR, ROUND, MOD, MIN, MAX // ADD, AVG, LEN
RESULT_MATH_1[i] = (Math.ceil(1.4) + RESULT_MATH_0[i] =
Math.floor(1.6) + cityId[i] +
Math.round(2.5) + countryId[i] +
(cityId[i] % 3) + (cityId[i] + countryId[i]) / 2 +
Math.min(cityId[i], countryId[i]) + city[i].length;
Math.max(cityId[i], countryId[i]))
// CEILING, FLOOR, ROUND, MOD, MIN, MAX
// LOG, EXP, POWER, SQRT RESULT_MATH_1[i] =
// only integer verification being computed, hence trunc Math.ceil(1.4) +
RESULT_MATH_2[i] = Math.trunc(Math.log(cityId[i]) + Math.floor(1.6) +
Math.exp(cityId[i]) + Math.round(2.5) +
Math.pow(cityId[i], 3) + (cityId[i] % 3) +
Math.sqrt(countryId[i])) Math.min(cityId[i], countryId[i]) +
} Math.max(cityId[i], countryId[i]);
it('Formula: CONCAT, LOWER, UPPER, TRIM', () => { // LOG, EXP, POWER, SQRT
addFormulaBasedColumn('NC_MATH_0', 'ADD(CityId, CountryId) + AVG(CityId, CountryId) + LEN(City)') // only integer verification being computed, hence trunc
rowValidation('NC_MATH_0', RESULT_MATH_0) RESULT_MATH_2[i] = Math.trunc(
}) Math.log(cityId[i]) +
Math.exp(cityId[i]) +
it('Formula: ADD, AVG, LEN', () => { Math.pow(cityId[i], 3) +
editColumnByName('NC_MATH_0', 'NC_STR_1', `CONCAT(UPPER(City), LOWER(City), TRIM(' trimmed '))`) Math.sqrt(countryId[i])
rowValidation('NC_STR_1', RESULT_STRING) );
}) }
it('Formula: CEILING, FLOOR, ROUND, MOD, MIN, MAX', () => { it("Formula: CONCAT, LOWER, UPPER, TRIM", () => {
editColumnByName('NC_STR_1', 'NC_MATH_1', `CEILING(1.4) + FLOOR(1.6) + ROUND(2.5) + MOD(CityId, 3) + MIN(CityId, CountryId) + MAX(CityId, CountryId)`) addFormulaBasedColumn(
rowValidation('NC_MATH_1', RESULT_MATH_1) "NC_MATH_0",
}) "ADD(CityId, CountryId) + AVG(CityId, CountryId) + LEN(City)"
);
it('Formula: LOG, EXP, POWER, SQRT', () => { rowValidation("NC_MATH_0", RESULT_MATH_0);
editColumnByName('NC_MATH_1', 'NC_MATH_2', `LOG(CityId) + EXP(CityId) + POWER(CityId, 3) + SQRT(CountryId)`) });
rowValidation('NC_MATH_2', RESULT_MATH_2)
}) it("Formula: ADD, AVG, LEN", () => {
editColumnByName(
it('Formula: NOW, EDIT & Delete column', () => { "NC_MATH_0",
editColumnByName('NC_MATH_2', 'NC_NOW', `NOW()`) "NC_STR_1",
deleteColumnByName('NC_NOW') `CONCAT(UPPER(City), LOWER(City), TRIM(' trimmed '))`
}) );
}) rowValidation("NC_STR_1", RESULT_STRING);
} });
it("Formula: CEILING, FLOOR, ROUND, MOD, MIN, MAX", () => {
editColumnByName(
"NC_STR_1",
"NC_MATH_1",
`CEILING(1.4) + FLOOR(1.6) + ROUND(2.5) + MOD(CityId, 3) + MIN(CityId, CountryId) + MAX(CityId, CountryId)`
);
rowValidation("NC_MATH_1", RESULT_MATH_1);
});
it("Formula: LOG, EXP, POWER, SQRT", () => {
editColumnByName(
"NC_MATH_1",
"NC_MATH_2",
`LOG(CityId) + EXP(CityId) + POWER(CityId, 3) + SQRT(CountryId)`
);
rowValidation("NC_MATH_2", RESULT_MATH_2);
});
it("Formula: NOW, EDIT & Delete column", () => {
editColumnByName("NC_MATH_2", "NC_NOW", `NOW()`);
deleteColumnByName("NC_NOW");
});
});
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -208,4 +232,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

171
scripts/cypress/integration/common/3c_lookup_column.js

@ -1,117 +1,102 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - LookUp column`, () => { describe(`${type.toUpperCase()} api - LookUp column`, () => {
// to retrieve few v-input nodes from their label
// to retrieve few v-input nodes from their label //
// const fetchParentFromLabel = (label) => {
const fetchParentFromLabel = (label) => { cy.get("label").contains(label).parents(".v-input").click();
cy.get('label') };
.contains(label)
.parents('.v-input') // Run once before test- create project (rest/graphql)
.click() //
} before(() => {
// open a table to work on views
// Run once before test- create project (rest/graphql) //
// cy.openTableTab("City", 25);
before(() => { });
// open a table to work on views
//
cy.openTableTab('City', 25);
})
after(() => {
cy.closeTableTab('City')
})
// Routine to create a new look up column
//
const addLookUpColumn = (childTable, childCol) => {
// (+) icon at end of column header (to add a new column)
// opens up a pop up window
//
cy.get('.new-column-header').click()
// Redundant to feed column name. as alias is displayed & referred for
cy.get('.nc-column-name-input input').clear().type(childCol)
// Column data type: to be set to lookup in this context
cy.get('.nc-ui-dt-dropdown').click()
cy.getActiveMenu().contains('Lookup').click()
// Configure Child table & column names
fetchParentFromLabel('Child Table')
cy.getActiveMenu().contains(childTable).click()
fetchParentFromLabel('Child column') after(() => {
cy.getActiveMenu().contains(childCol).click() cy.closeTableTab("City");
});
// click on Save // Routine to create a new look up column
cy.get('.nc-col-create-or-edit-card').contains('Save').click() //
const addLookUpColumn = (childTable, childCol) => {
// (+) icon at end of column header (to add a new column)
// opens up a pop up window
//
cy.get(".new-column-header").click();
// Verify if column exists. // Redundant to feed column name. as alias is displayed & referred for
// cy.get(".nc-column-name-input input").clear().type(childCol);
cy.get(`th:contains(${childCol})`)
.should('exist');
}
// routine to delete column // Column data type: to be set to lookup in this context
// cy.get(".nc-ui-dt-dropdown").click();
const deleteColumnByName = (childCol) => { cy.getActiveMenu().contains("Lookup").click();
// verify if column exists before delete // Configure Child table & column names
cy.get(`th:contains(${childCol})`) fetchParentFromLabel("Child Table");
.should('exist'); cy.getActiveMenu().contains(childTable).click();
// delete opiton visible on mouse-over fetchParentFromLabel("Child column");
cy.get(`th:contains(${childCol}) .mdi-menu-down`) cy.getActiveMenu().contains(childCol).click();
.trigger('mouseover')
.click()
// delete/ confirm on pop-up // click on Save
cy.get('.nc-column-delete').click() cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.getActiveModal().find('button:contains(Confirm)').click()
// validate if deleted (column shouldnt exist) // Verify if column exists.
cy.get(`th:contains(${childCol})`) //
.should('not.exist'); cy.get(`th:contains(${childCol})`).should("exist");
};
} // routine to delete column
//
const deleteColumnByName = (childCol) => {
// verify if column exists before delete
cy.get(`th:contains(${childCol})`).should("exist");
/////////////////////////////////////////////////// // delete opiton visible on mouse-over
// Test case cy.get(`th:contains(${childCol}) .mdi-menu-down`)
.trigger("mouseover")
.click();
it('Add Lookup column (Address, District) & Delete', () => { // delete/ confirm on pop-up
cy.get(".nc-column-delete").click();
cy.getActiveModal().find("button:contains(Confirm)").click();
addLookUpColumn('Address', 'District') // validate if deleted (column shouldnt exist)
cy.get(`th:contains(${childCol})`).should("not.exist");
};
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)' ///////////////////////////////////////////////////
cy.get(`tbody > :nth-child(1) > [data-col="District"]`) // Test case
.contains('Galicia')
.should('exist')
deleteColumnByName('District') it("Add Lookup column (Address, District) & Delete", () => {
addLookUpColumn("Address", "District");
}) // Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
cy.get(`tbody > :nth-child(1) > [data-col="District"]`)
.contains("Galicia")
.should("exist");
it.skip('Add Lookup column (Country, CountryId) & Delete', () => { deleteColumnByName("District");
});
addLookUpColumn('Country', 'CountryId') it.skip("Add Lookup column (Country, CountryId) & Delete", () => {
addLookUpColumn("Country", "CountryId");
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)' // Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
cy.get(`tbody > :nth-child(1) > [data-col="CountryId"]`) cy.get(`tbody > :nth-child(1) > [data-col="CountryId"]`)
.contains('87') .contains("87")
.should('exist') .should("exist");
deleteColumnByName('CountryId') deleteColumnByName("CountryId");
})
}); });
} });
};
// genTest('rest', false) // genTest('rest', false)
// genTest('graphql', false) // genTest('graphql', false)
@ -137,4 +122,4 @@ export const genTest = (type, xcdb) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

138
scripts/cypress/integration/common/3d_rollup_column.js

@ -1,154 +1,141 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - RollUp column`, () => { describe(`${type.toUpperCase()} api - RollUp column`, () => {
// to retrieve few v-input nodes from their label // to retrieve few v-input nodes from their label
// //
const fetchParentFromLabel = (label) => { const fetchParentFromLabel = (label) => {
cy.get('label') cy.get("label").contains(label).parents(".v-input").click();
.contains(label) };
.parents('.v-input')
.click()
}
// Run once before test- create project (rest/graphql) // Run once before test- create project (rest/graphql)
// //
before(() => { before(() => {
// open a table to work on views // open a table to work on views
// //
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
}) });
after(() => { after(() => {
cy.closeTableTab('Country'); cy.closeTableTab("Country");
}) });
// Routine to create a new look up column // Routine to create a new look up column
// //
const addLookUpColumn = (columnName, childTable, childCol, aggregateFunc) => { const addLookUpColumn = (
columnName,
childTable,
childCol,
aggregateFunc
) => {
// (+) icon at end of column header (to add a new column) // (+) icon at end of column header (to add a new column)
// opens up a pop up window // opens up a pop up window
// //
cy.get('.new-column-header').click() cy.get(".new-column-header").click();
// Column name // Column name
cy.get('.nc-column-name-input input').clear().type(`${columnName}{enter}`) cy.get(".nc-column-name-input input")
.clear()
.type(`${columnName}{enter}`);
// Column data type: to be set to rollup in this context // Column data type: to be set to rollup in this context
// Type 'Rollup' ensures item outside view is also listed (note, rollup is at bottom of scroll list) // Type 'Rollup' ensures item outside view is also listed (note, rollup is at bottom of scroll list)
cy.get('.nc-ui-dt-dropdown').click().type('Rollup') cy.get(".nc-ui-dt-dropdown").click().type("Rollup");
cy.getActiveMenu().contains('Rollup').click({ force: true }) cy.getActiveMenu().contains("Rollup").click({ force: true });
// Configure Child table & column names // Configure Child table & column names
fetchParentFromLabel('Child Table') fetchParentFromLabel("Child Table");
cy.getActiveMenu().contains(childTable).click() cy.getActiveMenu().contains(childTable).click();
fetchParentFromLabel('Child column') fetchParentFromLabel("Child column");
cy.getActiveMenu().contains(childCol).click() cy.getActiveMenu().contains(childCol).click();
fetchParentFromLabel('Aggregate function') fetchParentFromLabel("Aggregate function");
cy.getActiveMenu().contains(aggregateFunc).click() cy.getActiveMenu().contains(aggregateFunc).click();
// click on Save // click on Save
cy.get('.nc-col-create-or-edit-card').contains('Save').click() cy.get(".nc-col-create-or-edit-card").contains("Save").click();
// Verify if column exists. // Verify if column exists.
// //
cy.get(`th:contains(${columnName})`) cy.get(`th:contains(${columnName})`).should("exist");
.should('exist'); };
}
// routine to delete column // routine to delete column
// //
const deleteColumnByName = (columnName) => { const deleteColumnByName = (columnName) => {
// verify if column exists before delete // verify if column exists before delete
cy.get(`th:contains(${columnName})`) cy.get(`th:contains(${columnName})`).should("exist");
.should('exist');
// delete opiton visible on mouse-over // delete opiton visible on mouse-over
cy.get(`th:contains(${columnName}) .mdi-menu-down`) cy.get(`th:contains(${columnName}) .mdi-menu-down`)
.trigger('mouseover') .trigger("mouseover")
.click() .click();
// delete/ confirm on pop-up // delete/ confirm on pop-up
cy.get('.nc-column-delete').click() cy.get(".nc-column-delete").click();
cy.getActiveModal().find('button:contains(Confirm)').click() cy.getActiveModal().find("button:contains(Confirm)").click();
// validate if deleted (column shouldnt exist) // validate if deleted (column shouldnt exist)
cy.get(`th:contains(${columnName})`) cy.get(`th:contains(${columnName})`).should("not.exist");
.should('not.exist'); };
}
// routine to edit column // routine to edit column
// //
const editColumnByName = (oldName, newName) => { const editColumnByName = (oldName, newName) => {
// verify if column exists before delete // verify if column exists before delete
cy.get(`th:contains(${oldName})`) cy.get(`th:contains(${oldName})`).should("exist");
.should('exist');
// delete opiton visible on mouse-over // delete opiton visible on mouse-over
cy.get(`th:contains(${oldName}) .mdi-menu-down`) cy.get(`th:contains(${oldName}) .mdi-menu-down`)
.trigger('mouseover') .trigger("mouseover")
.click() .click();
// edit/ save on pop-up // edit/ save on pop-up
cy.get('.nc-column-edit').click() cy.get(".nc-column-edit").click();
cy.get('.nc-column-name-input input').clear().type(newName) cy.get(".nc-column-name-input input").clear().type(newName);
cy.get('.nc-col-create-or-edit-card').contains('Save').click() cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.toastWait('Successfully updated alias') cy.toastWait("Successfully updated alias");
// validate if deleted (column shouldnt exist) // validate if deleted (column shouldnt exist)
cy.get(`th:contains(${oldName})`) cy.get(`th:contains(${oldName})`).should("not.exist");
.should('not.exist'); cy.get(`th:contains(${newName})`).should("exist");
cy.get(`th:contains(${newName})`) };
.should('exist');
}
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// Test case // Test case
it('Add Rollup column (City, CityId, sum) & Delete', () => { it("Add Rollup column (City, CityId, sum) & Delete", () => {
addLookUpColumn("RollUpCol_2", "City", "CityId", "sum");
addLookUpColumn('RollUpCol_2', 'City', 'CityId', 'sum')
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)' // Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
// intentionally verifying 4th item, as initial items are being masked out by list scroll down // intentionally verifying 4th item, as initial items are being masked out by list scroll down
// to be fixed // to be fixed
// //
cy.get(`tbody > :nth-child(4) > [data-col="RollUpCol_2"]`) cy.get(`tbody > :nth-child(4) > [data-col="RollUpCol_2"]`)
.contains('427') .contains("427")
.should('exist') .should("exist");
editColumnByName('RollUpCol_2', 'RollUpCol_New')
deleteColumnByName('RollUpCol_New')
})
it.skip('Add Rollup column (City, CountryId, count) & Delete', () => { editColumnByName("RollUpCol_2", "RollUpCol_New");
deleteColumnByName("RollUpCol_New");
});
addLookUpColumn('RollUpCol_1', 'City', 'CountryId', 'count') it.skip("Add Rollup column (City, CountryId, count) & Delete", () => {
addLookUpColumn("RollUpCol_1", "City", "CountryId", "count");
// Verify first entry, will be displayed as alias here 'childColumn (from childTable)' // Verify first entry, will be displayed as alias here 'childColumn (from childTable)'
cy.get(`tbody > :nth-child(4) > [data-col="RollUpCol_1"]`) cy.get(`tbody > :nth-child(4) > [data-col="RollUpCol_1"]`)
.contains('2') .contains("2")
.should('exist') .should("exist");
editColumnByName('RollUpCol_1', 'RollUpCol_New') editColumnByName("RollUpCol_1", "RollUpCol_New");
deleteColumnByName('RollUpCol_New') deleteColumnByName("RollUpCol_New");
});
})
}); });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -172,4 +159,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

72
scripts/cypress/integration/common/4a_table_view_grid_gallery_form.js

@ -1,81 +1,76 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Table views: Create/Edit/Delete`, () => { describe(`${type.toUpperCase()} api - Table views: Create/Edit/Delete`, () => {
const name = "Test" + Date.now();
const name = 'Test' + Date.now();
// Run once before test- create project (rest/graphql) // Run once before test- create project (rest/graphql)
// //
before(() => { before(() => {
// open a table to work on views // open a table to work on views
// //
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
}) });
after(() => { after(() => {
cy.closeTableTab('Country') cy.closeTableTab("Country");
}) });
// Common routine to create/edit/delete GRID & GALLERY view // Common routine to create/edit/delete GRID & GALLERY view
// Input: viewType - 'grid'/'gallery' // Input: viewType - 'grid'/'gallery'
// //
const viewTest = (viewType) => { const viewTest = (viewType) => {
it(`Create ${viewType} view`, () => { it(`Create ${viewType} view`, () => {
// click on 'Grid/Gallery' button on Views bar // click on 'Grid/Gallery' button on Views bar
cy.get(`.nc-create-${viewType}-view`).click(); cy.get(`.nc-create-${viewType}-view`).click();
// Pop up window, click Submit (accepting default name for view) // Pop up window, click Submit (accepting default name for view)
cy.getActiveModal().find('button:contains(Submit)').click() cy.getActiveModal().find("button:contains(Submit)").click();
cy.toastWait('View created successfully') cy.toastWait("View created successfully");
// validate if view was creted && contains default name 'Country1' // validate if view was creted && contains default name 'Country1'
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').should('exist') cy.get(`.nc-view-item.nc-${viewType}-view-item`)
}) .contains("Country1")
.should("exist");
});
it(`Edit ${viewType} view name`, () => { it(`Edit ${viewType} view name`, () => {
// click on edit-icon (becomes visible on hovering mouse) // click on edit-icon (becomes visible on hovering mouse)
cy.get('.nc-view-edit-icon').click({ force: true, timeout: 1000 }) cy.get(".nc-view-edit-icon").click({ force: true, timeout: 1000 });
// feed new name // feed new name
cy.get(`.nc-${viewType}-view-item input`).type(`${viewType}View-1{enter}`) cy.get(`.nc-${viewType}-view-item input`).type(
cy.toastWait('View renamed successfully') `${viewType}View-1{enter}`
);
cy.toastWait("View renamed successfully");
// validate // validate
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains(`${viewType}View-1`).should('exist') cy.get(`.nc-view-item.nc-${viewType}-view-item`)
}) .contains(`${viewType}View-1`)
.should("exist");
});
it(`Delete ${viewType} view`, () => { it(`Delete ${viewType} view`, () => {
// number of view entries should be 2 before we delete // number of view entries should be 2 before we delete
cy.get('.nc-view-item').its('length').should('eq', 2) cy.get(".nc-view-item").its("length").should("eq", 2);
// click on delete icon (becomes visible on hovering mouse) // click on delete icon (becomes visible on hovering mouse)
cy.get('.nc-view-delete-icon').click({ force: true }) cy.get(".nc-view-delete-icon").click({ force: true });
cy.toastWait('View deleted successfully') cy.toastWait("View deleted successfully");
// confirm if the number of veiw entries is reduced by 1 // confirm if the number of veiw entries is reduced by 1
cy.get('.nc-view-item').its('length').should('eq', 1) cy.get(".nc-view-item").its("length").should("eq", 1);
}) });
};
}
// below two scenario's will be invoked twice, once for rest & then for graphql // below two scenario's will be invoked twice, once for rest & then for graphql
viewTest('grid') viewTest("grid");
viewTest('gallery') viewTest("gallery");
viewTest('form') viewTest("form");
});
}) };
}
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -99,4 +94,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

184
scripts/cypress/integration/common/4b_table_view_share.js

@ -1,99 +1,99 @@
import { mainPage } from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
let storedURL = '' let storedURL = "";
let linkText = '' let linkText = "";
const generateLinkWithPwd = () => { const generateLinkWithPwd = () => {
cy.get(".v-navigation-drawer__content > .container")
cy.get('.v-navigation-drawer__content > .container') .find(".v-list > .v-list-item")
.find('.v-list > .v-list-item') .contains("Share View")
.contains('Share View') .click();
.click()
// enable checkbox & feed pwd, save
// enable checkbox & feed pwd, save cy.getActiveModal()
cy.getActiveModal().find('[role="switch"][type="checkbox"]').click( {force: true} ) .find('[role="switch"][type="checkbox"]')
cy.getActiveModal().find('input[type="password"]').type('1') .click({ force: true });
cy.getActiveModal().find('button:contains("Save password")').click() cy.getActiveModal().find('input[type="password"]').type("1");
cy.getActiveModal().find('button:contains("Save password")').click();
cy.toastWait('Successfully updated')
cy.toastWait("Successfully updated");
// copy link text, visit URL
cy.getActiveModal().find('.share-link-box') // copy link text, visit URL
.then(($obj) => { cy.getActiveModal()
.find(".share-link-box")
linkText = $obj.text().trim() .then(($obj) => {
cy.log(linkText) linkText = $obj.text().trim();
}) cy.log(linkText);
} });
};
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Shared VIEWs (GRID)`, () => { describe(`${type.toUpperCase()} api - Shared VIEWs (GRID)`, () => {
// Run once before test- create project (rest/graphql)
// Run once before test- create project (rest/graphql) //
// before(() => {
before(() => { cy.openTableTab("City", 25);
cy.openTableTab('City', 25)
// store base URL- to re-visit and delete form view later
// store base URL- to re-visit and delete form view later cy.url().then((url) => {
cy.url().then((url) => { storedURL = url;
storedURL = url });
})
generateLinkWithPwd();
generateLinkWithPwd() });
})
beforeEach(() => {
beforeEach(() => { cy.restoreLocalStorage();
cy.restoreLocalStorage(); });
})
afterEach(() => {
afterEach(() => { cy.saveLocalStorage();
cy.saveLocalStorage(); });
})
it("Share view with incorrect password", () => {
it('Share view with incorrect password', () => { cy.visit(linkText, {
cy.visit(linkText, { baseUrl: null,
baseUrl: null });
})
cy.getActiveModal().should("exist");
cy.getActiveModal().should('exist')
// feed password
// feed password cy.getActiveModal().find('input[type="password"]').type("a");
cy.getActiveModal().find('input[type="password"]').type('a') cy.getActiveModal().find('button:contains("Unlock")').click();
cy.getActiveModal().find('button:contains("Unlock")').click()
// if pwd is incorrect, active modal requesting to feed in password again will persist
// if pwd is incorrect, active modal requesting to feed in password again will persist cy.get("body").find(".v-dialog.v-dialog--active").should("exist");
cy.get('body').find('.v-dialog.v-dialog--active').should('exist') });
})
// fallover test- use previously opened view & continue verification instead of opening again
// fallover test- use previously opened view & continue verification instead of opening again it("Share view with correct password", () => {
it('Share view with correct password', () => { // cy.visit(linkText, {
// cy.visit(linkText, { // baseUrl: null
// baseUrl: null // })
// })
// feed password
// feed password cy.getActiveModal().find('input[type="password"]').clear().type("1");
cy.getActiveModal().find('input[type="password"]').clear().type('1') cy.getActiveModal().find('button:contains("Unlock")').click();
cy.getActiveModal().find('button:contains("Unlock")').click()
// if pwd is incorrect, active modal requesting to feed in password again will persist
// if pwd is incorrect, active modal requesting to feed in password again will persist cy.get("body").find(".v-dialog.v-dialog--active").should("not.exist");
cy.get('body').find('.v-dialog.v-dialog--active').should('not.exist') });
})
it("Delete view", () => {
it('Delete view', () => { cy.visit(storedURL, {
cy.visit(storedURL, { baseUrl: null,
baseUrl: null });
}) mainPage.deleteCreatedViews();
mainPage.deleteCreatedViews() });
})
after(() => {
after(() => { cy.closeTableTab("City");
cy.closeTableTab('City') });
}) });
}) };
}
// genTest('rest', false) // genTest('rest', false)
// genTest('graphql', false) // genTest('graphql', false)
@ -119,4 +119,4 @@ export const genTest = (type, xcdb) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

722
scripts/cypress/integration/common/4c_form_view_detailed.js

@ -1,333 +1,438 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { mainPage } from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
let formViewURL let formViewURL;
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - FORM view`, () => { describe(`${type.toUpperCase()} api - FORM view`, () => {
const name = "Test" + Date.now();
const name = 'Test' + Date.now();
// Run once before test- create project (rest/graphql) // Run once before test- create project (rest/graphql)
// //
before(() => { before(() => {
// open a table to work on views // open a table to work on views
// //
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
}) });
beforeEach(() => { beforeEach(() => {
cy.restoreLocalStorage(); cy.restoreLocalStorage();
}) });
afterEach(() => { afterEach(() => {
cy.saveLocalStorage(); cy.saveLocalStorage();
}) });
after(() => { after(() => {
cy.closeTableTab('Country') cy.closeTableTab("Country");
}) });
// Common routine to create/edit/delete GRID & GALLERY view // Common routine to create/edit/delete GRID & GALLERY view
// Input: viewType - 'grid'/'gallery' // Input: viewType - 'grid'/'gallery'
// //
const viewTest = (viewType) => { const viewTest = (viewType) => {
it(`Create ${viewType} view`, () => {
it(`Create ${viewType} view`, () => { // click on 'Grid/Gallery' button on Views bar
// click on 'Grid/Gallery' button on Views bar cy.get(`.nc-create-${viewType}-view`).click();
cy.get(`.nc-create-${viewType}-view`).click();
// Pop up window, click Submit (accepting default name for view)
// Pop up window, click Submit (accepting default name for view) cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal().find('button:contains(Submit)').click()
cy.toastWait("View created successfully");
cy.toastWait('View created successfully')
// validate if view was creted && contains default name 'Country1'
// validate if view was creted && contains default name 'Country1' cy.get(`.nc-view-item.nc-${viewType}-view-item`)
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').should('exist') .contains("Country1")
}) .should("exist");
});
it(`Validate ${viewType} view: Drag & drop for re-order items`, () => {
// default order: Country, LastUpdate, Country => City it(`Validate ${viewType} view: Drag & drop for re-order items`, () => {
cy.get('.nc-field-wrapper').eq(0).contains('Country').should('exist') // default order: Country, LastUpdate, Country => City
cy.get('.nc-field-wrapper').eq(1).contains('LastUpdate').should('exist') cy.get(".nc-field-wrapper").eq(0).contains("Country").should("exist");
cy.get(".nc-field-wrapper")
// move Country field down (drag, drop) .eq(1)
cy.get('#data-table-form-Country').drag('#data-table-form-LastUpdate') .contains("LastUpdate")
.should("exist");
// Verify if order is: LastUpdate, Country, Country => City
cy.get('.nc-field-wrapper').eq(0).contains('LastUpdate').should('exist') // move Country field down (drag, drop)
cy.get('.nc-field-wrapper').eq(1).contains('Country').should('exist') cy.get("#data-table-form-Country").drag("#data-table-form-LastUpdate");
})
// Verify if order is: LastUpdate, Country, Country => City
it(`Validate ${viewType} view: Drag & drop for add/remove items`, () => { cy.get(".nc-field-wrapper")
// default, only one item in menu-bar; ensure LastUpdate field was present in form view .eq(0)
cy.get('.col-md-4').find('.pointer.item').should('not.exist') .contains("LastUpdate")
cy.get('.nc-field-wrapper').eq(0).contains('LastUpdate').should('exist') .should("exist");
cy.get(".nc-field-wrapper").eq(1).contains("Country").should("exist");
// drag 'LastUpdate' & drop into menu bar drag-drop box });
cy.get('#data-table-form-LastUpdate').drag('.nc-drag-n-drop-to-hide')
it(`Validate ${viewType} view: Drag & drop for add/remove items`, () => {
// validate- fields count in menu bar to be increased by 1 && // default, only one item in menu-bar; ensure LastUpdate field was present in form view
// first member in 'formView' is Country cy.get(".col-md-4").find(".pointer.item").should("not.exist");
cy.get('.nc-field-wrapper').eq(0).contains('Country').should('exist') cy.get(".nc-field-wrapper")
cy.get('.col-md-4').find('.pointer.item').its('length').should('eq', 1) .eq(0)
}) .contains("LastUpdate")
.should("exist");
it(`Validate ${viewType} view: Inverted order field member addition from menu`, () => {
cy.get('.col-md-4').find('.pointer.caption').contains('remove all').click() // drag 'LastUpdate' & drop into menu bar drag-drop box
cy.get("#data-table-form-LastUpdate").drag(".nc-drag-n-drop-to-hide");
// click fields in inverted order: LastUpdate, Country => City
cy.get('.col-md-4').find('.pointer.item').eq(1).click() // validate- fields count in menu bar to be increased by 1 &&
cy.get('.col-md-4').find('.pointer.item').eq(0).click() // first member in 'formView' is Country
cy.get(".nc-field-wrapper").eq(0).contains("Country").should("exist");
// verify if order of appearance in form is right cy.get(".col-md-4").find(".pointer.item").its("length").should("eq", 1);
// Country was never removed as its required field. Other two will appear in inverted order });
cy.get('.nc-field-wrapper').eq(0).contains('Country').should('exist')
cy.get('.nc-field-wrapper').eq(1).contains('Country => City').should('exist') it(`Validate ${viewType} view: Inverted order field member addition from menu`, () => {
cy.get('.nc-field-wrapper').eq(2).contains('LastUpdate').should('exist') cy.get(".col-md-4")
}) .find(".pointer.caption")
.contains("remove all")
it(`Validate ${viewType}: Form header & description validation`, () => { .click();
// Header & description should exist
cy.get('.nc-form').find('[placeholder="Form Title"]').should('exist') // click fields in inverted order: LastUpdate, Country => City
cy.get('.nc-form').find('[placeholder="Add form description"]').should('exist') cy.get(".col-md-4").find(".pointer.item").eq(1).click();
cy.get(".col-md-4").find(".pointer.item").eq(0).click();
// Update header & add some description, verify
cy.get('.nc-form').find('[placeholder="Form Title"]').type('A B C D') // verify if order of appearance in form is right
cy.get('.nc-form').find('[placeholder="Add form description"]').type('Some description about form comes here') // Country was never removed as its required field. Other two will appear in inverted order
cy.get(".nc-field-wrapper").eq(0).contains("Country").should("exist");
// validate new contents cy.get(".nc-field-wrapper")
cy.get('.nc-form').find('[placeholder="Form Title"]').contains('A B C D').should('exist') .eq(1)
cy.get('.nc-form').find('[placeholder="Add form description"]').contains('Some description about form comes here').should('exist') .contains("Country => City")
}) .should("exist");
cy.get(".nc-field-wrapper")
it(`Validate ${viewType}: Add all, Remove all validation`, () => { .eq(2)
// .col-md-4 : left hand menu .contains("LastUpdate")
// .nc-form : form view (right hand side) .should("exist");
});
// ensure buttons exist on left hand menu
cy.get('.col-md-4').find('.pointer.caption').contains('add all').should('not.exist') it(`Validate ${viewType}: Form header & description validation`, () => {
cy.get('.col-md-4').find('.pointer.caption').contains('remove all').should('exist') // Header & description should exist
cy.get(".nc-form").find('[placeholder="Form Title"]').should("exist");
// click: remove-all cy.get(".nc-form")
cy.get('.col-md-4').find('.pointer.caption').contains('remove all').click() .find('[placeholder="Add form description"]')
// form should not contain any "field remove icons" -- except for mandatory field (Country) .should("exist");
cy.get('.nc-form').find('.nc-field-remove-icon').its('length').should('eq', 1)
// menu bar should contain 3 .pointer.item (LastUpdate, County->City) // Update header & add some description, verify
cy.get('.col-md-4').find('.pointer.item').its('length').should('eq', 2) cy.get(".nc-form").find('[placeholder="Form Title"]').type("A B C D");
cy.get(".nc-form")
// click: add all .find('[placeholder="Add form description"]')
// cy.get('.col-md-4').find('.pointer.caption').contains('remove all').should('not.exist') .type("Some description about form comes here");
cy.get('.col-md-4').find('.pointer.caption').contains('add all').click()
cy.get('.col-md-4').find('.pointer.caption').contains('remove all').should('exist') // validate new contents
// form should contain "field remove icons" cy.get(".nc-form")
cy.get('.nc-form').find('.nc-field-remove-icon').should('exist') .find('[placeholder="Form Title"]')
// Fix me: a dummy remove icon is left over on screen .contains("A B C D")
cy.get('.nc-form').find('.nc-field-remove-icon').its('length').should('eq', 3) .should("exist");
// menu bar should not contain .pointer.item (column name/ field name add options) cy.get(".nc-form")
cy.get('.col-md-4').find('.pointer.item').should('not.exist') .find('[placeholder="Add form description"]')
}) .contains("Some description about form comes here")
.should("exist");
it(`Validate ${viewType}: Submit default, empty show this message textbox`, () => { });
// fill up mandatory fields
cy.get('#data-table-form-Country').type('_abc') it(`Validate ${viewType}: Add all, Remove all validation`, () => {
cy.get('#data-table-form-LastUpdate').click() // .col-md-4 : left hand menu
cy.getActiveModal().find('button').contains('19').click() // .nc-form : form view (right hand side)
cy.getActiveModal().find('button').contains('OK').click()
// ensure buttons exist on left hand menu
// default message, no update cy.get(".col-md-4")
.find(".pointer.caption")
// submit button & validate .contains("add all")
cy.get('.nc-form').find('button').contains('Submit').click() .should("not.exist");
cy.toastWait('Saved successfully') cy.get(".col-md-4")
cy.get('.v-alert').contains('Successfully submitted form data').should('exist') .find(".pointer.caption")
.contains("remove all")
// end of test removes newly added rows from table. that step validates if row was successfully added. .should("exist");
})
// click: remove-all
it(`Validate ${viewType}: Submit default, with valid Show message entry`, () => { cy.get(".col-md-4")
// clicking again on view name shows blank still. work around- toggling between two views .find(".pointer.caption")
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country').click() .contains("remove all")
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() .click();
// form should not contain any "field remove icons" -- except for mandatory field (Country)
// fill up mandatory fields cy.get(".nc-form")
cy.get('#data-table-form-Country').type('_abc') .find(".nc-field-remove-icon")
cy.get('#data-table-form-LastUpdate').click() .its("length")
cy.getActiveModal().find('button').contains('19').click() .should("eq", 1);
cy.getActiveModal().find('button').contains('OK').click() // menu bar should contain 3 .pointer.item (LastUpdate, County->City)
cy.get(".col-md-4").find(".pointer.item").its("length").should("eq", 2);
// add message
cy.get('.nc-form > .mx-auto').find('textarea').type('Congratulations!') // click: add all
// cy.get('.col-md-4').find('.pointer.caption').contains('remove all').should('not.exist')
// submit button & validate cy.get(".col-md-4")
cy.get('.nc-form').find('button').contains('Submit').click() .find(".pointer.caption")
cy.toastWait('Congratulations') .contains("add all")
cy.get('.v-alert').contains('Congratulations').should('exist') .click();
cy.get(".col-md-4")
// end of test removes newly added rows from table. that step validates if row was successfully added. .find(".pointer.caption")
}) .contains("remove all")
.should("exist");
it(`Validate ${viewType}: Submit default, Enable checkbox "Submit another form`, () => { // form should contain "field remove icons"
// clicking again on view name shows blank still. work around- toggling between two views cy.get(".nc-form").find(".nc-field-remove-icon").should("exist");
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country').click() // Fix me: a dummy remove icon is left over on screen
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() cy.get(".nc-form")
.find(".nc-field-remove-icon")
// fill up mandatory fields .its("length")
cy.get('#data-table-form-Country').type('_abc') .should("eq", 3);
cy.get('#data-table-form-LastUpdate').click() // menu bar should not contain .pointer.item (column name/ field name add options)
cy.getActiveModal().find('button').contains('19').click() cy.get(".col-md-4").find(".pointer.item").should("not.exist");
cy.getActiveModal().find('button').contains('OK').click() });
// enable "Submit another form" check box it(`Validate ${viewType}: Submit default, empty show this message textbox`, () => {
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(0).click() // fill up mandatory fields
cy.get("#data-table-form-Country").type("_abc");
// submit button & validate cy.get("#data-table-form-LastUpdate").click();
cy.get('.nc-form').find('button').contains('Submit').click() cy.getActiveModal().find("button").contains("19").click();
cy.toastWait('Congratulations') cy.getActiveModal().find("button").contains("OK").click();
cy.get('.v-alert').contains('Congratulations').should('exist')
cy.get('button').contains('Submit Another Form').should('exist') // default message, no update
cy.get('button').contains('Submit Another Form').click() // submit button & validate
cy.get('.nc-form').should('exist') cy.get(".nc-form").find("button").contains("Submit").click();
// New form appeared? Header & description should exist cy.toastWait("Saved successfully");
cy.get('.nc-form').find('[placeholder="Form Title"]').contains('A B C D').should('exist') cy.get(".v-alert")
cy.get('.nc-form').find('[placeholder="Add form description"]').contains('Some description about form comes here').should('exist') .contains("Successfully submitted form data")
.should("exist");
// end of test removes newly added rows from table. that step validates if row was successfully added.
}) // end of test removes newly added rows from table. that step validates if row was successfully added.
});
it(`Validate ${viewType}: Submit default, Enable checkbox "blank form after 5 seconds"`, () => {
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country').click() it(`Validate ${viewType}: Submit default, with valid Show message entry`, () => {
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() // clicking again on view name shows blank still. work around- toggling between two views
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country').click()
cy.get('#data-table-form-Country').type('_abc') cy.get(`.nc-view-item.nc-${viewType}-view-item`)
cy.get('#data-table-form-LastUpdate').click() .contains("Country1")
cy.getActiveModal().find('button').contains('19').click() .click();
cy.getActiveModal().find('button').contains('OK').click()
// fill up mandatory fields
// enable "New form after 5 seconds" button cy.get("#data-table-form-Country").type("_abc");
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(0).click( {force: true} ) cy.get("#data-table-form-LastUpdate").click();
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(1).click() cy.getActiveModal().find("button").contains("19").click();
cy.getActiveModal().find("button").contains("OK").click();
// submit button & validate
cy.get('.nc-form').find('button').contains('Submit').click() // add message
cy.toastWait('Congratulations') cy.get(".nc-form > .mx-auto").find("textarea").type("Congratulations!");
cy.get('.v-alert').contains('Congratulations').should('exist').then(() => {
// wait for 5 seconds // submit button & validate
cy.get('.nc-form').should('exist') cy.get(".nc-form").find("button").contains("Submit").click();
cy.toastWait("Congratulations");
// validate if form has appeared again cy.get(".v-alert").contains("Congratulations").should("exist");
cy.get('.nc-form').find('[placeholder="Form Title"]').contains('A B C D').should('exist')
cy.get('.nc-form').find('[placeholder="Add form description"]').contains('Some description about form comes here').should('exist') // end of test removes newly added rows from table. that step validates if row was successfully added.
}) });
// end of test removes newly added rows from table. that step validates if row was successfully added. it(`Validate ${viewType}: Submit default, Enable checkbox "Submit another form`, () => {
}) // clicking again on view name shows blank still. work around- toggling between two views
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country').click()
it(`Validate ${viewType}: Email me verification, without SMTP configuration`, () => { cy.get(`.nc-view-item.nc-${viewType}-view-item`)
// open formview & enable "email me" option .contains("Country1")
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() .click();
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(2).click({ force: true })
// validate if toaster pops up requesting to activate SMTP // fill up mandatory fields
cy.toastWait('Please activate SMTP plugin in App store for enabling email notification') cy.get("#data-table-form-Country").type("_abc");
}) cy.get("#data-table-form-LastUpdate").click();
cy.getActiveModal().find("button").contains("19").click();
it(`Validate ${viewType}: Email me verification, with SMTP configuration`, () => { cy.getActiveModal().find("button").contains("OK").click();
// activate SMTP, dummy profile
mainPage.navigationDraw(mainPage.APPSTORE).click() // enable "Submit another form" check box
mainPage.configureSMTP('admin@ex.com', 'smtp.ex.com', '8080', 'TLS') cy.get(".nc-form > .mx-auto").find('[type="checkbox"]').eq(0).click();
// open form view & enable "email me" option // submit button & validate
cy.openTableTab('Country', 25); cy.get(".nc-form").find("button").contains("Submit").click();
cy.toastWait("Congratulations");
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() cy.get(".v-alert").contains("Congratulations").should("exist");
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(2).click({ force: true }) cy.get("button").contains("Submit Another Form").should("exist");
// validate if toaster pops up informing installation of email notification
// cy.get('.toasted:visible', { timout: 6000 }) cy.get("button").contains("Submit Another Form").click();
// .contains('Successfully installed and email notification will use SMTP configuration') cy.get(".nc-form").should("exist");
// .should('exist') // New form appeared? Header & description should exist
// reset SMPT config's cy.get(".nc-form")
mainPage.navigationDraw(mainPage.APPSTORE).click() .find('[placeholder="Form Title"]')
mainPage.resetSMTP() .contains("A B C D")
cy.openTableTab('Country', 25); .should("exist");
}) cy.get(".nc-form")
.find('[placeholder="Add form description"]')
it(`Validate ${viewType}: Add/ remove field verification"`, () => { .contains("Some description about form comes here")
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() .should("exist");
cy.get('#data-table-form-LastUpdate').should('exist') // end of test removes newly added rows from table. that step validates if row was successfully added.
// remove "LastUpdate field" });
cy.get('.nc-form').find('.nc-field-remove-icon').eq(1).click()
cy.get('#data-table-form-lastUpdate').should('not.exist') it(`Validate ${viewType}: Submit default, Enable checkbox "blank form after 5 seconds"`, () => {
cy.get('.col-md-4').find('.pointer.item').contains('LastUpdate').should('exist') // cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country').click()
// cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click()
// add it back
cy.get('.col-md-4').find('.pointer.item').contains('LastUpdate').click() cy.get("#data-table-form-Country").type("_abc");
cy.get('#data-table-form-LastUpdate').should('exist') cy.get("#data-table-form-LastUpdate").click();
}) cy.getActiveModal().find("button").contains("19").click();
cy.getActiveModal().find("button").contains("OK").click();
it(`Validate ${viewType}: URL verification`, () => {
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Country1').click() // enable "New form after 5 seconds" button
// verify URL & copy it for subsequent test cy.get(".nc-form > .mx-auto")
cy.url().should('contain', `&view=Country1`) .find('[type="checkbox"]')
cy.url().then((url) => { .eq(0)
cy.log(url) .click({ force: true });
formViewURL = url cy.get(".nc-form > .mx-auto").find('[type="checkbox"]').eq(1).click();
})
}) // submit button & validate
cy.get(".nc-form").find("button").contains("Submit").click();
it(`Validate ${viewType}: URL validation after re-access`, () => { cy.toastWait("Congratulations");
// visit URL cy.get(".v-alert")
cy.log(formViewURL) .contains("Congratulations")
cy.visit(formViewURL, { .should("exist")
baseUrl: null .then(() => {
}) // wait for 5 seconds
cy.get(".nc-form").should("exist");
// New form appeared? Header & description should exist
cy.get('.nc-form', { timeout: 10000 }) // validate if form has appeared again
.find('[placeholder="Form Title"]') cy.get(".nc-form")
.contains('A B C D') .find('[placeholder="Form Title"]')
.should('exist') .contains("A B C D")
cy.get('.nc-form', { timeout: 10000 }) .should("exist");
.find('[placeholder="Add form description"]') cy.get(".nc-form")
.contains('Some description about form comes here') .find('[placeholder="Add form description"]')
.should('exist') .contains("Some description about form comes here")
}) .should("exist");
});
it(`Delete ${viewType} view`, () => {
// number of view entries should be 2 before we delete // end of test removes newly added rows from table. that step validates if row was successfully added.
cy.get('.nc-view-item').its('length').should('eq', 2) });
// click on delete icon (becomes visible on hovering mouse) it(`Validate ${viewType}: Email me verification, without SMTP configuration`, () => {
cy.get('.nc-view-delete-icon').click({ force: true }) // open formview & enable "email me" option
cy.toastWait('View deleted successfully') cy.get(`.nc-view-item.nc-${viewType}-view-item`)
.contains("Country1")
// confirm if the number of veiw entries is reduced by 1 .click();
cy.get('.nc-view-item').its('length').should('eq', 1) cy.get(".nc-form > .mx-auto")
.find('[type="checkbox"]')
// clean up newly added rows into Country table operations .eq(2)
// this auto verifies successfull addition of rows to table as well .click({ force: true });
mainPage.getPagination(5).click() // validate if toaster pops up requesting to activate SMTP
cy.get('.nc-grid-row').should('have.length', 13) cy.toastWait(
mainPage.getRow(10).find('.mdi-checkbox-blank-outline').click({ force: true }) "Please activate SMTP plugin in App store for enabling email notification"
mainPage.getRow(11).find('.mdi-checkbox-blank-outline').click({ force: true }) );
mainPage.getRow(12).find('.mdi-checkbox-blank-outline').click({ force: true }) });
mainPage.getRow(13).find('.mdi-checkbox-blank-outline').click({ force: true })
it(`Validate ${viewType}: Email me verification, with SMTP configuration`, () => {
mainPage.getCell("Country", 10).rightclick() // activate SMTP, dummy profile
cy.getActiveMenu().contains('Delete Selected Row').click() mainPage.navigationDraw(mainPage.APPSTORE).click();
// cy.toastWait('Deleted selected rows successfully') mainPage.configureSMTP("admin@ex.com", "smtp.ex.com", "8080", "TLS");
})
} // open form view & enable "email me" option
cy.openTableTab("Country", 25);
cy.get(`.nc-view-item.nc-${viewType}-view-item`)
.contains("Country1")
.click();
cy.get(".nc-form > .mx-auto")
.find('[type="checkbox"]')
.eq(2)
.click({ force: true });
// validate if toaster pops up informing installation of email notification
// cy.get('.toasted:visible', { timout: 6000 })
// .contains('Successfully installed and email notification will use SMTP configuration')
// .should('exist')
// reset SMPT config's
mainPage.navigationDraw(mainPage.APPSTORE).click();
mainPage.resetSMTP();
cy.openTableTab("Country", 25);
});
it(`Validate ${viewType}: Add/ remove field verification"`, () => {
cy.get(`.nc-view-item.nc-${viewType}-view-item`)
.contains("Country1")
.click();
cy.get("#data-table-form-LastUpdate").should("exist");
// remove "LastUpdate field"
cy.get(".nc-form").find(".nc-field-remove-icon").eq(1).click();
cy.get("#data-table-form-lastUpdate").should("not.exist");
cy.get(".col-md-4")
.find(".pointer.item")
.contains("LastUpdate")
.should("exist");
// add it back
cy.get(".col-md-4")
.find(".pointer.item")
.contains("LastUpdate")
.click();
cy.get("#data-table-form-LastUpdate").should("exist");
});
it(`Validate ${viewType}: URL verification`, () => {
cy.get(`.nc-view-item.nc-${viewType}-view-item`)
.contains("Country1")
.click();
// verify URL & copy it for subsequent test
cy.url().should("contain", `&view=Country1`);
cy.url().then((url) => {
cy.log(url);
formViewURL = url;
});
});
it(`Validate ${viewType}: URL validation after re-access`, () => {
// visit URL
cy.log(formViewURL);
cy.visit(formViewURL, {
baseUrl: null,
});
// New form appeared? Header & description should exist
cy.get(".nc-form", { timeout: 10000 })
.find('[placeholder="Form Title"]')
.contains("A B C D")
.should("exist");
cy.get(".nc-form", { timeout: 10000 })
.find('[placeholder="Add form description"]')
.contains("Some description about form comes here")
.should("exist");
});
it(`Delete ${viewType} view`, () => {
// number of view entries should be 2 before we delete
cy.get(".nc-view-item").its("length").should("eq", 2);
// click on delete icon (becomes visible on hovering mouse)
cy.get(".nc-view-delete-icon").click({ force: true });
cy.toastWait("View deleted successfully");
// confirm if the number of veiw entries is reduced by 1
cy.get(".nc-view-item").its("length").should("eq", 1);
// clean up newly added rows into Country table operations
// this auto verifies successfull addition of rows to table as well
mainPage.getPagination(5).click();
cy.get(".nc-grid-row").should("have.length", 13);
mainPage
.getRow(10)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage
.getRow(11)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage
.getRow(12)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage
.getRow(13)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains("Delete Selected Row").click();
// cy.toastWait('Deleted selected rows successfully')
});
};
// below scenario's will be invoked twice, once for rest & then for graphql // below scenario's will be invoked twice, once for rest & then for graphql
viewTest('form') viewTest("form");
});
}) };
}
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -351,4 +456,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

135
scripts/cypress/integration/common/4d_table_view_grid_locked.js

@ -1,71 +1,93 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { mainPage } from "../../support/page_objects/mainPage";
import { mainPage } from "../../support/page_objects/mainPage"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Lock view`, () => { describe(`${type.toUpperCase()} api - Lock view`, () => {
// Run once before test- create project (rest/graphql) // Run once before test- create project (rest/graphql)
// //
before(() => { before(() => {
// open a table to work on views // open a table to work on views
// //
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
}) });
after(() => { after(() => {
cy.closeTableTab('Country') cy.closeTableTab("Country");
}) });
const lockViewTest = (enabled) => { const lockViewTest = (enabled) => {
it(`Grid: lock view set to ${enabled}: validation`, () => { it(`Grid: lock view set to ${enabled}: validation`, () => {
let vString = enabled ? 'not.' : '' let vString = enabled ? "not." : "";
let menuOption = enabled ? 1 : 0 let menuOption = enabled ? 1 : 0;
// on menu, collaboration view appears first (at index 0)
// followed by Locked view (at index 1)
cy.get('.xc-toolbar').find('.nc-view-lock-menu:enabled').click()
cy.getActiveMenu().find('[role="menuitem"]').eq(menuOption).click()
// expected toolbar for Lock view: Only lock-view menu, reload, toggle-nav-drawer to be enabled // on menu, collaboration view appears first (at index 0)
// // followed by Locked view (at index 1)
cy.get('.xc-toolbar').find('.nc-view-lock-menu:enabled') .should('exist') cy.get(".xc-toolbar").find(".nc-view-lock-menu:enabled").click();
cy.get('.xc-toolbar').find('.nc-table-reload-btn:enabled') .should('exist') cy.getActiveMenu().find('[role="menuitem"]').eq(menuOption).click();
cy.get('.xc-toolbar').find('.nc-add-new-row-btn:enabled') .should(`${vString}exist`)
// cy.get('.xc-toolbar').find('.nc-save-new-row-btn:disabled') .should('exist')
cy.get('.xc-toolbar').find('.nc-fields-menu-btn:enabled') .should(`${vString}exist`)
cy.get('.xc-toolbar').find('.nc-sort-menu-btn:enabled') .should(`${vString}exist`)
cy.get('.xc-toolbar').find('.nc-filter-menu-btn:enabled') .should(`${vString}exist`)
cy.get('.xc-toolbar').find('.nc-table-delete-btn:enabled') .should(`${vString}exist`)
cy.get('.xc-toolbar').find('.nc-toggle-nav-drawer:enabled') .should('exist')
// dblClick on a cell & see if we can edit
mainPage.getCell('Country', 1).dblclick()
mainPage.getCell('Country', 1).find('input').should(`${vString}exist`)
// check if expand row option is available? // expected toolbar for Lock view: Only lock-view menu, reload, toggle-nav-drawer to be enabled
cy.get('td').find('.nc-row-expand-icon').should(`${vString}exist`) //
// alt validation: mainPage.getRow(1).find('.nc-row-expand-icon').should(`${vString}exist`) cy.get(".xc-toolbar")
.find(".nc-view-lock-menu:enabled")
.should("exist");
cy.get(".xc-toolbar")
.find(".nc-table-reload-btn:enabled")
.should("exist");
cy.get(".xc-toolbar")
.find(".nc-add-new-row-btn:enabled")
.should(`${vString}exist`);
// cy.get('.xc-toolbar').find('.nc-save-new-row-btn:disabled') .should('exist')
cy.get(".xc-toolbar")
.find(".nc-fields-menu-btn:enabled")
.should(`${vString}exist`);
cy.get(".xc-toolbar")
.find(".nc-sort-menu-btn:enabled")
.should(`${vString}exist`);
cy.get(".xc-toolbar")
.find(".nc-filter-menu-btn:enabled")
.should(`${vString}exist`);
cy.get(".xc-toolbar")
.find(".nc-table-delete-btn:enabled")
.should(`${vString}exist`);
cy.get(".xc-toolbar")
.find(".nc-toggle-nav-drawer:enabled")
.should("exist");
// check if add/ expand options available for 'has many' column type // dblClick on a cell & see if we can edit
mainPage.getCell('Country => City', 1).click().find('button.mdi-plus').should(`${vString}exist`) mainPage.getCell("Country", 1).dblclick();
mainPage.getCell('Country => City', 1).click().find('button.mdi-arrow-expand').should(`${vString}exist`) mainPage.getCell("Country", 1).find("input").should(`${vString}exist`);
// update row option (right click) - should not be available for Lock view // check if expand row option is available?
mainPage.getCell('Country => City', 1).rightclick() cy.get("td").find(".nc-row-expand-icon").should(`${vString}exist`);
cy.get('.menuable__content__active').should(`${vString}be.visible`) // alt validation: mainPage.getRow(1).find('.nc-row-expand-icon').should(`${vString}exist`)
})
}
// Locked view // check if add/ expand options available for 'has many' column type
lockViewTest(true) mainPage
.getCell("Country => City", 1)
.click()
.find("button.mdi-plus")
.should(`${vString}exist`);
mainPage
.getCell("Country => City", 1)
.click()
.find("button.mdi-arrow-expand")
.should(`${vString}exist`);
// collaboration view // update row option (right click) - should not be available for Lock view
lockViewTest(false) mainPage.getCell("Country => City", 1).rightclick();
}) cy.get(".menuable__content__active").should(`${vString}be.visible`);
} });
};
// Locked view
lockViewTest(true);
// collaboration view
lockViewTest(false);
});
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -89,4 +111,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

361
scripts/cypress/integration/common/4e_form_view_share.js

@ -1,176 +1,196 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { mainPage } from "../../support/page_objects/mainPage";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" let storedURL = "";
import { mainPage } from "../../support/page_objects/mainPage"
let storedURL = ''
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - FORM view (Share)`, () => { describe(`${type.toUpperCase()} api - FORM view (Share)`, () => {
const name = "Test" + Date.now();
const name = 'Test' + Date.now();
// Run once before test- create project (rest/graphql)
// Run once before test- create project (rest/graphql) //
// before(() => {
before(() => { // open a table to work on views
// open a table to work on views //
// cy.openTableTab("City", 25);
cy.openTableTab('City', 25) });
})
beforeEach(() => {
beforeEach(() => { cy.restoreLocalStorage();
cy.restoreLocalStorage(); });
})
afterEach(() => {
afterEach(() => { cy.saveLocalStorage();
cy.saveLocalStorage(); });
})
after(() => {
after(() => { cy.closeTableTab("City");
cy.closeTableTab('City') });
})
// Common routine to create/edit/delete GRID & GALLERY view
// Input: viewType - 'grid'/'gallery'
// Common routine to create/edit/delete GRID & GALLERY view //
// Input: viewType - 'grid'/'gallery' const viewTest = (viewType) => {
// it(`Create ${viewType} view`, () => {
const viewTest = (viewType) => { // click on 'Grid/Gallery' button on Views bar
cy.get(`.nc-create-${viewType}-view`).click();
it(`Create ${viewType} view`, () => {
// click on 'Grid/Gallery' button on Views bar // Pop up window, click Submit (accepting default name for view)
cy.get(`.nc-create-${viewType}-view`).click(); cy.getActiveModal().find("button:contains(Submit)").click();
// Pop up window, click Submit (accepting default name for view) cy.toastWait("View created successfully");
cy.getActiveModal().find('button:contains(Submit)').click()
// Prepare form
cy.toastWait('View created successfully') // add header, description
// add post submission message
// Prepare form // swap position for City, LastUpdate fields
// add header, description // remove City=>Address field
// add post submission message cy.get(".nc-form > .mx-auto").find('[type="checkbox"]').eq(1).click();
// swap position for City, LastUpdate fields cy.get(".nc-form > .mx-auto")
// remove City=>Address field .find('[type="checkbox"]')
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(1).click() .eq(1)
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(1).should('be.checked') .should("be.checked");
cy.get('.nc-form').find('[placeholder="Form Title"]').type('A B C D') cy.get(".nc-form").find('[placeholder="Form Title"]').type("A B C D");
cy.get('.nc-form').find('[placeholder="Add form description"]').type('Some description about form comes here') cy.get(".nc-form")
cy.get('.nc-form > .mx-auto').find('textarea').type('Congratulations!') .find('[placeholder="Add form description"]')
.type("Some description about form comes here");
cy.get('#data-table-form-City').drag('#data-table-form-LastUpdate') cy.get(".nc-form > .mx-auto").find("textarea").type("Congratulations!");
cy.get('[title="City => Address"]').drag('.nc-drag-n-drop-to-hide')
cy.get("#data-table-form-City").drag("#data-table-form-LastUpdate");
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(1).should('be.checked') cy.get('[title="City => Address"]').drag(".nc-drag-n-drop-to-hide");
// store base URL- to re-visit and delete form view later cy.get(".nc-form > .mx-auto")
cy.url().then((url) => { .find('[type="checkbox"]')
storedURL = url .eq(1)
}) .should("be.checked");
})
// store base URL- to re-visit and delete form view later
it(`Share form view`, () => { cy.url().then((url) => {
cy.get('.nc-form > .mx-auto').find('[type="checkbox"]').eq(1).should('be.checked') storedURL = url;
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('City1').click() });
cy.get('.v-navigation-drawer__content > .container') });
.find('.v-list > .v-list-item')
.contains('Share View') it(`Share form view`, () => {
.click() cy.get(".nc-form > .mx-auto")
.find('[type="checkbox"]')
// copy link text, visit URL .eq(1)
cy.getActiveModal().find('.share-link-box') .should("be.checked");
.contains('/nc/form/', {timeout: 10000}) cy.get(`.nc-view-item.nc-${viewType}-view-item`)
.then(($obj) => { .contains("City1")
.click();
let linkText = $obj.text().trim() cy.get(".v-navigation-drawer__content > .container")
cy.log(linkText) .find(".v-list > .v-list-item")
cy.visit(linkText, { .contains("Share View")
baseUrl: null .click();
})
// copy link text, visit URL
// wait for share view page to load! cy.getActiveModal()
cy.get('.nc-form').should('exist') .find(".share-link-box")
.contains("/nc/form/", { timeout: 10000 })
// New form appeared? Header & description should exist .then(($obj) => {
cy.get('.nc-form', { timeout: 10000 }) let linkText = $obj.text().trim();
.find('h2') cy.log(linkText);
.contains('A B C D') cy.visit(linkText, {
.should('exist') baseUrl: null,
cy.get('.nc-form', { timeout: 10000 }) });
.find('.body-1')
.contains('Some description about form comes here') // wait for share view page to load!
.should('exist') cy.get(".nc-form").should("exist");
// all fields, barring removed field should exist // New form appeared? Header & description should exist
cy.get('[title="City"]').should('exist') cy.get(".nc-form", { timeout: 10000 })
cy.get('[title="LastUpdate"]').should('exist') .find("h2")
cy.get('[title="Country <= City"]').should('exist') .contains("A B C D")
cy.get('[title="City => Address"]').should('not.exist') .should("exist");
cy.get(".nc-form", { timeout: 10000 })
// order of LastUpdate & City field is retained .find(".body-1")
cy.get('.nc-field-wrapper').eq(0).contains('LastUpdate').should('exist') .contains("Some description about form comes here")
cy.get('.nc-field-wrapper').eq(1).contains('City').should('exist') .should("exist");
// submit form, to read message // all fields, barring removed field should exist
cy.get('#data-table-form-City').type('_abc') cy.get('[title="City"]').should("exist");
cy.get('#data-table-form-LastUpdate').click() cy.get('[title="LastUpdate"]').should("exist");
cy.getActiveModal().find('button').contains('19').click() cy.get('[title="Country <= City"]').should("exist");
cy.getActiveModal().find('button').contains('OK').click() cy.get('[title="City => Address"]').should("not.exist");
cy.get('button').contains("Link to 'Country'").click()
cy.getActiveModal().find('.child-card').contains('Afghanistan').click() // order of LastUpdate & City field is retained
cy.get(".nc-field-wrapper")
// submit button & validate .eq(0)
cy.get('.nc-form').find('button').contains('Submit').click() .contains("LastUpdate")
cy.toastWait('Congratulations') .should("exist");
cy.get('.v-alert').contains('Congratulations').should('exist').then(() => { cy.get(".nc-field-wrapper").eq(1).contains("City").should("exist");
cy.get('.nc-form').should('exist')
// submit form, to read message
// validate if form has appeared again cy.get("#data-table-form-City").type("_abc");
cy.get('.nc-form', { timeout: 10000 }) cy.get("#data-table-form-LastUpdate").click();
.find('h2') cy.getActiveModal().find("button").contains("19").click();
.contains('A B C D') cy.getActiveModal().find("button").contains("OK").click();
.should('exist') cy.get("button").contains("Link to 'Country'").click();
cy.get('.nc-form', { timeout: 10000 }) cy.getActiveModal()
.find('.body-1') .find(".child-card")
.contains('Some description about form comes here') .contains("Afghanistan")
.should('exist') .click();
})
}) // submit button & validate
}) cy.get(".nc-form").find("button").contains("Submit").click();
cy.toastWait("Congratulations");
it(`Delete ${viewType} view`, () => { cy.get(".v-alert")
// go back to base page .contains("Congratulations")
cy.visit(storedURL, { .should("exist")
baseUrl: null .then(() => {
}) cy.get(".nc-form").should("exist");
// number of view entries should be 2 before we delete // validate if form has appeared again
cy.get('.nc-view-item').its('length').should('eq', 2) cy.get(".nc-form", { timeout: 10000 })
.find("h2")
// click on delete icon (becomes visible on hovering mouse) .contains("A B C D")
cy.get('.nc-view-delete-icon').click({ force: true }) .should("exist");
cy.toastWait('View deleted successfully') cy.get(".nc-form", { timeout: 10000 })
.find(".body-1")
// confirm if the number of veiw entries is reduced by 1 .contains("Some description about form comes here")
cy.get('.nc-view-item').its('length').should('eq', 1) .should("exist");
});
// clean up newly added rows into Country table operations });
// this auto verifies successfull addition of rows to table as well });
mainPage.getPagination(25).click()
cy.get('.nc-grid-row').should('have.length', 1) it(`Delete ${viewType} view`, () => {
mainPage.getRow(1).find('.mdi-checkbox-blank-outline').click({ force: true }) // go back to base page
cy.visit(storedURL, {
mainPage.getCell("City", 1).rightclick() baseUrl: null,
cy.getActiveMenu().contains('Delete Selected Row').click() });
// cy.toastWait('Deleted selected rows successfully')
}) // number of view entries should be 2 before we delete
} cy.get(".nc-view-item").its("length").should("eq", 2);
// below scenario's will be invoked twice, once for rest & then for graphql // click on delete icon (becomes visible on hovering mouse)
viewTest('form') cy.get(".nc-view-delete-icon").click({ force: true });
}) cy.toastWait("View deleted successfully");
}
// confirm if the number of veiw entries is reduced by 1
cy.get(".nc-view-item").its("length").should("eq", 1);
// clean up newly added rows into Country table operations
// this auto verifies successfull addition of rows to table as well
mainPage.getPagination(25).click();
cy.get(".nc-grid-row").should("have.length", 1);
mainPage
.getRow(1)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage.getCell("City", 1).rightclick();
cy.getActiveMenu().contains("Delete Selected Row").click();
// cy.toastWait('Deleted selected rows successfully')
});
};
// below scenario's will be invoked twice, once for rest & then for graphql
viewTest("form");
});
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -194,4 +214,3 @@ export const genTest = (type, xcdb) => {
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

757
scripts/cypress/integration/common/4f_grid_view_share.js

@ -1,8 +1,7 @@
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { mainPage } from "../../support/page_objects/mainPage";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" let storedURL = "";
import { mainPage } from "../../support/page_objects/mainPage"
let storedURL = ''
// 0: all enabled // 0: all enabled
// 1: field hide // 1: field hide
@ -10,348 +9,418 @@ let storedURL = ''
// 3: field filter // 3: field filter
// 4: default (address table): for view operation validation // 4: default (address table): for view operation validation
// 5: default (country table): for update row/column validation // 5: default (country table): for update row/column validation
let viewURL = {} let viewURL = {};
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
const generateViewLink = (viewName) => { const generateViewLink = (viewName) => {
// click on share view // click on share view
cy.get('.v-navigation-drawer__content > .container') cy.get(".v-navigation-drawer__content > .container")
.find('.v-list > .v-list-item') .find(".v-list > .v-list-item")
.contains('Share View') .contains("Share View")
.click() .click();
// wait, as URL initially will be /undefined // wait, as URL initially will be /undefined
cy.getActiveModal().find('.share-link-box') cy.getActiveModal()
.contains('/nc/view/', {timeout: 10000}).should('exist') .find(".share-link-box")
.contains("/nc/view/", { timeout: 10000 })
// copy link text, visit URL .should("exist");
cy.getActiveModal().find('.share-link-box')
.contains('/nc/view/', {timeout: 10000}) // copy link text, visit URL
.then(($obj) => { cy.getActiveModal()
cy.get('body').type('{esc}') .find(".share-link-box")
// viewURL.push($obj.text()) .contains("/nc/view/", { timeout: 10000 })
viewURL[viewName] = $obj.text().trim() .then(($obj) => {
}) cy.get("body").type("{esc}");
} // viewURL.push($obj.text())
viewURL[viewName] = $obj.text().trim();
describe(`${type.toUpperCase()} api - GRID view (Share)`, () => { });
// Run once before test- create project (rest/graphql) };
//
before(() => { describe(`${type.toUpperCase()} api - GRID view (Share)`, () => {
// open a table to work on views // Run once before test- create project (rest/graphql)
// //
cy.openTableTab('Address', 25); before(() => {
// open a table to work on views
cy.saveLocalStorage() //
}) cy.openTableTab("Address", 25);
beforeEach(() => { cy.saveLocalStorage();
cy.restoreLocalStorage(); });
})
beforeEach(() => {
afterEach(() => { cy.restoreLocalStorage();
cy.saveLocalStorage(); });
})
afterEach(() => {
after(() => { cy.saveLocalStorage();
// close table });
// mainPage.deleteCreatedViews()
cy.closeTableTab('Address') after(() => {
}) // close table
// mainPage.deleteCreatedViews()
// Common routine to create/edit/delete GRID & GALLERY view cy.closeTableTab("Address");
// Input: viewType - 'grid'/'gallery' });
//
const viewTest = (viewType) => { // Common routine to create/edit/delete GRID & GALLERY view
// Input: viewType - 'grid'/'gallery'
it(`Create ${viewType.toUpperCase()} view`, () => { //
// create a normal public view const viewTest = (viewType) => {
cy.get(`.nc-create-${viewType}-view`).click(); it(`Create ${viewType.toUpperCase()} view`, () => {
cy.getActiveModal().find('button:contains(Submit)').click() // create a normal public view
cy.toastWait('View created successfully') cy.get(`.nc-create-${viewType}-view`).click();
cy.getActiveModal().find("button:contains(Submit)").click();
// store base URL- to re-visit and delete form view later cy.toastWait("View created successfully");
cy.url().then((url) => {
storedURL = url // store base URL- to re-visit and delete form view later
}) cy.url().then((url) => {
}) storedURL = url;
});
it(`Share ${viewType.toUpperCase()} hide, sort, filter & verify`, () => { });
cy.get(`.nc-view-item.nc-${viewType}-view-item`).contains('Address1').click()
mainPage.hideField('Address2') it(`Share ${viewType.toUpperCase()} hide, sort, filter & verify`, () => {
mainPage.sortField('District', 'Z -> A') cy.get(`.nc-view-item.nc-${viewType}-view-item`)
mainPage.filterField('Address', 'is like', 'Ab') .contains("Address1")
generateViewLink('combined') .click();
cy.log(viewURL['combined']) mainPage.hideField("Address2");
}) mainPage.sortField("District", "Z -> A");
mainPage.filterField("Address", "is like", "Ab");
it(`Share GRID view : ensure we have only one link even if shared multiple times`, () => { generateViewLink("combined");
// generate view link multiple times cy.log(viewURL["combined"]);
generateViewLink('combined') });
generateViewLink('combined')
it(`Share GRID view : ensure we have only one link even if shared multiple times`, () => {
// verify if only one link exists in table // generate view link multiple times
cy.get('.v-navigation-drawer__content > .container') generateViewLink("combined");
.find('.v-list > .v-list-item') generateViewLink("combined");
.contains('Share View')
.parent().find('button.mdi-dots-vertical').click() // verify if only one link exists in table
cy.get(".v-navigation-drawer__content > .container")
cy.getActiveMenu().find('.v-list-item').contains('Views List').click() .find(".v-list > .v-list-item")
.contains("Share View")
cy.get('th:contains("View Link")').should('exist') .parent()
.find("button.mdi-dots-vertical")
cy.get('th:contains("View Link")').parent().parent() .click();
.next().find('tr').its('length').should('eq', 1)
.then(() => { cy.getActiveMenu().find(".v-list-item").contains("Views List").click();
cy.get('.v-overlay__content > .d-flex > .v-icon').click()
}) cy.get('th:contains("View Link")').should("exist");
})
cy.get('th:contains("View Link")')
it(`Share ${viewType.toUpperCase()} view : Visit URL, Verify title`, () => { .parent()
// visit public view .parent()
cy.visit(viewURL['combined'], { .next()
baseUrl: null .find("tr")
}) .its("length")
.should("eq", 1)
// wait for page rendering to complete .then(() => {
cy.get('.nc-grid-row').should('have.length', 18) cy.get(".v-overlay__content > .d-flex > .v-icon").click();
});
// verify title });
cy.get('div.model-name').contains('Address1').should('exist')
}) it(`Share ${viewType.toUpperCase()} view : Visit URL, Verify title`, () => {
// visit public view
it(`Share ${viewType.toUpperCase()} view : verify fields hidden/open`, () => { cy.visit(viewURL["combined"], {
// verify column headers baseUrl: null,
cy.get('[data-col="Address"]').should('exist') });
cy.get('[data-col="Address2"]').should('not.exist')
cy.get('[data-col="District"]').should('exist') // wait for page rendering to complete
}) cy.get(".nc-grid-row").should("have.length", 18);
it(`Share ${viewType.toUpperCase()} view : verify fields sort/ filter`, () => { // verify title
// country column content verification before sort cy.get("div.model-name").contains("Address1").should("exist");
mainPage.getCell("District", 1).contains("West Bengali").should('exist') });
mainPage.getCell("District", 2).contains("Tutuila").should('exist')
mainPage.getCell("District", 3).contains("Tamil Nadu").should('exist') it(`Share ${viewType.toUpperCase()} view : verify fields hidden/open`, () => {
}) // verify column headers
cy.get('[data-col="Address"]').should("exist");
it(`Share ${viewType.toUpperCase()} view : verify download CSV`, () => { cy.get('[data-col="Address2"]').should("not.exist");
mainPage.hideField('LastUpdate') cy.get('[data-col="District"]').should("exist");
const verifyCsv = (retrievedRecords) => { });
// expected output, statically configured
let storedRecords = [ it(`Share ${viewType.toUpperCase()} view : verify fields sort/ filter`, () => {
`Address,District,PostalCode,Phone,Location,Address => Customer,Address => Staff,City <= Address,Address <=> Staff`, // country column content verification before sort
`1013 Tabuk Boulevard,West Bengali,96203,158399646978,[object Object],2,,Kanchrapara,`, mainPage
`1892 Nabereznyje Telny Lane,Tutuila,28396,478229987054,[object Object],2,,Tafuna,`, .getCell("District", 1)
`1993 Tabuk Lane,Tamil Nadu,64221,648482415405,[object Object],2,,Tambaram,`, .contains("West Bengali")
`1661 Abha Drive,Tamil Nadu,14400,270456873752,[object Object],1,,Pudukkottai,` .should("exist");
] mainPage.getCell("District", 2).contains("Tutuila").should("exist");
mainPage.getCell("District", 3).contains("Tamil Nadu").should("exist");
for (let i = 0; i < storedRecords.length; i++) { });
let strCol = storedRecords[i].split(',')
let retCol = retrievedRecords[i].split(',') it(`Share ${viewType.toUpperCase()} view : verify download CSV`, () => {
for (let j = 0; j < 4; j++) { mainPage.hideField("LastUpdate");
expect(strCol[j]).to.be.equal(retCol[j]) const verifyCsv = (retrievedRecords) => {
} // expected output, statically configured
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i]) let storedRecords = [
} `Address,District,PostalCode,Phone,Location,Address => Customer,Address => Staff,City <= Address,Address <=> Staff`,
} `1013 Tabuk Boulevard,West Bengali,96203,158399646978,[object Object],2,,Kanchrapara,`,
`1892 Nabereznyje Telny Lane,Tutuila,28396,478229987054,[object Object],2,,Tafuna,`,
// download & verify `1993 Tabuk Lane,Tamil Nadu,64221,648482415405,[object Object],2,,Tambaram,`,
mainPage.downloadAndVerifyCsv(`Address_exported_1.csv`, verifyCsv) `1661 Abha Drive,Tamil Nadu,14400,270456873752,[object Object],1,,Pudukkottai,`,
mainPage.unhideField('LastUpdate') ];
})
for (let i = 0; i < storedRecords.length; i++) {
it(`Share ${viewType.toUpperCase()} view : Disable sort`, () => { let strCol = storedRecords[i].split(",");
// remove sort and validate let retCol = retrievedRecords[i].split(",");
mainPage.clearSort() for (let j = 0; j < 4; j++) {
mainPage.getCell("District", 1).contains("Southern Mindanao").should('exist') expect(strCol[j]).to.be.equal(retCol[j]);
}) }
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
it(`Share ${viewType.toUpperCase()} view : Enable sort`, () => { }
// Sort menu operations (Country Column, Z->A) };
mainPage.sortField('District', 'Z -> A')
mainPage.getCell("District", 1).contains("West Bengali").should('exist') // download & verify
}) mainPage.downloadAndVerifyCsv(`Address_exported_1.csv`, verifyCsv);
mainPage.unhideField("LastUpdate");
it(`Share ${viewType.toUpperCase()} view : Create Filter`, () => { });
// add filter & validate
mainPage.filterField('District', 'is like', 'Tamil') it(`Share ${viewType.toUpperCase()} view : Disable sort`, () => {
// wait for page rendering to complete // remove sort and validate
cy.get('.nc-grid-row').should('have.length', 2) mainPage.clearSort();
mainPage.getCell("District", 1).contains("Tamil").should('exist') mainPage
}) .getCell("District", 1)
.contains("Southern Mindanao")
it(`Share ${viewType.toUpperCase()} view : verify download CSV after local filter`, () => { .should("exist");
mainPage.hideField('LastUpdate') });
const verifyCsv = (retrievedRecords) => {
// expected output, statically configured it(`Share ${viewType.toUpperCase()} view : Enable sort`, () => {
let storedRecords = [ // Sort menu operations (Country Column, Z->A)
`Address,District,PostalCode,Phone,Location,Address => Customer,Address => Staff,City <= Address,Address <=> Staff`, mainPage.sortField("District", "Z -> A");
`1993 Tabuk Lane,Tamil Nadu,64221,648482415405,[object Object],2,,Tambaram,`, mainPage
`1661 Abha Drive,Tamil Nadu,14400,270456873752,[object Object],1,,Pudukkottai,` .getCell("District", 1)
] .contains("West Bengali")
.should("exist");
// for (let i = 0; i < storedRecords.length; i++) { });
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
// } it(`Share ${viewType.toUpperCase()} view : Create Filter`, () => {
// add filter & validate
for (let i = 0; i < storedRecords.length; i++) { mainPage.filterField("District", "is like", "Tamil");
let strCol = storedRecords[i].split(',') // wait for page rendering to complete
let retCol = retrievedRecords[i].split(',') cy.get(".nc-grid-row").should("have.length", 2);
for (let j = 0; j < 4; j++) { mainPage.getCell("District", 1).contains("Tamil").should("exist");
expect(strCol[j]).to.be.equal(retCol[j]) });
}
} it(`Share ${viewType.toUpperCase()} view : verify download CSV after local filter`, () => {
} mainPage.hideField("LastUpdate");
mainPage.downloadAndVerifyCsv(`Address_exported_1.csv`, verifyCsv) const verifyCsv = (retrievedRecords) => {
mainPage.unhideField('LastUpdate') // expected output, statically configured
}) let storedRecords = [
`Address,District,PostalCode,Phone,Location,Address => Customer,Address => Staff,City <= Address,Address <=> Staff`,
it(`Share ${viewType.toUpperCase()} view : Delete Filter`, () => { `1993 Tabuk Lane,Tamil Nadu,64221,648482415405,[object Object],2,,Tambaram,`,
// Remove sort and Validate `1661 Abha Drive,Tamil Nadu,14400,270456873752,[object Object],1,,Pudukkottai,`,
mainPage.filterReset() ];
mainPage.getCell("District", 1).contains("West Bengali").should('exist')
}) // for (let i = 0; i < storedRecords.length; i++) {
// expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
it(`Share GRID view : Virtual column validation > has many`, () => { // }
// verify column headers
cy.get('[data-col="Address => Customer"]').should('exist') for (let i = 0; i < storedRecords.length; i++) {
cy.get('[data-col="Address => Staff"]').should('exist') let strCol = storedRecords[i].split(",");
cy.get('[data-col="City <= Address"]').should('exist') let retCol = retrievedRecords[i].split(",");
cy.get('[data-col="Address <=> Staff"]').should('exist') for (let j = 0; j < 4; j++) {
expect(strCol[j]).to.be.equal(retCol[j]);
// has many field validation }
mainPage.getCell("Address => Customer", 3).click().find('button.mdi-close-thick').should('not.exist') }
mainPage.getCell("Address => Customer", 3).click().find('button.mdi-plus').should('not.exist') };
mainPage.getCell("Address => Customer", 3).click().find('button.mdi-arrow-expand').click() mainPage.downloadAndVerifyCsv(`Address_exported_1.csv`, verifyCsv);
mainPage.unhideField("LastUpdate");
cy.getActiveModal().find('button.mdi-reload').should('exist') });
cy.getActiveModal().find('button').contains('Link to').should('not.exist')
cy.getActiveModal().find('.child-card').contains('2').should('exist') it(`Share ${viewType.toUpperCase()} view : Delete Filter`, () => {
cy.getActiveModal().find('.child-card').find('button').should('not.exist') // Remove sort and Validate
cy.get('body').type('{esc}') mainPage.filterReset();
}) mainPage
.getCell("District", 1)
it(`Share GRID view : Virtual column validation > belongs to`, () => { .contains("West Bengali")
// belongs to field validation .should("exist");
mainPage.getCell("City <= Address", 1).click().find('button.mdi-close-thick').should('not.exist') });
mainPage.getCell("City <= Address", 1).click().find('button.mdi-arrow-expand').should('not.exist')
mainPage.getCell("City <= Address", 1).find('.v-chip').contains('Kanchrapara').should('exist') it(`Share GRID view : Virtual column validation > has many`, () => {
}) // verify column headers
cy.get('[data-col="Address => Customer"]').should("exist");
it(`Share GRID view : Virtual column validation > many to many`, () => { cy.get('[data-col="Address => Staff"]').should("exist");
// many-to-many field validation cy.get('[data-col="City <= Address"]').should("exist");
mainPage.getCell("Address <=> Staff", 1).click().find('button.mdi-close-thick').should('not.exist') cy.get('[data-col="Address <=> Staff"]').should("exist");
mainPage.getCell("Address <=> Staff", 1).click().find('button.mdi-plus').should('not.exist')
mainPage.getCell("Address <=> Staff", 1).click().find('button.mdi-arrow-expand').click() // has many field validation
mainPage
cy.getActiveModal().find('button.mdi-reload').should('exist') .getCell("Address => Customer", 3)
cy.getActiveModal().find('button').contains('Link to').should('not.exist') .click()
cy.get('body').type('{esc}') .find("button.mdi-close-thick")
}) .should("not.exist");
mainPage
it(`Delete ${viewType.toUpperCase()} view`, () => { .getCell("Address => Customer", 3)
// go back to base page .click()
cy.visit(storedURL, { .find("button.mdi-plus")
baseUrl: null .should("not.exist");
}) mainPage
.getCell("Address => Customer", 3)
// number of view entries should be 2 before we delete .click()
cy.get('.nc-view-item').its('length').should('eq', 2) .find("button.mdi-arrow-expand")
.click();
cy.get('.nc-view-delete-icon').eq(0).click({ force: true })
cy.toastWait('View deleted successfully') cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.getActiveModal()
// confirm if the number of veiw entries is reduced by 1 .find("button")
cy.get('.nc-view-item').its('length').should('eq', 1) .contains("Link to")
}) .should("not.exist");
} cy.getActiveModal().find(".child-card").contains("2").should("exist");
cy.getActiveModal()
// below scenario's will be invoked twice, once for rest & then for graphql .find(".child-card")
viewTest('grid') .find("button")
}) .should("not.exist");
cy.get("body").type("{esc}");
describe(`${type.toUpperCase()} api - Grid view/ row-column update verification`, () => { });
before(() => {
// Address table has belongs to, has many & many-to-many it(`Share GRID view : Virtual column validation > belongs to`, () => {
cy.openTableTab('Country', 25) // belongs to field validation
mainPage
cy.saveLocalStorage() .getCell("City <= Address", 1)
// store base URL- to re-visit and delete form view later .click()
cy.url().then((url) => { .find("button.mdi-close-thick")
storedURL = url .should("not.exist");
generateViewLink('rowColUpdate') mainPage
}) .getCell("City <= Address", 1)
}) .click()
.find("button.mdi-arrow-expand")
after(() => { .should("not.exist");
// close table mainPage
cy.restoreLocalStorage(); .getCell("City <= Address", 1)
cy.visit(storedURL, { .find(".v-chip")
baseUrl: null .contains("Kanchrapara")
}) .should("exist");
});
// delete row
mainPage.getPagination(5).click() it(`Share GRID view : Virtual column validation > many to many`, () => {
// wait for page rendering to complete // many-to-many field validation
cy.get('.nc-grid-row').should('have.length', 10) mainPage
mainPage.getRow(10).find('.mdi-checkbox-blank-outline').click({ force: true }) .getCell("Address <=> Staff", 1)
mainPage.getCell("Country", 10).rightclick() .click()
cy.getActiveMenu().contains('Delete Selected Row').click() .find("button.mdi-close-thick")
.should("not.exist");
// delete column mainPage
cy.get(`th:contains('dummy') .mdi-menu-down`) .getCell("Address <=> Staff", 1)
.trigger('mouseover') .click()
.click() .find("button.mdi-plus")
cy.get('.nc-column-delete').click() .should("not.exist");
cy.get('button:contains(Confirm)').click() mainPage
.getCell("Address <=> Staff", 1)
cy.toastWait('Update table.Country successful') .click()
.find("button.mdi-arrow-expand")
mainPage.deleteCreatedViews() .click();
// close table cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.closeTableTab('Country') cy.getActiveModal()
}) .find("button")
.contains("Link to")
it(`Generate default Shared GRID view URL`, () => { .should("not.exist");
// add row cy.get("body").type("{esc}");
cy.get('.nc-add-new-row-btn').click({force: true}) });
cy.get('#data-table-form-Country > input').first().click().type('a')
cy.contains('Save Row').filter('button').click({ force: true }) it(`Delete ${viewType.toUpperCase()} view`, () => {
cy.toastWait('updated successfully') // go back to base page
cy.visit(storedURL, {
// add column baseUrl: null,
mainPage.addColumn('dummy', 'Country') });
// visit public view // number of view entries should be 2 before we delete
cy.log(viewURL['rowColUpdate']) cy.get(".nc-view-item").its("length").should("eq", 2);
cy.restoreLocalStorage();
cy.visit(viewURL['rowColUpdate'], { cy.get(".nc-view-delete-icon").eq(0).click({ force: true });
baseUrl: null cy.toastWait("View deleted successfully");
}) //5
// wait for public view page to load! // confirm if the number of veiw entries is reduced by 1
// wait for page rendering to complete cy.get(".nc-view-item").its("length").should("eq", 1);
cy.get('.nc-grid-row').should('have.length', 25) });
}) };
it(`Share GRID view : new row visible`, () => { // below scenario's will be invoked twice, once for rest & then for graphql
// verify row viewTest("grid");
cy.get(`.v-pagination > li:contains('5') button`).click() });
// wait for page rendering to complete
cy.get('.nc-grid-row').should('have.length', 10) describe(`${type.toUpperCase()} api - Grid view/ row-column update verification`, () => {
mainPage.getCell('Country', 10).contains('a').should('exist') before(() => {
}) // Address table has belongs to, has many & many-to-many
cy.openTableTab("Country", 25);
it.skip(`Share GRID view : new column visible`, () => {
// verify column headers cy.saveLocalStorage();
cy.get('[data-col="dummy"]').should('exist') // store base URL- to re-visit and delete form view later
}) cy.url().then((url) => {
}) storedURL = url;
} generateViewLink("rowColUpdate");
});
});
after(() => {
// close table
cy.restoreLocalStorage();
cy.visit(storedURL, {
baseUrl: null,
});
// delete row
mainPage.getPagination(5).click();
// wait for page rendering to complete
cy.get(".nc-grid-row").should("have.length", 10);
mainPage
.getRow(10)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains("Delete Selected Row").click();
// delete column
cy.get(`th:contains('dummy') .mdi-menu-down`)
.trigger("mouseover")
.click();
cy.get(".nc-column-delete").click();
cy.get("button:contains(Confirm)").click();
cy.toastWait("Update table.Country successful");
mainPage.deleteCreatedViews();
// close table
cy.closeTableTab("Country");
});
it(`Generate default Shared GRID view URL`, () => {
// add row
cy.get(".nc-add-new-row-btn").click({ force: true });
cy.get("#data-table-form-Country > input").first().click().type("a");
cy.contains("Save Row").filter("button").click({ force: true });
cy.toastWait("updated successfully");
// add column
mainPage.addColumn("dummy", "Country");
// visit public view
cy.log(viewURL["rowColUpdate"]);
cy.restoreLocalStorage();
cy.visit(viewURL["rowColUpdate"], {
baseUrl: null,
}); //5
// wait for public view page to load!
// wait for page rendering to complete
cy.get(".nc-grid-row").should("have.length", 25);
});
it(`Share GRID view : new row visible`, () => {
// verify row
cy.get(`.v-pagination > li:contains('5') button`).click();
// wait for page rendering to complete
cy.get(".nc-grid-row").should("have.length", 10);
mainPage.getCell("Country", 10).contains("a").should("exist");
});
it.skip(`Share GRID view : new column visible`, () => {
// verify column headers
cy.get('[data-col="dummy"]').should("exist");
});
});
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

313
scripts/cypress/integration/common/5a_user_role.js

@ -1,155 +1,168 @@
import { loginPage, projectsPage } from "../../support/page_objects/navigation" import { loginPage, projectsPage } from "../../support/page_objects/navigation";
import { mainPage } from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
import { roles, staticProjects } from "../../support/page_objects/projectConstants" import {
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" roles,
import { _advSettings, _editSchema, _editData, _editComment, _viewMenu, _topRightMenu } from "../spec/roleValidation.spec" staticProjects,
} from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import {
_advSettings,
_editSchema,
_editData,
_editComment,
_viewMenu,
_topRightMenu,
} from "../spec/roleValidation.spec";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if (!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe('Static user creations (different roles)', () => { describe("Static user creations (different roles)", () => {
// beforeEach(() => { // beforeEach(() => {
// loginPage.signIn(roles.owner.credentials) // loginPage.signIn(roles.owner.credentials)
// projectsPage.openProject(getPrimarySuite().basic.name) // projectsPage.openProject(getPrimarySuite().basic.name)
// }) // })
before(() => { before(() => {
mainPage.navigationDraw(mainPage.TEAM_N_AUTH).click() mainPage.navigationDraw(mainPage.TEAM_N_AUTH).click();
}) });
const addUser = (user) => { const addUser = (user) => {
it(`RoleType: ${user.name}`, () => { it(`RoleType: ${user.name}`, () => {
// for first project, users need to be added explicitly using "New User" button // for first project, users need to be added explicitly using "New User" button
// for subsequent projects, they will be required to just add to this project // for subsequent projects, they will be required to just add to this project
// using ROW count to identify if its former or latter scenario // using ROW count to identify if its former or latter scenario
// 5 users (owner, creator, editor, viewer, commenter) + row header = 6 // 5 users (owner, creator, editor, viewer, commenter) + row header = 6
cy.get(`tr`).then((obj) => { cy.get(`tr`).then((obj) => {
cy.log(obj.length) cy.log(obj.length);
if (obj.length == 6) { if (obj.length == 6) {
mainPage.addExistingUserToProject(user.credentials.username, user.name) mainPage.addExistingUserToProject(
} else { user.credentials.username,
mainPage.addNewUserToProject(user.credentials, user.name) user.name
} );
}) } else {
}) mainPage.addNewUserToProject(user.credentials, user.name);
} }
});
addUser(roles.creator) });
addUser(roles.editor) };
addUser(roles.commenter)
addUser(roles.viewer) addUser(roles.creator);
}) addUser(roles.editor);
addUser(roles.commenter);
const roleValidation = (roleType) => { addUser(roles.viewer);
describe(`User role validation`, () => { });
if (roleType != 'owner') { const roleValidation = (roleType) => {
it(`[${roles[roleType].name}] SignIn, Open project`, () => { describe(`User role validation`, () => {
cy.log(mainPage.roleURL[roleType]) if (roleType != "owner") {
cy.visit(mainPage.roleURL[roleType], { it(`[${roles[roleType].name}] SignIn, Open project`, () => {
baseUrl: null cy.log(mainPage.roleURL[roleType]);
}) cy.visit(mainPage.roleURL[roleType], {
baseUrl: null,
// Redirected to new URL, feed details });
//
cy.get('input[type="text"]').should('exist').type(roles[roleType].credentials.username) // Redirected to new URL, feed details
cy.get('input[type="password"]').type(roles[roleType].credentials.password) //
cy.get('button:contains("SIGN")').click() cy.get('input[type="text"]')
.should("exist")
cy.url({ timeout: 6000 }).should('contain', '#/project') .type(roles[roleType].credentials.username);
cy.get('input[type="password"]').type(
if('rest' == type) roles[roleType].credentials.password
projectsPage.openProject(staticProjects.externalREST.basic.name) );
else cy.get('button:contains("SIGN")').click();
projectsPage.openProject(staticProjects.externalGQL.basic.name)
cy.url({ timeout: 6000 }).should("contain", "#/project");
if (roleType != 'creator') {
cy.closeTableTab('Actor') if ("rest" == type)
} projectsPage.openProject(staticProjects.externalREST.basic.name);
}) else projectsPage.openProject(staticProjects.externalGQL.basic.name);
}
if (roleType != "creator") {
/////////////////////////////////////////////////////// cy.closeTableTab("Actor");
// Test suite }
});
it(`[${roles[roleType].name}] Left navigation menu, New User add`, () => { }
// project configuration settings
// ///////////////////////////////////////////////////////
_advSettings(roleType, false) // Test suite
})
it(`[${roles[roleType].name}] Left navigation menu, New User add`, () => {
it(`[${roles[roleType].name}] Schema: create table, add/modify/delete column`, () => { // project configuration settings
// Schema related validations //
// - Add/delete table _advSettings(roleType, false);
// - Add/Update/delete column });
//
_editSchema(roleType, false) it(`[${roles[roleType].name}] Schema: create table, add/modify/delete column`, () => {
}) // Schema related validations
// - Add/delete table
it(`[${roles[roleType].name}] Data: add/modify/delete row, update cell contents`, () => { // - Add/Update/delete column
// Table data related validations //
// - Add/delete/modify row _editSchema(roleType, false);
// });
_editData(roleType, false)
}) it(`[${roles[roleType].name}] Data: add/modify/delete row, update cell contents`, () => {
// Table data related validations
it(`[${roles[roleType].name}] Comments: view/add`, () => { // - Add/delete/modify row
// read &/ update comment //
// Viewer: only allowed to read _editData(roleType, false);
// Everyone else: read &/ update });
//
if (roleType != 'viewer') it(`[${roles[roleType].name}] Comments: view/add`, () => {
_editComment(roleType, false) // read &/ update comment
}) // Viewer: only allowed to read
// Everyone else: read &/ update
it(`[${roles[roleType].name}] Right navigation menu, share view`, () => { //
// right navigation menu bar if (roleType != "viewer") _editComment(roleType, false);
// Editor/Viewer/Commenter : can only view 'existing' views });
// Rest: can create/edit
_viewMenu(roleType, false) it(`[${roles[roleType].name}] Right navigation menu, share view`, () => {
}) // right navigation menu bar
// Editor/Viewer/Commenter : can only view 'existing' views
it(`[${roles[roleType].name}] Top Right Menu bar`, () => { // Rest: can create/edit
// Share button is conditional _viewMenu(roleType, false);
// Rest are static/ mandatory });
//
_topRightMenu(roleType, false) it(`[${roles[roleType].name}] Top Right Menu bar`, () => {
}) // Share button is conditional
// Rest are static/ mandatory
it(`[${roles[roleType].name}] Download files`, () => { //
// #ID, City, LastUpdate, City => Address, Country <= City, + _topRightMenu(roleType, false);
mainPage.hideField('LastUpdate') });
const verifyCsv = (retrievedRecords) => { it(`[${roles[roleType].name}] Download files`, () => {
// expected output, statically configured // #ID, City, LastUpdate, City => Address, Country <= City, +
let storedRecords = [ mainPage.hideField("LastUpdate");
`City,City => Address,Country <= City`,
`A Corua (La Corua),939 Probolinggo Loop,Spain`, const verifyCsv = (retrievedRecords) => {
`Abha,733 Mandaluyong Place,Saudi Arabia`, // expected output, statically configured
`Abu Dhabi,535 Ahmadnagar Manor,United Arab Emirates`, let storedRecords = [
`Acua,1789 Saint-Denis Parkway,Mexico` `City,City => Address,Country <= City`,
] `A Corua (La Corua),939 Probolinggo Loop,Spain`,
`Abha,733 Mandaluyong Place,Saudi Arabia`,
for (let i = 0; i < storedRecords.length; i++) { `Abu Dhabi,535 Ahmadnagar Manor,United Arab Emirates`,
// cy.log(retrievedRecords[i]) `Acua,1789 Saint-Denis Parkway,Mexico`,
expect(retrievedRecords[i]).to.be.equal(storedRecords[i]) ];
}
} for (let i = 0; i < storedRecords.length; i++) {
// cy.log(retrievedRecords[i])
// download & verify expect(retrievedRecords[i]).to.be.equal(storedRecords[i]);
mainPage.downloadAndVerifyCsv(`City_exported_1.csv`, verifyCsv) }
mainPage.unhideField('LastUpdate') };
})
}) // download & verify
} mainPage.downloadAndVerifyCsv(`City_exported_1.csv`, verifyCsv);
mainPage.unhideField("LastUpdate");
// skip owner validation as rest of the cases pretty much cover the same });
// roleValidation('owner') });
roleValidation('creator') };
roleValidation('editor')
roleValidation('commenter') // skip owner validation as rest of the cases pretty much cover the same
roleValidation('viewer') // roleValidation('owner')
} roleValidation("creator");
roleValidation("editor");
roleValidation("commenter");
roleValidation("viewer");
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

189
scripts/cypress/integration/common/5b_preview_role.js

@ -1,98 +1,101 @@
// pre-requisite:
// pre-requisite:
// user@nocodb.com signed up as admin // user@nocodb.com signed up as admin
// sakilaDb database created already // sakilaDb database created already
import { loginPage, projectsPage } from "../../support/page_objects/navigation" import { loginPage, projectsPage } from "../../support/page_objects/navigation";
import { mainPage } from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { _advSettings, _editSchema, _editData, _editComment, _viewMenu, _topRightMenu } from "../spec/roleValidation.spec" import {
_advSettings,
_editSchema,
_editData,
_editComment,
_viewMenu,
_topRightMenu,
} from "../spec/roleValidation.spec";
export const genTest = (type, xcdb, roleType) => { export const genTest = (type, xcdb, roleType) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
//// Test Suite //// Test Suite
describe('Role preview validations', () => { describe("Role preview validations", () => {
// Sign in/ open project // Sign in/ open project
before(() => { before(() => {
loginPage.loginAndOpenProject(type, xcdb) loginPage.loginAndOpenProject(type, xcdb);
}) });
after(() => { after(() => {
cy.get('.nc-preview-reset').click({ force: true }) cy.get(".nc-preview-reset").click({ force: true });
// cy.wait(20000) // cy.wait(20000)
// wait for page rendering to complete // wait for page rendering to complete
cy.get('.nc-grid-row', { timeout: 25000 }).should('have.length', 25) cy.get(".nc-grid-row", { timeout: 25000 }).should("have.length", 25);
// cy.get('.nc-preview-reset:visible').should('not-exist') // cy.get('.nc-preview-reset:visible').should('not-exist')
// mainPage.navigationDraw(mainPage.ROLE_VIEW).contains('Reset Preview').should('not.exist') // mainPage.navigationDraw(mainPage.ROLE_VIEW).contains('Reset Preview').should('not.exist')
// cy.get('.nc-preview-reset').should('not-exist') // cy.get('.nc-preview-reset').should('not-exist')
cy.closeTableTab('City') cy.closeTableTab("City");
}) });
const genTestSub = (roleType) => { const genTestSub = (roleType) => {
it(`Role preview: ${roleType}: Enable preview`, () => {
it(`Role preview: ${roleType}: Enable preview`, () => { cy.get(`.nc-preview-${roleType}`).click();
cy.get(`.nc-preview-${roleType}`).click()
cy.openTableTab("City", 25);
cy.openTableTab('City', 25) });
})
it(`Role preview: ${roleType}: Advance settings`, () => {
it(`Role preview: ${roleType}: Advance settings`, () => { // project configuration settings
// project configuration settings //
// _advSettings(roleType, true);
_advSettings(roleType, true) });
})
it(`Role preview: ${roleType}: Edit data`, () => {
it(`Role preview: ${roleType}: Edit data`, () => { // Table data related validations
// Table data related validations // - Add/delete/modify row
// - Add/delete/modify row //
// _editData(roleType, true);
_editData(roleType, true) });
})
it(`Role preview: ${roleType}: Edit comment`, () => {
it(`Role preview: ${roleType}: Edit comment`, () => { // read &/ update comment
// read &/ update comment // Viewer: not allowed to read
// Viewer: not allowed to read // Everyone else: read &/ update
// Everyone else: read &/ update //
// _editComment(roleType, true);
_editComment(roleType, true) });
})
it(`Role preview: ${roleType}: Preview menu`, () => {
it(`Role preview: ${roleType}: Preview menu`, () => { // right navigation menu bar
// right navigation menu bar // Editor/Viewer/Commenter : can only view 'existing' views
// Editor/Viewer/Commenter : can only view 'existing' views // Rest: can create/edit
// Rest: can create/edit _viewMenu(roleType, true);
_viewMenu(roleType, true) });
})
it(`Role preview: ${roleType}: Top Right Menu bar`, () => {
it(`Role preview: ${roleType}: Top Right Menu bar`, () => { // Share button is conditional
// Share button is conditional // Rest are static/ mandatory
// Rest are static/ mandatory //
// _topRightMenu(roleType, false);
_topRightMenu(roleType, false) });
})
it(`Role preview: ${roleType}: Edit Schema`, () => {
it(`Role preview: ${roleType}: Edit Schema`, () => { // Schema related validations
// Schema related validations // - Add/delete table
// - Add/delete table // - Add/Update/delete column
// - Add/Update/delete column //
// _editSchema(roleType, true);
_editSchema(roleType, true) });
}) };
}
genTestSub("editor");
genTestSub('editor') genTestSub("commenter");
genTestSub('commenter') genTestSub("viewer");
genTestSub('viewer') });
}) };
}
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -115,4 +118,4 @@ export const genTest = (type, xcdb, roleType) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

71
scripts/cypress/integration/common/6b_downloadCsv.js

@ -1,45 +1,44 @@
import { mainPage } from "../../support/page_objects/mainPage";
import { mainPage } from "../../support/page_objects/mainPage" import { loginPage } from "../../support/page_objects/navigation";
import { loginPage } from "../../support/page_objects/navigation" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} Upload/ Download CSV`, () => {
before(() => {
// loginPage.loginAndOpenProject(type)
cy.openTableTab("Country", 25);
});
describe(`${type.toUpperCase()} Upload/ Download CSV`, () => { after(() => {
before(() => { cy.closeTableTab("Country");
// loginPage.loginAndOpenProject(type) });
cy.openTableTab('Country', 25);
})
after(() => { it("Download verification- base view, default columns", () => {
cy.closeTableTab('Country') mainPage.hideField("LastUpdate");
}) const verifyCsv = (retrievedRecords) => {
// expected output, statically configured
let storedRecords = [
`Country,Country => City`,
`Afghanistan,Kabul`,
`Algeria,"Batna,Bchar,Skikda"`,
`American Samoa,Tafuna`,
`Angola,"Benguela,Namibe"`,
];
it('Download verification- base view, default columns', () => { for (let i = 0; i < storedRecords.length; i++) {
mainPage.hideField('LastUpdate') cy.log(retrievedRecords[i]);
const verifyCsv = (retrievedRecords) => { expect(retrievedRecords[i]).to.be.equal(storedRecords[i]);
// expected output, statically configured }
let storedRecords = [ };
`Country,Country => City`,
`Afghanistan,Kabul`,
`Algeria,"Batna,Bchar,Skikda"`,
`American Samoa,Tafuna`,
`Angola,"Benguela,Namibe"`
]
for (let i = 0; i < storedRecords.length; i++) {
cy.log(retrievedRecords[i])
expect(retrievedRecords[i]).to.be.equal(storedRecords[i])
}
}
// download & verify // download & verify
mainPage.downloadAndVerifyCsv(`Country_exported_1.csv`, verifyCsv) mainPage.downloadAndVerifyCsv(`Country_exported_1.csv`, verifyCsv);
mainPage.unhideField('LastUpdate') mainPage.unhideField("LastUpdate");
}) });
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

406
scripts/cypress/integration/common/6c_swagger_api.js

@ -1,188 +1,228 @@
import { loginPage } from "../../support/page_objects/navigation";
import { loginPage } from "../../support/page_objects/navigation" import { mainPage } from "../../support/page_objects/mainPage";
import { mainPage } from "../../support/page_objects/mainPage" import { roles } from "../../support/page_objects/projectConstants";
import { roles } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants"
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} : API List - Test preparation`, () => { describe(`${type.toUpperCase()} : API List - Test preparation`, () => {
before(()=> { before(() => {
loginPage.loginAndOpenProject(type, false) loginPage.loginAndOpenProject(type, false);
}) });
it("Open project & record swagger URL, AuthToken", () => { it("Open project & record swagger URL, AuthToken", () => {
let authToken = mainPage.getAuthToken() let authToken = mainPage.getAuthToken();
cy.url().then( (url) => { cy.url().then((url) => {
// retrieve project name from URL & use it to construct Swagger URL // retrieve project name from URL & use it to construct Swagger URL
// URL on homepage: http://localhost:3000/#/nc/externalrest_weUO?type=roles&dbalias=&name=Team%20%26%20Auth%20 // URL on homepage: http://localhost:3000/#/nc/externalrest_weUO?type=roles&dbalias=&name=Team%20%26%20Auth%20
// [REST] Swagger URL: http://localhost:8080/nc/externalrest_weUO/db/swagger // [REST] Swagger URL: http://localhost:8080/nc/externalrest_weUO/db/swagger
// [GQL] http://localhost:8080/nc/externalgql_dgwx/v1/graphql // [GQL] http://localhost:8080/nc/externalgql_dgwx/v1/graphql
const projectName = url.split("/")[5].split("?")[0]; const projectName = url.split("/")[5].split("?")[0];
let swaggerURL = `` let swaggerURL = ``;
if ('rest' == type) { if ("rest" == type) {
swaggerURL = `http://localhost:8080/nc/${projectName}/db/swagger` swaggerURL = `http://localhost:8080/nc/${projectName}/db/swagger`;
} } else {
else { swaggerURL = `http://localhost:8080/nc/${projectName}/v1/graphql`;
swaggerURL = `http://localhost:8080/nc/${projectName}/v1/graphql` }
}
// exchange information between two tests using a file
// exchange information between two tests using a file // https://stackoverflow.com/questions/52050657/what-is-the-best-practice-of-pass-states-between-tests-in-cypress
// https://stackoverflow.com/questions/52050657/what-is-the-best-practice-of-pass-states-between-tests-in-cypress //
// cy.writeFile("shared.json", {
cy.writeFile("shared.json", {SWAGGER_URL: swaggerURL, AUTH_TOKEN: authToken}) SWAGGER_URL: swaggerURL,
}) AUTH_TOKEN: authToken,
}) });
}) });
});
if ('rest' == type) { });
describe(`Swagger page, base verification`, () => { if ("rest" == type) {
describe(`Swagger page, base verification`, () => {
// returns swagger button intended for // returns swagger button intended for
// //
const getSwaggerButton = (tag, idx, desc) => { const getSwaggerButton = (tag, idx, desc) => {
return cy.get(`#operations-tag-${tag}`).next().find('.opblock').eq(idx).find(`button:contains(${desc})`) return cy
} .get(`#operations-tag-${tag}`)
.next()
let Token .find(".opblock")
.eq(idx)
// basic authentication tag verification .find(`button:contains(${desc})`);
// };
it("Swagger URL access & basic validation", () => {
// retrieve information stored in previous IT block let Token;
//
cy.readFile("shared.json").then((jsonPayload) => { // basic authentication tag verification
let URL = jsonPayload.SWAGGER_URL //
Token = jsonPayload.AUTH_TOKEN it("Swagger URL access & basic validation", () => {
// retrieve information stored in previous IT block
cy.visit(URL, { //
baseUrl: null cy.readFile("shared.json").then((jsonPayload) => {
}).then(() => { let URL = jsonPayload.SWAGGER_URL;
Token = jsonPayload.AUTH_TOKEN;
// wait to allow time for SWAGGER Library loading to finish
cy.log(Token) cy.visit(URL, {
baseUrl: null,
// validate; API order assumed }).then(() => {
cy.get('#operations-tag-Authentication', {timeout: 20000}).should('exist').next().find('.opblock').should('has.length', 9) // wait to allow time for SWAGGER Library loading to finish
getSwaggerButton("Authentication", 0, "User login").should('exist') cy.log(Token);
getSwaggerButton("Authentication", 1, "User signup").should('exist')
getSwaggerButton("Authentication", 2, "Password Forgot").should('exist') // validate; API order assumed
getSwaggerButton("Authentication", 3, "Email validate link").should('exist') cy.get("#operations-tag-Authentication", { timeout: 20000 })
getSwaggerButton("Authentication", 4, "Validate password reset token").should('exist') .should("exist")
getSwaggerButton("Authentication", 5, "Password reset").should('exist') .next()
getSwaggerButton("Authentication", 6, "User details").should('exist') .find(".opblock")
getSwaggerButton("Authentication", 7, "Update user details").should('exist') .should("has.length", 9);
getSwaggerButton("Authentication", 8, "Update user details").should('exist') getSwaggerButton("Authentication", 0, "User login").should("exist");
}) getSwaggerButton("Authentication", 1, "User signup").should(
}) "exist"
}) );
getSwaggerButton("Authentication", 2, "Password Forgot").should(
it("Authorize success: Valid token", ()=> { "exist"
// authorize button, feed token, click authorize );
cy.get('[class="btn authorize unlocked"]').click() getSwaggerButton("Authentication", 3, "Email validate link").should(
cy.get('input').type(Token) "exist"
cy.get('.auth-btn-wrapper > .authorize').click() );
getSwaggerButton(
// Response: "Authorized" should exist on DOM "Authentication",
cy.get('.auth-container').contains('Authorized').should('exist') 4,
cy.get('.btn-done').click() "Validate password reset token"
).should("exist");
// Authorize button is LOCKED now getSwaggerButton("Authentication", 5, "Password reset").should(
cy.get('[class="btn authorize locked"]').should('exist') "exist"
}) );
getSwaggerButton("Authentication", 6, "User details").should(
it("Execute Authentication (valid token case) > GET: User details API", ()=> { "exist"
// Auth> User details API );
getSwaggerButton("Authentication", 6, "User details").click() getSwaggerButton("Authentication", 7, "Update user details").should(
"exist"
// "Try it out" button, followed by "Execute" );
cy.get('.try-out > .btn').click() getSwaggerButton("Authentication", 8, "Update user details").should(
cy.get('.execute-wrapper > .btn').click() "exist"
);
// check response: validate email credentials });
cy.get('.highlight-code > .microlight').contains('email').should('exist') });
cy.get('.highlight-code > .microlight').contains(roles.owner.credentials.username).should('exist') });
// reset operations (clear, cancel, windback User details tab) it("Authorize success: Valid token", () => {
cy.get('.btn-clear').click() // authorize button, feed token, click authorize
cy.get('.try-out > .btn').click() cy.get('[class="btn authorize unlocked"]').click();
getSwaggerButton("Authentication", 6, "User details").click() cy.get("input").type(Token);
}) cy.get(".auth-btn-wrapper > .authorize").click();
it("Logout post authorization", ()=> { // Response: "Authorized" should exist on DOM
// authorize button, logout cy.get(".auth-container").contains("Authorized").should("exist");
cy.get('[class="btn authorize locked"]').click() cy.get(".btn-done").click();
cy.get('.auth-btn-wrapper > button:contains("Logout")').click()
cy.get('.btn-done').click() // Authorize button is LOCKED now
cy.get('[class="btn authorize locked"]').should("exist");
// Authorize button is UNLOCKED now });
cy.get('[class="btn authorize unlocked"]').should('exist')
}) it("Execute Authentication (valid token case) > GET: User details API", () => {
// Auth> User details API
it("Execute Authentication (logout case) > GET: User details API", ()=> { getSwaggerButton("Authentication", 6, "User details").click();
// Auth> User details API
getSwaggerButton("Authentication", 6, "User details").click() // "Try it out" button, followed by "Execute"
cy.get(".try-out > .btn").click();
// "Try it out" button, followed by "Execute" cy.get(".execute-wrapper > .btn").click();
cy.get('.try-out > .btn').click()
cy.get('.execute-wrapper > .btn').click() // check response: validate email credentials
cy.get(".highlight-code > .microlight")
// check response: email credentials shouldnt exist. should display 'guest:true' .contains("email")
cy.get('.highlight-code > .microlight').contains('guest').should('exist') .should("exist");
cy.get('.highlight-code > .microlight').contains('email').should('not.exist') cy.get(".highlight-code > .microlight")
cy.get('.highlight-code > .microlight').contains(roles.owner.credentials.username).should('not.exist') .contains(roles.owner.credentials.username)
.should("exist");
// reset operations (clear, cancel, windback User details tab)
cy.get('.btn-clear').click() // reset operations (clear, cancel, windback User details tab)
cy.get('.try-out > .btn').click() cy.get(".btn-clear").click();
getSwaggerButton("Authentication", 6, "User details").click() cy.get(".try-out > .btn").click();
}) getSwaggerButton("Authentication", 6, "User details").click();
});
it("Authorize failure: invalid token", ()=> {
// authorize button, feed *invalid* token, click authorize it("Logout post authorization", () => {
cy.get('[class="btn authorize unlocked"]').click() // authorize button, logout
cy.get('input').type('xyz') cy.get('[class="btn authorize locked"]').click();
cy.get('.auth-btn-wrapper > .authorize').click() cy.get('.auth-btn-wrapper > button:contains("Logout")').click();
cy.get(".btn-done").click();
// Response: "Authorized" should *not* exist on DOM
// TBD: cy.get('.auth-container').contains('Authorized').should('not.exist') // Authorize button is UNLOCKED now
cy.get('.btn-done').click() cy.get('[class="btn authorize unlocked"]').should("exist");
});
// Authorize button should be UNLOCKED now
// TBD: cy.get('[class="btn authorize unlocked"]').should('exist') it("Execute Authentication (logout case) > GET: User details API", () => {
}) // Auth> User details API
getSwaggerButton("Authentication", 6, "User details").click();
it("Execute Authentication (invalid token case) > GET: User details API", ()=> {
// Auth> User details API // "Try it out" button, followed by "Execute"
getSwaggerButton("Authentication", 6, "User details").click() cy.get(".try-out > .btn").click();
cy.get(".execute-wrapper > .btn").click();
// "Try it out" button, followed by "Execute"
cy.get('.try-out > .btn').click() // check response: email credentials shouldnt exist. should display 'guest:true'
cy.get('.execute-wrapper > .btn').click() cy.get(".highlight-code > .microlight")
.contains("guest")
// check response: email credentials shouldnt exist. should display 'guest:true' .should("exist");
cy.get('.highlight-code > .microlight').contains('guest').should('exist') cy.get(".highlight-code > .microlight")
cy.get('.highlight-code > .microlight').contains('email').should('not.exist') .contains("email")
cy.get('.highlight-code > .microlight').contains(roles.owner.credentials.username).should('not.exist') .should("not.exist");
cy.get(".highlight-code > .microlight")
// reset operations (clear, cancel, windback User details tab) .contains(roles.owner.credentials.username)
cy.get('.btn-clear').click() .should("not.exist");
cy.get('.try-out > .btn').click()
getSwaggerButton("Authentication", 6, "User details").click() // reset operations (clear, cancel, windback User details tab)
}) cy.get(".btn-clear").click();
cy.get(".try-out > .btn").click();
// clean-up created file (shared.json) getSwaggerButton("Authentication", 6, "User details").click();
// after(() => { });
// cy.exec("del shared.json").then(()=> {
// cy.log("file cleaned up!") it("Authorize failure: invalid token", () => {
// }) // authorize button, feed *invalid* token, click authorize
// }) cy.get('[class="btn authorize unlocked"]').click();
}) cy.get("input").type("xyz");
} cy.get(".auth-btn-wrapper > .authorize").click();
}
// Response: "Authorized" should *not* exist on DOM
// TBD: cy.get('.auth-container').contains('Authorized').should('not.exist')
cy.get(".btn-done").click();
// Authorize button should be UNLOCKED now
// TBD: cy.get('[class="btn authorize unlocked"]').should('exist')
});
it("Execute Authentication (invalid token case) > GET: User details API", () => {
// Auth> User details API
getSwaggerButton("Authentication", 6, "User details").click();
// "Try it out" button, followed by "Execute"
cy.get(".try-out > .btn").click();
cy.get(".execute-wrapper > .btn").click();
// check response: email credentials shouldnt exist. should display 'guest:true'
cy.get(".highlight-code > .microlight")
.contains("guest")
.should("exist");
cy.get(".highlight-code > .microlight")
.contains("email")
.should("not.exist");
cy.get(".highlight-code > .microlight")
.contains(roles.owner.credentials.username)
.should("not.exist");
// reset operations (clear, cancel, windback User details tab)
cy.get(".btn-clear").click();
cy.get(".try-out > .btn").click();
getSwaggerButton("Authentication", 6, "User details").click();
});
// clean-up created file (shared.json)
// after(() => {
// cy.exec("del shared.json").then(()=> {
// cy.log("file cleaned up!")
// })
// })
});
}
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

118
scripts/cypress/integration/common/6d_language_validation.js

@ -1,68 +1,66 @@
const { mainPage } = require("../../support/page_objects/mainPage") const { mainPage } = require("../../support/page_objects/mainPage");
const { loginPage } = require("../../support/page_objects/navigation") const { loginPage } = require("../../support/page_objects/navigation");
const { roles } = require("../../support/page_objects/projectConstants") const { roles } = require("../../support/page_objects/projectConstants");
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`Language support`, () => { describe(`Language support`, () => {
before(() => {
//loginPage.signIn(roles.owner.credentials)
mainPage.toolBarTopLeft(mainPage.HOME).click();
});
before(() => { const langVerification = (idx, lang) => {
//loginPage.signIn(roles.owner.credentials) // pick json from the file specified
mainPage.toolBarTopLeft(mainPage.HOME).click() it(`Language verification: ${lang} > Projects page`, () => {
}) let json = require(`../../../../packages/nc-gui/lang/${lang}`);
const langVerification = (idx, lang) => { // toggle menu as per index
// pick json from the file specified cy.get(".nc-menu-translate").click();
it(`Language verification: ${lang} > Projects page`, () => { cy.getActiveMenu().find(".v-list-item").eq(idx).click();
let json = require(`../../../../packages/nc-gui/lang/${lang}`);
// toggle menu as per index
cy.get('.nc-menu-translate').click()
cy.getActiveMenu().find('.v-list-item').eq(idx).click()
// basic validations // basic validations
// 1. Page title: "My Projects" // 1. Page title: "My Projects"
// 2. Button: "New Project" // 2. Button: "New Project"
// 3. Search box palceholder text: "Search Projects" // 3. Search box palceholder text: "Search Projects"
cy.get('b') cy.get("b").contains(json.projects.my_projects).should("exist");
.contains(json.projects.my_projects) cy.get("button.v-btn")
.should('exist') .contains(json.projects.create_new_project_button.text)
cy.get('button.v-btn') .should("exist");
.contains(json.projects.create_new_project_button.text) cy.get(`[placeholder="${json.projects.search_project}"]`).should(
.should('exist') "exist"
cy.get(`[placeholder="${json.projects.search_project}"]`) );
.should('exist') });
}) };
}
// Index is the order in which menu options appear // Index is the order in which menu options appear
langVerification(0, 'da.json') langVerification(0, "da.json");
langVerification(1, 'de.json') langVerification(1, "de.json");
langVerification(2, 'en.json') langVerification(2, "en.json");
langVerification(3, 'es.json') langVerification(3, "es.json");
langVerification(4, 'fi.json') langVerification(4, "fi.json");
langVerification(5, 'fr.json') langVerification(5, "fr.json");
langVerification(6, 'hr.json') langVerification(6, "hr.json");
langVerification(7, 'id.json') langVerification(7, "id.json");
langVerification(8, 'it_IT.json') langVerification(8, "it_IT.json");
langVerification(9, 'iw.json') langVerification(9, "iw.json");
langVerification(10, 'ja.json') langVerification(10, "ja.json");
langVerification(11, 'ko.json') langVerification(11, "ko.json");
langVerification(12, 'nl.json') langVerification(12, "nl.json");
langVerification(13, 'no.json') langVerification(13, "no.json");
langVerification(14, 'pt_BR.json') langVerification(14, "pt_BR.json");
langVerification(15, 'ru.json') langVerification(15, "ru.json");
langVerification(16, 'sl.json') langVerification(16, "sl.json");
langVerification(17, 'sv.json') langVerification(17, "sv.json");
langVerification(18, 'th.json') langVerification(18, "th.json");
langVerification(19, 'uk.json') langVerification(19, "uk.json");
langVerification(20, 'vi.json') langVerification(20, "vi.json");
langVerification(21, 'zh_CN.json') langVerification(21, "zh_CN.json");
langVerification(22, 'zh_HK.json') langVerification(22, "zh_HK.json");
langVerification(23, 'zh_TW.json') langVerification(23, "zh_TW.json");
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -84,4 +82,4 @@ export const genTest = (type, xcdb) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

89
scripts/cypress/integration/common/6e_project_operations.js

@ -1,71 +1,70 @@
import { loginPage } from "../../support/page_objects/navigation" import { loginPage } from "../../support/page_objects/navigation";
import { roles } from "../../support/page_objects/projectConstants" import { roles } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
describe(`${type.toUpperCase()} Project operations`, () => { describe(`${type.toUpperCase()} Project operations`, () => {
if(!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
before(() => { before(() => {
loginPage.signIn(roles.owner.credentials) loginPage.signIn(roles.owner.credentials);
}) });
it('Stop Project', () => { it("Stop Project", () => {
//cy.visit('./#/projects') //cy.visit('./#/projects')
cy.get(`.nc-${type}-project-row .mdi-stop-circle-outline`, { timeout: 10000 }) cy.get(`.nc-${type}-project-row .mdi-stop-circle-outline`, {
.should('exist') timeout: 10000,
})
.should("exist")
.last() .last()
.invoke('show') .invoke("show")
.click();
cy.contains('Submit')
.closest('button')
.click(); .click();
cy.contains("Submit").closest("button").click();
cy.toastWait('stopped successfully') cy.toastWait("stopped successfully");
}) });
it('Start Project', () => { it("Start Project", () => {
//cy.visit('./#/projects') //cy.visit('./#/projects')
cy.get(`.nc-${type}-project-row .mdi-play-circle-outline`, { timeout: 10000 }) cy.get(`.nc-${type}-project-row .mdi-play-circle-outline`, {
.should('exist') timeout: 10000,
})
.should("exist")
.last() .last()
.invoke('show') .invoke("show")
.click(); .click();
cy.contains('Submit').closest('button').click(); cy.contains("Submit").closest("button").click();
cy.toastWait('started successfully') cy.toastWait("started successfully");
}) });
it('Restart Project', () => { it("Restart Project", () => {
//cy.visit('./#/projects') //cy.visit('./#/projects')
cy.get(`.nc-${type}-project-row .mdi-restart`, { timeout: 10000 }) cy.get(`.nc-${type}-project-row .mdi-restart`, { timeout: 10000 })
.should('exist') .should("exist")
.last() .last()
.invoke('show') .invoke("show")
.click();
cy.contains('Submit')
.closest('button')
.click(); .click();
cy.contains("Submit").closest("button").click();
cy.toastWait('restarted successfully')
})
it('Delete Project', () => { cy.toastWait("restarted successfully");
});
it("Delete Project", () => {
//cy.visit('./#/projects') //cy.visit('./#/projects')
cy.get(`.nc-${type}-project-row .mdi-delete-circle-outline`, { timeout: 10000 }) cy.get(`.nc-${type}-project-row .mdi-delete-circle-outline`, {
.should('exist') timeout: 10000,
})
.should("exist")
.last() .last()
.invoke('show') .invoke("show")
.click();
cy.contains('Submit')
.closest('button')
.click(); .click();
cy.contains("Submit").closest("button").click();
cy.toastWait('deleted successfully')
}) cy.toastWait("deleted successfully");
}) });
} });
};
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -87,4 +86,4 @@ export const genTest = (type, xcdb) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

137
scripts/cypress/integration/common/6f_attachments.js

@ -1,117 +1,126 @@
import {mainPage} from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
import {loginPage} from "../../support/page_objects/navigation" import { loginPage } from "../../support/page_objects/navigation";
import {isTestSuiteActive} from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if (!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} Columns of type attachment`, () => { describe(`${type.toUpperCase()} Columns of type attachment`, () => {
before(() => { before(() => {
loginPage.loginAndOpenProject(type) loginPage.loginAndOpenProject(type);
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
}) });
after(() => { after(() => {
mainPage.deleteColumn('testAttach') mainPage.deleteColumn("testAttach");
// clean up newly added rows into Country table operations // clean up newly added rows into Country table operations
// this auto verifies successfull addition of rows to table as well // this auto verifies successfull addition of rows to table as well
mainPage.getPagination(5).click() mainPage.getPagination(5).click();
// wait for page rendering to complete // wait for page rendering to complete
cy.get('.nc-grid-row').should('have.length', 10) cy.get(".nc-grid-row").should("have.length", 10);
mainPage.getRow(10).find('.mdi-checkbox-blank-outline').click({force: true}) mainPage
.getRow(10)
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage.getCell("Country", 10).rightclick() mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains('Delete Selected Row').click() cy.getActiveMenu().contains("Delete Selected Row").click();
cy.closeTableTab('Country') cy.closeTableTab("Country");
}) });
it(`Add column of type attachments`, () => { it(`Add column of type attachments`, () => {
mainPage.addColumnWithType('testAttach', 'Attachment', 'Country') mainPage.addColumnWithType("testAttach", "Attachment", "Country");
for (let i = 1; i <= 2; i++) { for (let i = 1; i <= 2; i++) {
let filepath = `sampleFiles/${i}.json` let filepath = `sampleFiles/${i}.json`;
mainPage.getCell('testAttach', i).click().find('input[type="file"]').attachFile(filepath) mainPage
mainPage.getCell('testAttach', i).find('.mdi-file').should('exist') .getCell("testAttach", i)
.click()
.find('input[type="file"]')
.attachFile(filepath);
mainPage.getCell("testAttach", i).find(".mdi-file").should("exist");
} }
}) });
it(`Form view with Attachment field- Submit & verify`, () => { it(`Form view with Attachment field- Submit & verify`, () => {
// create form-view // create form-view
cy.get(`.nc-create-form-view`).click(); cy.get(`.nc-create-form-view`).click();
cy.getActiveModal().find('button:contains(Submit)').click() cy.getActiveModal().find("button:contains(Submit)").click();
cy.toastWait('View created successfully') cy.toastWait("View created successfully");
cy.get(`.nc-view-item.nc-form-view-item`).contains('Country1').click() cy.get(`.nc-view-item.nc-form-view-item`).contains("Country1").click();
cy.get('.v-navigation-drawer__content > .container') cy.get(".v-navigation-drawer__content > .container")
.should('exist') .should("exist")
.find('.v-list > .v-list-item') .find(".v-list > .v-list-item")
.contains('Share View') .contains("Share View")
.click() .click();
// copy link text, visit URL // copy link text, visit URL
cy.getActiveModal().find('.share-link-box') cy.getActiveModal()
.contains('/nc/form/', {timeout: 10000}) .find(".share-link-box")
.contains("/nc/form/", { timeout: 10000 })
.then(($obj) => { .then(($obj) => {
let linkText = $obj.text().trim();
let linkText = $obj.text().trim() cy.log(linkText);
cy.log(linkText)
cy.visit(linkText, { cy.visit(linkText, {
baseUrl: null baseUrl: null,
}) });
// wait for share view page to load! // wait for share view page to load!
cy.get('#data-table-form-Country').should('exist').type('_abc') cy.get("#data-table-form-Country").should("exist").type("_abc");
cy.get('#data-table-form-LastUpdate').click() cy.get("#data-table-form-LastUpdate").click();
cy.getActiveModal().find('button').contains('19').click() cy.getActiveModal().find("button").contains("19").click();
cy.getActiveModal().find('button').contains('OK').click() cy.getActiveModal().find("button").contains("OK").click();
cy.get('.nc-field-editables') cy.get(".nc-field-editables")
.last() .last()
.find('input[type="file"]') .find('input[type="file"]')
.attachFile(`sampleFiles/1.json`) .attachFile(`sampleFiles/1.json`);
// submit button & validate // submit button & validate
cy.get('.nc-form').find('button').contains('Submit').click() cy.get(".nc-form").find("button").contains("Submit").click();
cy.toastWait('Saved successfully') cy.toastWait("Saved successfully");
}) });
}) });
it(`Filter column which contain only attachments, download CSV`, () => { it(`Filter column which contain only attachments, download CSV`, () => {
// come back to main window // come back to main window
loginPage.loginAndOpenProject(type) loginPage.loginAndOpenProject(type);
cy.openTableTab('Country', 25); cy.openTableTab("Country", 25);
mainPage.filterField('testAttach', 'is not null', null) mainPage.filterField("testAttach", "is not null", null);
mainPage.hideField('LastUpdate') mainPage.hideField("LastUpdate");
const verifyCsv = (retrievedRecords) => { const verifyCsv = (retrievedRecords) => {
let storedRecords = [ let storedRecords = [
`Country,Country => City,testAttach`, `Country,Country => City,testAttach`,
`Afghanistan,Kabul,1.json(http://localhost:8080/dl/externalrest_5agd/db/country/testAttach_VWk3fz_1.json)` `Afghanistan,Kabul,1.json(http://localhost:8080/dl/externalrest_5agd/db/country/testAttach_VWk3fz_1.json)`,
] ];
expect(retrievedRecords[0]).to.be.equal(storedRecords[0]) expect(retrievedRecords[0]).to.be.equal(storedRecords[0]);
for (let i = 1; i < storedRecords.length; i++) { for (let i = 1; i < storedRecords.length; i++) {
const columns = retrievedRecords[i].split(',') const columns = retrievedRecords[i].split(",");
expect(columns[2]).to.contain('.json(http://localhost:8080/dl/external') expect(columns[2]).to.contain(
".json(http://localhost:8080/dl/external"
);
} }
cy.log(retrievedRecords[109]) cy.log(retrievedRecords[109]);
cy.log(retrievedRecords[110]) cy.log(retrievedRecords[110]);
cy.log(retrievedRecords[111]) cy.log(retrievedRecords[111]);
} };
mainPage.downloadAndVerifyCsv(`Country_exported_1.csv`, verifyCsv) mainPage.downloadAndVerifyCsv(`Country_exported_1.csv`, verifyCsv);
mainPage.unhideField('LastUpdate') mainPage.unhideField("LastUpdate");
mainPage.filterReset() mainPage.filterReset();
}) });
}) });
} };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

247
scripts/cypress/integration/common/6g_base_share.js

@ -1,77 +1,77 @@
import { mainPage } from "../../support/page_objects/mainPage";
import { mainPage } from "../../support/page_objects/mainPage" import { projectsPage } from "../../support/page_objects/navigation";
import { projectsPage } from "../../support/page_objects/navigation" import { loginPage } from "../../support/page_objects/navigation";
import { loginPage } from "../../support/page_objects/navigation" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import {
import { _advSettings, _editSchema, _editData, _editComment, _viewMenu, _topRightMenu } from "../spec/roleValidation.spec" _advSettings,
_editSchema,
let linkText = '' _editData,
_editComment,
_viewMenu,
_topRightMenu,
} from "../spec/roleValidation.spec";
let linkText = "";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if (!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
const permissionValidation = (roleType) => { const permissionValidation = (roleType) => {
it(`${roleType}: Visit base shared URL`, () => {
it(`${roleType}: Visit base shared URL`, () => { cy.log(linkText);
cy.log(linkText)
// visit URL & wait for page load to complete
// visit URL & wait for page load to complete cy.visit(linkText, {
cy.visit(linkText, { baseUrl: null,
baseUrl: null });
}) projectsPage.waitHomePageLoad();
projectsPage.waitHomePageLoad()
cy.closeTableTab("Actor");
cy.closeTableTab('Actor') });
})
it(`${roleType}: Validate access permissions: advance menu`, () => {
it(`${roleType}: Validate access permissions: advance menu`, () => { _advSettings(roleType, false);
_advSettings(roleType, false) });
})
it(`${roleType}: Validate access permissions: edit schema`, () => {
it(`${roleType}: Validate access permissions: edit schema`, () => { _editSchema(roleType, false);
_editSchema(roleType, false) });
})
it(`${roleType}: Validate access permissions: edit data`, () => {
it(`${roleType}: Validate access permissions: edit data`, () => { _editData(roleType, false);
_editData(roleType, false) });
})
it(`${roleType}: Validate access permissions: edit comments`, () => {
it(`${roleType}: Validate access permissions: edit comments`, () => { _editComment(roleType, false);
_editComment(roleType, false) });
})
it(`${roleType}: Validate access permissions: view's menu`, () => {
it(`${roleType}: Validate access permissions: view's menu`, () => { _viewMenu(roleType, false);
_viewMenu(roleType, false) });
}) };
}
describe(`${type.toUpperCase()} Base VIEW share`, () => {
describe(`${type.toUpperCase()} Base VIEW share`, () => { it(`Generate base share URL`, () => {
// click SHARE
it(`Generate base share URL`, () => { cy.get(".nc-topright-menu").find(".nc-menu-share").click();
// click SHARE
cy.get('.nc-topright-menu') // Click on readonly base text
.find('.nc-menu-share') cy.getActiveModal().find(".nc-disable-shared-base").click();
.click()
// Select 'Readonly link'
// Click on readonly base text cy.getActiveMenu()
cy.getActiveModal() .find(".caption")
.find('.nc-disable-shared-base') .contains("Anyone with the link")
.click() .click();
// Select 'Readonly link' // Copy URL
cy.getActiveMenu() cy.getActiveModal()
.find('.caption') .find(".nc-url")
.contains('Anyone with the link') .then(($obj) => {
.click() cy.log($obj[0]);
linkText = $obj[0].innerText.trim();
// Copy URL
cy.getActiveModal() const htmlFile = `
.find('.nc-url')
.then(($obj) => {
cy.log($obj[0])
linkText = $obj[0].innerText.trim()
const htmlFile = `
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<body> <body>
@ -86,58 +86,57 @@ style="background: transparent; "></iframe>
</body> </body>
</html> </html>
` `;
cy.writeFile("scripts/cypress/fixtures/sampleFiles/iFrame.html", htmlFile) cy.writeFile(
}) "scripts/cypress/fixtures/sampleFiles/iFrame.html",
}) htmlFile
);
permissionValidation('viewer') });
});
it('Update to EDITOR base share link', () => {
loginPage.loginAndOpenProject(type) permissionValidation("viewer");
// click SHARE it("Update to EDITOR base share link", () => {
cy.get('.nc-topright-menu') loginPage.loginAndOpenProject(type);
.find('.nc-menu-share')
.click() // click SHARE
cy.get(".nc-topright-menu").find(".nc-menu-share").click();
cy.getActiveModal()
.find('.nc-shared-base-role') cy.getActiveModal().find(".nc-shared-base-role").click();
.click()
cy.getActiveMenu().find('[role="menuitem"]').contains("Editor").click();
cy.getActiveMenu() });
.find('[role="menuitem"]')
.contains('Editor') permissionValidation("editor");
.click()
}) it("Generate & verify embed HTML IFrame", { baseUrl: null }, () => {
// open iFrame html
permissionValidation('editor') cy.visit("scripts/cypress/fixtures/sampleFiles/iFrame.html");
it('Generate & verify embed HTML IFrame', { baseUrl: null }, () => { // wait for iFrame to load
// open iFrame html cy.frameLoaded(".nc-embed");
cy.visit('scripts/cypress/fixtures/sampleFiles/iFrame.html')
// for GQL- additionally close GQL Client window
// wait for iFrame to load if (type === "graphql") {
cy.frameLoaded('.nc-embed') cy.iframe().find(`[title="Graphql Client"] > button.mdi-close`).click();
}
// for GQL- additionally close GQL Client window
if (type === 'graphql') { // validation for base menu opitons
cy.iframe().find(`[title="Graphql Client"] > button.mdi-close`).click() cy.iframe().find(".nc-project-tree").should("exist");
} cy.iframe().find(".nc-fields-menu-btn").should("exist");
cy.iframe().find(".nc-sort-menu-btn").should("exist");
// validation for base menu opitons cy.iframe().find(".nc-filter-menu-btn").should("exist");
cy.iframe().find('.nc-project-tree').should('exist') cy.iframe().find(".nc-actions-menu-btn").should("exist");
cy.iframe().find('.nc-fields-menu-btn').should('exist')
cy.iframe().find('.nc-sort-menu-btn').should('exist') // validate data (row-1)
cy.iframe().find('.nc-filter-menu-btn').should('exist') mainPage
cy.iframe().find('.nc-actions-menu-btn').should('exist') .getIFrameCell("FirstName", 1)
.contains("PENELOPE")
// validate data (row-1) .should("exist");
mainPage.getIFrameCell('FirstName', 1).contains("PENELOPE").should('exist') mainPage.getIFrameCell("LastName", 1).contains("GUINESS").should("exist");
mainPage.getIFrameCell('LastName', 1).contains("GUINESS").should('exist') });
}) });
}) };
}
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

539
scripts/cypress/integration/common/7a_create_project_from_excel.js

@ -1,47 +1,49 @@
// Cypress test suite: Project creation using EXCEL // Cypress test suite: Project creation using EXCEL
// //
import { projectsPage } from "../../support/page_objects/navigation" import { projectsPage } from "../../support/page_objects/navigation";
import { mainPage } from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
import { roles, isTestSuiteActive } from "../../support/page_objects/projectConstants" import {
roles,
isTestSuiteActive,
} from "../../support/page_objects/projectConstants";
// stores sheet names (table name) // stores sheet names (table name)
let sheetList let sheetList;
// stores table data (read from excel) // stores table data (read from excel)
let sheetData let sheetData;
//let UrlSheetData //let UrlSheetData
let URL = 'https://go.microsoft.com/fwlink/?LinkID=521962' let URL = "https://go.microsoft.com/fwlink/?LinkID=521962";
let filepath = `sampleFiles/simple.xlsx` let filepath = `sampleFiles/simple.xlsx`;
// let UrlFilePath = `sampleFiles/Financial Sample.xlsx` // let UrlFilePath = `sampleFiles/Financial Sample.xlsx`
let expectedData = { let expectedData = {
0: ['number', 'Number'], 0: ["number", "Number"],
1: ['float', 'Decimal'], 1: ["float", "Decimal"],
2: ['text', 'SingleLineText'] 2: ["text", "SingleLineText"],
} };
let UrlFileExpectedData = { let UrlFileExpectedData = {
0: ['Segment', 'SingleSelect', ['Government']], 0: ["Segment", "SingleSelect", ["Government"]],
1: ['Country', 'SingleSelect', ['Canada']], 1: ["Country", "SingleSelect", ["Canada"]],
2: ['Product', 'SingleSelect', ['Carretera']], 2: ["Product", "SingleSelect", ["Carretera"]],
3: ['Discount Band', 'SingleSelect', ['None']], 3: ["Discount Band", "SingleSelect", ["None"]],
4: ['Units Sold', 'Decimal', [1618.5]], 4: ["Units Sold", "Decimal", [1618.5]],
5: ['Manufacturing Price', 'Number', [3]], 5: ["Manufacturing Price", "Number", [3]],
6: ['Sale Price', 'Number', [20]], 6: ["Sale Price", "Number", [20]],
7: ['Gross Sales', 'Decimal', [32370]], 7: ["Gross Sales", "Decimal", [32370]],
8: ['Discounts', 'Decimal', [0]], 8: ["Discounts", "Decimal", [0]],
9: ['Sales', 'Decimal', [32370]], 9: ["Sales", "Decimal", [32370]],
10: ['COGS', 'Decimal', [16185]], 10: ["COGS", "Decimal", [16185]],
11: ['Profit', 'Decimal', [16185]], 11: ["Profit", "Decimal", [16185]],
12: ['Date', 'Date', ['2014-01-01']], 12: ["Date", "Date", ["2014-01-01"]],
13: ['Month Number', 'Number', [1]], 13: ["Month Number", "Number", [1]],
14: ['Month Name', 'SingleSelect', ['January']], 14: ["Month Name", "SingleSelect", ["January"]],
15: ['Year', 'SingleSelect', [2014]] 15: ["Year", "SingleSelect", [2014]],
} };
// let filepath = `sampleFiles/sample.xlsx` // let filepath = `sampleFiles/sample.xlsx`
// let expectedData = { // let expectedData = {
@ -61,231 +63,260 @@ let UrlFileExpectedData = {
// } // }
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if (!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`Import from excel`, () => { describe(`Import from excel`, () => {
before(() => {
before(() => { cy.task("readSheetList", {
file: `./scripts/cypress/fixtures/${filepath}`,
cy.task('readSheetList', { file: `./scripts/cypress/fixtures/${filepath}` }) }).then((rows) => {
.then((rows) => { cy.log(rows);
cy.log(rows) sheetList = rows;
sheetList = rows });
})
cy.task("readXlsx", {
cy.task('readXlsx', { file: `./scripts/cypress/fixtures/${filepath}`, sheet: "Sheet2" }) file: `./scripts/cypress/fixtures/${filepath}`,
.then((rows) => { sheet: "Sheet2",
cy.log(rows) }).then((rows) => {
sheetData = rows cy.log(rows);
}) sheetData = rows;
});
// cy.task('readXlsx', { file: `./scripts/cypress/fixtures/${UrlFilePath}`, sheet: "Sheet1" })
// .then((rows) => { // cy.task('readXlsx', { file: `./scripts/cypress/fixtures/${UrlFilePath}`, sheet: "Sheet1" })
// cy.log(rows) // .then((rows) => {
// UrlSheetData = rows // cy.log(rows)
// }) // UrlSheetData = rows
}) // })
});
it('File Upload: Upload excel as template', () => {
it("File Upload: Upload excel as template", () => {
mainPage.toolBarTopLeft(mainPage.HOME).click() mainPage.toolBarTopLeft(mainPage.HOME).click();
// click on "New Project" // click on "New Project"
cy.get(':nth-child(5) > .v-btn', { timeout: 20000 }).click() cy.get(":nth-child(5) > .v-btn", { timeout: 20000 }).click();
// Subsequent form, select (+ Create) option // Subsequent form, select (+ Create) option
cy.get('.nc-create-project-from-excel', { timeout: 20000 }).click({ force: true }) cy.get(".nc-create-project-from-excel", { timeout: 20000 }).click({
force: true,
cy.get('.nc-excel-import-input').attachFile(filepath) });
cy.get('.nc-btn-use-template', { timeout: 120000 }).should('exist')
}) cy.get(".nc-excel-import-input").attachFile(filepath);
cy.get(".nc-btn-use-template", { timeout: 120000 }).should("exist");
it('File Upload: Verify pre-load template page', () => { });
cy.getActiveContentModal().find('.v-expansion-panel').then((sheets) => { it("File Upload: Verify pre-load template page", () => {
cy.getActiveContentModal()
for (let i = 0; i < sheets.length; i++) { .find(".v-expansion-panel")
.then((sheets) => {
// verify if all sheet names are correct for (let i = 0; i < sheets.length; i++) {
// cy.wrap(sheets[i]).find('.title').then((blk) => { // verify if all sheet names are correct
// cy.log(blk.text().trim()) // cy.wrap(sheets[i]).find('.title').then((blk) => {
// expect(blk.text().trim()).to.equal(sheetList[i]) // cy.log(blk.text().trim())
// }) // expect(blk.text().trim()).to.equal(sheetList[i])
// })
cy.wrap(sheets[i]).contains(sheetList[i]).should('exist')
cy.wrap(sheets[i]).contains(sheetList[i]).should("exist");
// for each sheet, expand to verify table names & their data types
cy.wrap(sheets[i]).find('.mdi-chevron-down').click() // for each sheet, expand to verify table names & their data types
cy.wrap(sheets[i]).find(".mdi-chevron-down").click();
// wait for 4 DOM rows to become visible, corresponding to 4 column names in excel
// change to avoid static wait // wait for 4 DOM rows to become visible, corresponding to 4 column names in excel
cy.get('.v-data-table').find('tr:visible').should('have.length', 4) // change to avoid static wait
cy.get(".v-data-table").find("tr:visible").should("have.length", 4);
cy.get('.v-data-table').find('tr:visible').then((row) => {
cy.get(".v-data-table")
for (let j = 1; j < row.length; j++) { .find("tr:visible")
.then((row) => {
// column name to match input in excel for (let j = 1; j < row.length; j++) {
cy.wrap(row[j]).find('[placeholder="Column name"]').then((obj) => { // column name to match input in excel
cy.log(obj[0].value) cy.wrap(row[j])
expect(obj[0].value).to.equal(expectedData[j-1][0]) .find('[placeholder="Column name"]')
}) .then((obj) => {
cy.log(obj[0].value);
// datatype to match expected output expect(obj[0].value).to.equal(expectedData[j - 1][0]);
cy.wrap(row[j]).find('span.caption').then((obj) => { });
cy.log(obj[0].innerText)
expect(obj[0].innerText).to.equal(expectedData[j-1][1]) // datatype to match expected output
}) cy.wrap(row[j])
} .find("span.caption")
}) .then((obj) => {
cy.log(obj[0].innerText);
// unwind expect(obj[0].innerText).to.equal(expectedData[j - 1][1]);
cy.wrap(sheets[i]).find('.mdi-chevron-down').click() });
}
})
})
it('File Upload: Verify loaded data', () => {
// create rest/ gql project
cy.get('.nc-btn-use-template', { timeout: 120000 }).click()
// if (type == 'rest') {
// cy.getActiveMenu().find('[role="menuitem"]').contains('REST').click()
// } else {
// cy.getActiveMenu().find('[role="menuitem"]').contains('GQL').click()
// }
// wait for loading to be completed
projectsPage.waitHomePageLoad()
// open sheet & validate contents
// sheetData contains data read from excel in format
// 0: { float: 1.1, number: 1, text: "abc" }
// 1: { float: 1.2, number: 0, text: "def" }
cy.openTableTab('Sheet2', 2)
for (const [key, value] of Object.entries(expectedData)) {
mainPage.getCell(value[0], 1).contains(sheetData[0][value[0]]).should('exist')
mainPage.getCell(value[0], 2).contains(sheetData[1][value[0]]).should('exist')
}
cy.closeTableTab('Sheet2')
cy.openTableTab('Sheet3', 2)
for (const [key, value] of Object.entries(expectedData)) {
mainPage.getCell(value[0], 1).contains(sheetData[0][value[0]]).should('exist')
mainPage.getCell(value[0], 2).contains(sheetData[1][value[0]]).should('exist')
}
cy.closeTableTab('Sheet3')
// delete project once all operations are completed
mainPage.toolBarTopLeft(mainPage.HOME).click()
cy.get(`.nc-${type}-project-row .mdi-delete-circle-outline`, { timeout: 10000 })
.should('exist')
.last()
.invoke('show')
.click();
cy.contains('Submit')
.closest('button')
.click();
})
it('URL: Upload excel as template', () => {
// click on "New Project"
cy.get(':nth-child(5) > .v-btn', { timeout: 20000 }).click()
// Subsequent form, select (+ Create) option
cy.get('.nc-create-project-from-excel', { timeout: 20000 }).click({ force: true })
cy.getActiveModal().find('.caption').contains('URL').click()
cy.get('.nc-excel-import-tab-item').find('input[type="url"]').click().type(URL)
cy.get('.nc-excel-import-tab-item').find('button').contains('Load').click()
cy.get('.nc-btn-use-template', { timeout: 120000 }).should('exist')
})
it('URL: Verify pre-load template page', () => {
cy.getActiveContentModal().find('.v-expansion-panel').then((sheets) => {
for (let i = 0; i < sheets.length; i++) {
// verify if all sheet names are correct
// cy.wrap(sheets[i]).find('.title').then((blk) => {
// cy.log(blk.text().trim())
// expect(blk.text().trim()).to.equal('Sheet1')
// })
cy.wrap(sheets[i]).contains('Sheet1').should('exist')
// for each sheet, expand to verify table names & their data types
cy.wrap(sheets[i]).find('.mdi-chevron-down').click()
cy.wait(3000).then(() => {
cy.get('.v-data-table').find('tr:visible').then((row) => {
// verification restricting to 10, as others need to be scrolled back into view
for (let j = 1; j <= 10/*row.length*/; j++) {
// column name to match input in excel
cy.wrap(row[j]).find('[placeholder="Column name"]').then((obj) => {
cy.log(obj[0].value)
expect(obj[0].value).to.equal(UrlFileExpectedData[j-1][0])
})
// datatype to match expected output
cy.wrap(row[j]).find('span.caption').then((obj) => {
cy.log(obj[0].innerText)
expect(obj[0].innerText).to.equal(UrlFileExpectedData[j-1][1])
})
}
})
})
// unwind
cy.wrap(sheets[i]).find('.mdi-chevron-down').click()
} }
}) });
})
// unwind
it('URL: Verify loaded data', () => { cy.wrap(sheets[i]).find(".mdi-chevron-down").click();
}
// create rest/ gql project });
cy.get('.nc-btn-use-template', { timeout: 120000 }).click() });
// wait for loading to be completed it("File Upload: Verify loaded data", () => {
projectsPage.waitHomePageLoad() // create rest/ gql project
cy.get(".nc-btn-use-template", { timeout: 120000 }).click();
// open sheet & validate contents // if (type == 'rest') {
// sheetData contains data read from excel in format // cy.getActiveMenu().find('[role="menuitem"]').contains('REST').click()
// 0: { float: 1.1, number: 1, text: "abc" } // } else {
// 1: { float: 1.2, number: 0, text: "def" } // cy.getActiveMenu().find('[role="menuitem"]').contains('GQL').click()
// }
cy.openTableTab('Sheet1', 25)
let idx = 0 // wait for loading to be completed
for (const [key, value] of Object.entries(UrlFileExpectedData)) { projectsPage.waitHomePageLoad();
if(UrlFileExpectedData[idx][1] != 'Date')
mainPage.getCell(value[0], 1).contains(UrlFileExpectedData[idx++][2][0]).should('exist') // open sheet & validate contents
} // sheetData contains data read from excel in format
cy.closeTableTab('Sheet1') // 0: { float: 1.1, number: 1, text: "abc" }
}) // 1: { float: 1.2, number: 0, text: "def" }
cy.openTableTab("Sheet2", 2);
after(() => { for (const [key, value] of Object.entries(expectedData)) {
// delete project once all operations are completed mainPage
mainPage.toolBarTopLeft(mainPage.HOME).click() .getCell(value[0], 1)
cy.get(`.nc-${type}-project-row .mdi-delete-circle-outline`, { timeout: 10000 }) .contains(sheetData[0][value[0]])
.should('exist') .should("exist");
.last() mainPage
.invoke('show') .getCell(value[0], 2)
.click(); .contains(sheetData[1][value[0]])
cy.contains('Submit') .should("exist");
.closest('button') }
.click(); cy.closeTableTab("Sheet2");
})
}) cy.openTableTab("Sheet3", 2);
} for (const [key, value] of Object.entries(expectedData)) {
mainPage
.getCell(value[0], 1)
.contains(sheetData[0][value[0]])
.should("exist");
mainPage
.getCell(value[0], 2)
.contains(sheetData[1][value[0]])
.should("exist");
}
cy.closeTableTab("Sheet3");
// delete project once all operations are completed
mainPage.toolBarTopLeft(mainPage.HOME).click();
cy.get(`.nc-${type}-project-row .mdi-delete-circle-outline`, {
timeout: 10000,
})
.should("exist")
.last()
.invoke("show")
.click();
cy.contains("Submit").closest("button").click();
});
it("URL: Upload excel as template", () => {
// click on "New Project"
cy.get(":nth-child(5) > .v-btn", { timeout: 20000 }).click();
// Subsequent form, select (+ Create) option
cy.get(".nc-create-project-from-excel", { timeout: 20000 }).click({
force: true,
});
cy.getActiveModal().find(".caption").contains("URL").click();
cy.get(".nc-excel-import-tab-item")
.find('input[type="url"]')
.click()
.type(URL);
cy.get(".nc-excel-import-tab-item")
.find("button")
.contains("Load")
.click();
cy.get(".nc-btn-use-template", { timeout: 120000 }).should("exist");
});
it("URL: Verify pre-load template page", () => {
cy.getActiveContentModal()
.find(".v-expansion-panel")
.then((sheets) => {
for (let i = 0; i < sheets.length; i++) {
// verify if all sheet names are correct
// cy.wrap(sheets[i]).find('.title').then((blk) => {
// cy.log(blk.text().trim())
// expect(blk.text().trim()).to.equal('Sheet1')
// })
cy.wrap(sheets[i]).contains("Sheet1").should("exist");
// for each sheet, expand to verify table names & their data types
cy.wrap(sheets[i]).find(".mdi-chevron-down").click();
cy.wait(3000).then(() => {
cy.get(".v-data-table")
.find("tr:visible")
.then((row) => {
// verification restricting to 10, as others need to be scrolled back into view
for (let j = 1; j <= 10 /*row.length*/; j++) {
// column name to match input in excel
cy.wrap(row[j])
.find('[placeholder="Column name"]')
.then((obj) => {
cy.log(obj[0].value);
expect(obj[0].value).to.equal(
UrlFileExpectedData[j - 1][0]
);
});
// datatype to match expected output
cy.wrap(row[j])
.find("span.caption")
.then((obj) => {
cy.log(obj[0].innerText);
expect(obj[0].innerText).to.equal(
UrlFileExpectedData[j - 1][1]
);
});
}
});
});
// unwind
cy.wrap(sheets[i]).find(".mdi-chevron-down").click();
}
});
});
it("URL: Verify loaded data", () => {
// create rest/ gql project
cy.get(".nc-btn-use-template", { timeout: 120000 }).click();
// wait for loading to be completed
projectsPage.waitHomePageLoad();
// open sheet & validate contents
// sheetData contains data read from excel in format
// 0: { float: 1.1, number: 1, text: "abc" }
// 1: { float: 1.2, number: 0, text: "def" }
cy.openTableTab("Sheet1", 25);
let idx = 0;
for (const [key, value] of Object.entries(UrlFileExpectedData)) {
if (UrlFileExpectedData[idx][1] != "Date")
mainPage
.getCell(value[0], 1)
.contains(UrlFileExpectedData[idx++][2][0])
.should("exist");
}
cy.closeTableTab("Sheet1");
});
after(() => {
// delete project once all operations are completed
mainPage.toolBarTopLeft(mainPage.HOME).click();
cy.get(`.nc-${type}-project-row .mdi-delete-circle-outline`, {
timeout: 10000,
})
.should("exist")
.last()
.invoke("show")
.click();
cy.contains("Submit").closest("button").click();
});
});
};
// if (typeof require !== 'undefined') XLSX = require('xlsx'); // if (typeof require !== 'undefined') XLSX = require('xlsx');
@ -313,7 +344,7 @@ export const genTest = (type, xcdb) => {
// columnA.push(worksheet[z].v); // columnA.push(worksheet[z].v);
// } // }
// } // }
// return columnA // return columnA
// } // }
// const getCell = (sheet, cellIdx) => { // const getCell = (sheet, cellIdx) => {

324
scripts/cypress/integration/spec/roleValidation.spec.js

@ -1,5 +1,5 @@
import { mainPage } from "../../support/page_objects/mainPage" import { mainPage } from "../../support/page_objects/mainPage";
import { roles } from "../../support/page_objects/projectConstants" import { roles } from "../../support/page_objects/projectConstants";
// Left hand navigation bar, validation for // Left hand navigation bar, validation for
// 1. Audit menu // 1. Audit menu
@ -7,107 +7,115 @@ import { roles } from "../../support/page_objects/projectConstants"
// 3. Preview mode menu // 3. Preview mode menu
// //
export function _advSettings(roleType, previewMode) { export function _advSettings(roleType, previewMode) {
let validationString = (true == roles[roleType].validations.advSettings) ? 'exist' : 'not.exist' let validationString =
true == roles[roleType].validations.advSettings ? "exist" : "not.exist";
// audit/advance settings menu visible only for owner/ creator
mainPage.navigationDraw(mainPage.AUDIT).should(validationString) // audit/advance settings menu visible only for owner/ creator
mainPage.navigationDraw(mainPage.APPSTORE).should(validationString) mainPage.navigationDraw(mainPage.AUDIT).should(validationString);
mainPage.navigationDraw(mainPage.TEAM_N_AUTH).should(validationString) mainPage.navigationDraw(mainPage.APPSTORE).should(validationString);
mainPage.navigationDraw(mainPage.PROJ_METADATA).should(validationString) mainPage.navigationDraw(mainPage.TEAM_N_AUTH).should(validationString);
mainPage.navigationDraw(mainPage.PROJ_METADATA).should(validationString);
// option to add new user conditionally visible only to owner/ creator
cy.get('button:contains("New User")').should(validationString) // option to add new user conditionally visible only to owner/ creator
cy.get('button:contains("New User")').should(validationString);
if (true == previewMode) {
// preview mode, role toggle menubar is visible if (true == previewMode) {
mainPage.navigationDraw(mainPage.ROLE_VIEW_EDITOR).should('exist') // preview mode, role toggle menubar is visible
mainPage.navigationDraw(mainPage.ROLE_VIEW_COMMENTER).should('exist') mainPage.navigationDraw(mainPage.ROLE_VIEW_EDITOR).should("exist");
mainPage.navigationDraw(mainPage.ROLE_VIEW_VIEWER).should('exist') mainPage.navigationDraw(mainPage.ROLE_VIEW_COMMENTER).should("exist");
mainPage.navigationDraw(mainPage.ROLE_VIEW_RESET).should('exist') mainPage.navigationDraw(mainPage.ROLE_VIEW_VIEWER).should("exist");
mainPage.navigationDraw(mainPage.ROLE_VIEW_RESET).should("exist");
} else { } else {
// normal mode, role toggle menubar is visible only for owner/ creator // normal mode, role toggle menubar is visible only for owner/ creator
mainPage.navigationDraw(mainPage.ROLE_VIEW_EDITOR).should(validationString) mainPage.navigationDraw(mainPage.ROLE_VIEW_EDITOR).should(validationString);
mainPage.navigationDraw(mainPage.ROLE_VIEW_COMMENTER).should(validationString) mainPage
mainPage.navigationDraw(mainPage.ROLE_VIEW_VIEWER).should(validationString) .navigationDraw(mainPage.ROLE_VIEW_COMMENTER)
} .should(validationString);
mainPage.navigationDraw(mainPage.ROLE_VIEW_VIEWER).should(validationString);
}
} }
export function _editSchema(roleType, previewMode) { export function _editSchema(roleType, previewMode) {
let columnName = "City";
let columnName = 'City' let validationString =
let validationString = (true == roles[roleType].validations.editSchema) ? 'exist' : 'not.exist' true == roles[roleType].validations.editSchema ? "exist" : "not.exist";
if (false == previewMode) { if (false == previewMode) {
cy.openTableTab(columnName, 25) cy.openTableTab(columnName, 25);
} }
// create table options // create table options
// //
cy.get('.add-btn').should(validationString) cy.get(".add-btn").should(validationString);
cy.get('.v-tabs-bar').eq(0).find('button.mdi-plus-box').should(validationString) cy.get(".v-tabs-bar")
.eq(0)
// delete table option .find("button.mdi-plus-box")
// .should(validationString);
cy.get('.nc-table-delete-btn').should(validationString)
// delete table option
// add new column option //
// cy.get(".nc-table-delete-btn").should(validationString);
cy.get('.new-column-header').should(validationString)
// add new column option
// update column (edit/ delete menu) //
// cy.get(".new-column-header").should(validationString);
cy.get(`th:contains(${columnName}) .mdi-menu-down`).should(validationString)
// update column (edit/ delete menu)
//
cy.get(`th:contains(${columnName}) .mdi-menu-down`).should(validationString);
} }
export function _editData(roleType, previewMode) { export function _editData(roleType, previewMode) {
let columnName = "City";
let validationString =
true == roles[roleType].validations.editData ? "exist" : "not.exist";
let columnName = 'City' cy.openTableTab(columnName, 25);
let validationString = (true == roles[roleType].validations.editData) ? 'exist' : 'not.exist'
cy.openTableTab(columnName, 25) // add new row option (from menu header)
//
cy.get(".nc-add-new-row-btn").should(validationString);
// add new row option (from menu header) // update row option (right click)
// //
cy.get('.nc-add-new-row-btn').should(validationString) cy.get(`tbody > :nth-child(4) > [data-col="City"]`).rightclick();
cy.get(".menuable__content__active").should(validationString);
// update row option (right click) if (validationString == "exist") {
// right click options will exist (only for 'exist' case)
//
cy.getActiveMenu().contains("Insert New Row").should(validationString);
cy.getActiveMenu().contains("Delete Row").should(validationString);
cy.getActiveMenu()
.contains("Delete Selected Rows")
.should(validationString);
cy.get("body").type("{esc}");
// update cell contents option using row expander should be enabled
// //
cy.get(`tbody > :nth-child(4) > [data-col="City"]`).rightclick() //cy.get('.nc-row-expand-icon').eq(4).click({ force: true })
cy.get('.menuable__content__active').should(validationString) cy.get(".v-input.row-checkbox").eq(4).next().next().click({ force: true });
cy.getActiveModal().find("button").contains("Save Row").should("exist");
if (validationString == 'exist') { cy.get("body").type("{esc}");
} else {
// right click options will exist (only for 'exist' case) // update cell contents option using row expander should be disabled
//
cy.getActiveMenu().contains('Insert New Row').should(validationString)
cy.getActiveMenu().contains('Delete Row').should(validationString)
cy.getActiveMenu().contains('Delete Selected Rows').should(validationString)
cy.get('body').type('{esc}')
// update cell contents option using row expander should be enabled
//
//cy.get('.nc-row-expand-icon').eq(4).click({ force: true })
cy.get('.v-input.row-checkbox').eq(4).next().next().click({ force: true })
cy.getActiveModal().find('button').contains('Save Row').should('exist')
cy.get('body').type('{esc}')
}
else {
// update cell contents option using row expander should be disabled
//
//cy.get('.nc-row-expand-icon').eq(4).click({ force: true })
cy.get('.v-input.row-checkbox').eq(4).next().next().click({ force: true })
cy.getActiveModal().find('button:disabled').contains('Save Row').should('exist')
cy.getActiveModal().find('button').contains('Cancel').click()
cy.get('body').type('{esc}')
}
// double click cell entries to edit
// //
cy.get(`tbody > :nth-child(4) > [data-col="City"]`).dblclick().find('input').should(validationString) //cy.get('.nc-row-expand-icon').eq(4).click({ force: true })
cy.get(".v-input.row-checkbox").eq(4).next().next().click({ force: true });
cy.getActiveModal()
.find("button:disabled")
.contains("Save Row")
.should("exist");
cy.getActiveModal().find("button").contains("Cancel").click();
cy.get("body").type("{esc}");
}
// double click cell entries to edit
//
cy.get(`tbody > :nth-child(4) > [data-col="City"]`)
.dblclick()
.find("input")
.should(validationString);
} }
// read &/ update comment // read &/ update comment
@ -115,81 +123,95 @@ export function _editData(roleType, previewMode) {
// Everyone else: read &/ update // Everyone else: read &/ update
// //
export function _editComment(roleType, previewMode) { export function _editComment(roleType, previewMode) {
let columnName = "City";
let columnName = 'City' let validationString =
let validationString = (true == roles[roleType].validations.editComment) ? 'Comment added successfully' : 'Not allowed' true == roles[roleType].validations.editComment
? "Comment added successfully"
cy.openTableTab(columnName, 25) : "Not allowed";
// click on comment icon & type comment cy.openTableTab(columnName, 25);
//
// click on comment icon & type comment
cy.get('.v-input.row-checkbox').eq(4).next().next().click({ force: true }) //
// Expected response: cy.get(".v-input.row-checkbox").eq(4).next().next().click({ force: true });
// Viewer: Not able to see comment option
// Everyone else: Comment added/read successfully // Expected response:
// // Viewer: Not able to see comment option
// Everyone else: Comment added/read successfully
if ('viewer' == roleType) { //
cy.getActiveModal().find('.mdi-comment-multiple-outline').should('not.exist')
} if ("viewer" == roleType) {
else { cy.getActiveModal()
cy.getActiveModal().find('.mdi-comment-multiple-outline').should('exist').click() .find(".mdi-comment-multiple-outline")
cy.getActiveModal().find('.comment-box').type('Comment-1{enter}') .should("not.exist");
// cy.toastWait('Comment added successfully') } else {
cy.getActiveModal().find('.mdi-door-open').click() cy.getActiveModal()
.find(".mdi-comment-multiple-outline")
cy.get('body').contains(validationString, { timeout: 2000 }).should('exist') .should("exist")
} .click();
cy.getActiveModal().find(".comment-box").type("Comment-1{enter}");
cy.getActiveModal().find('button').contains('Cancel').should('exist').click() // cy.toastWait('Comment added successfully')
cy.get('body').type('{esc}') cy.getActiveModal().find(".mdi-door-open").click();
cy.get("body")
.contains(validationString, { timeout: 2000 })
.should("exist");
}
cy.getActiveModal().find("button").contains("Cancel").should("exist").click();
cy.get("body").type("{esc}");
} }
// right navigation menu bar // right navigation menu bar
// Editor/Viewer/Commenter : can only view 'existing' views // Editor/Viewer/Commenter : can only view 'existing' views
// Rest: can create/edit // Rest: can create/edit
export function _viewMenu(roleType, previewMode) { export function _viewMenu(roleType, previewMode) {
let columnName = "City";
let navDrawListCnt = 2;
let columnName = 'City' cy.openTableTab(columnName, 25);
let navDrawListCnt = 2
cy.openTableTab(columnName, 25) let validationString =
true == roles[roleType].validations.shareView ? "exist" : "not.exist";
let validationString = (true == roles[roleType].validations.shareView) ? 'exist' : 'not.exist'
// validate if Share button is visible at header tool bar // validate if Share button is visible at header tool bar
cy.get('header.v-toolbar').eq(0).find('button:contains("Share")').should(validationString) cy.get("header.v-toolbar")
.eq(0)
.find('button:contains("Share")')
.should(validationString);
// Owner, Creator will have two navigation drawer (on each side of center panel) // Owner, Creator will have two navigation drawer (on each side of center panel)
if (roleType == 'owner' || roleType == 'creator') { if (roleType == "owner" || roleType == "creator") {
navDrawListCnt = 4 navDrawListCnt = 4;
} }
cy.get('.v-navigation-drawer__content').eq(1).find('[role="list"]').should('have.length', navDrawListCnt) cy.get(".v-navigation-drawer__content")
.eq(1)
.find('[role="list"]')
.should("have.length", navDrawListCnt);
// view list field (default GRID view) // view list field (default GRID view)
cy.get(`.nc-view-item`).should('exist') cy.get(`.nc-view-item`).should("exist");
// view create option, exists only for owner/ creator // view create option, exists only for owner/ creator
cy.get(`.nc-create-gallery-view`).should(validationString) cy.get(`.nc-create-gallery-view`).should(validationString);
cy.get(`.nc-create-grid-view`).should(validationString) cy.get(`.nc-create-grid-view`).should(validationString);
cy.get(`.nc-create-form-view`).should(validationString) cy.get(`.nc-create-form-view`).should(validationString);
// share view & automations, exists only for owner/creator // share view & automations, exists only for owner/creator
cy.get(`.nc-share-view`).should(validationString) cy.get(`.nc-share-view`).should(validationString);
cy.get(`.nc-automations`).should(validationString) cy.get(`.nc-automations`).should(validationString);
} }
export function _topRightMenu(roleType, previewMode) { export function _topRightMenu(roleType, previewMode) {
let validationString = (true == roles[roleType].validations.shareView) ? 'exist' : 'not.exist' let validationString =
cy.get('.nc-topright-menu').find('.nc-menu-share').should(validationString) true == roles[roleType].validations.shareView ? "exist" : "not.exist";
cy.get(".nc-topright-menu").find(".nc-menu-share").should(validationString);
cy.get('.nc-topright-menu').find('.nc-menu-theme').should('exist')
cy.get('.nc-topright-menu').find('.nc-menu-dark-theme').should('exist') cy.get(".nc-topright-menu").find(".nc-menu-theme").should("exist");
cy.get('.nc-topright-menu').find('.nc-menu-translate').should('exist') cy.get(".nc-topright-menu").find(".nc-menu-dark-theme").should("exist");
cy.get('.nc-topright-menu').find('.nc-menu-account').should('exist') cy.get(".nc-topright-menu").find(".nc-menu-translate").should("exist");
cy.get('.nc-topright-menu').find('.nc-menu-alert').should('exist') cy.get(".nc-topright-menu").find(".nc-menu-account").should("exist");
cy.get(".nc-topright-menu").find(".nc-menu-alert").should("exist");
} }

35
scripts/cypress/integration/test/explicitLogin.js

@ -1,26 +1,25 @@
import { loginPage } from "../../support/page_objects/navigation" import { loginPage } from "../../support/page_objects/navigation";
import { isTestSuiteActive } from "../../support/page_objects/projectConstants" import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
export const genTest = (type, xcdb) => { export const genTest = (type, xcdb) => {
if (!isTestSuiteActive(type, xcdb)) return; if (!isTestSuiteActive(type, xcdb)) return;
describe(`${type.toUpperCase()} api - Login & Open project`, () => { describe(`${type.toUpperCase()} api - Login & Open project`, () => {
// Run once before test- create project (rest/graphql)
//
before(() => {
loginPage.loginAndOpenProject(type);
// Run once before test- create project (rest/graphql) // open a table to work on views
// //
before(() => { // cy.openTableTab('City');
loginPage.loginAndOpenProject(type) });
// open a table to work on views it(``, () => {
// cy.log("Test-1");
// cy.openTableTab('City'); });
}) });
};
it(``, () => {
cy.log('Test-1')
})
})
}
// genTest('rest', false) // genTest('rest', false)

56
scripts/cypress/integration/test/gqlMisc.js

@ -1,35 +1,33 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t6b = require("../common/6b_downloadCsv");
let t6b = require('../common/6b_downloadCsv') let t6c = require("../common/6c_swagger_api");
let t6c = require('../common/6c_swagger_api') let t6d = require("../common/6d_language_validation");
let t6d = require('../common/6d_language_validation') let t6e = require("../common/6e_project_operations");
let t6e = require('../common/6e_project_operations') let t6f = require("../common/6f_attachments");
let t6f = require('../common/6f_attachments') let t6g = require("../common/6g_base_share");
let t6g = require('../common/6g_base_share')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
if (0 == executionMode) { t0.genTest(type, xcdb);
t0.genTest(type, xcdb) } else {
} else { t01.genTest(type, xcdb);
t01.genTest(type, xcdb) }
}
t6b.genTest(type, xcdb);
t6b.genTest(type, xcdb) t6c.genTest(type, xcdb);
t6c.genTest(type, xcdb) t6d.genTest(type, xcdb);
t6d.genTest(type, xcdb) t6f.genTest(type, xcdb);
t6f.genTest(type, xcdb) t6g.genTest(type, xcdb);
t6g.genTest(type, xcdb) // **deletes created project, hence place it @ end
// **deletes created project, hence place it @ end t6e.genTest(type, xcdb);
t6e.genTest(type, xcdb) };
}
nocoTestSuite("graphql", false);
nocoTestSuite('graphql', false)
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -52,7 +50,3 @@ nocoTestSuite('graphql', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

34
scripts/cypress/integration/test/gqlRoles.js

@ -1,26 +1,24 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t5a = require("../common/5a_user_role");
let t5a = require('../common/5a_user_role') let t5b = require("../common/5b_preview_role");
let t5b = require('../common/5b_preview_role')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb);
} else {
t01.genTest(type, xcdb);
}
if (0 == executionMode) { t5a.genTest(type, xcdb);
t0.genTest(type, xcdb) t5b.genTest(type, xcdb);
} else { };
t01.genTest(type, xcdb)
}
t5a.genTest(type, xcdb)
t5b.genTest(type, xcdb)
}
nocoTestSuite('graphql', false) nocoTestSuite("graphql", false);
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -43,7 +41,3 @@ nocoTestSuite('graphql', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

62
scripts/cypress/integration/test/gqlTableOps.js

@ -1,38 +1,36 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t1a = require("../common/1a_table_operations");
let t1a = require('../common/1a_table_operations') let t1b = require("../common/1b_table_column_operations");
let t1b = require('../common/1b_table_column_operations') let t2a = require("../common/2a_table_with_belongs_to_colulmn");
let t2a = require('../common/2a_table_with_belongs_to_colulmn') let t2b = require("../common/2b_table_with_m2m_column");
let t2b = require('../common/2b_table_with_m2m_column') let t3a = require("../common/3a_filter_sort_fields_operations");
let t3a = require('../common/3a_filter_sort_fields_operations') let t3b = require("../common/3b_formula_column");
let t3b = require('../common/3b_formula_column') let t3c = require("../common/3c_lookup_column");
let t3c = require('../common/3c_lookup_column') let t3d = require("../common/3d_rollup_column");
let t3d = require('../common/3d_rollup_column')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
if (0 == executionMode) { t0.genTest(type, xcdb);
t0.genTest(type, xcdb) } else {
} else { t01.genTest(type, xcdb);
t01.genTest(type, xcdb) }
}
t1a.genTest(type, xcdb);
t1a.genTest(type, xcdb) t1b.genTest(type, xcdb);
t1b.genTest(type, xcdb) t2a.genTest(type, xcdb);
t2a.genTest(type, xcdb) t2b.genTest(type, xcdb);
t2b.genTest(type, xcdb) t3a.genTest(type, xcdb);
t3a.genTest(type, xcdb) t3b.genTest(type, xcdb);
t3b.genTest(type, xcdb) t3c.genTest(type, xcdb);
t3c.genTest(type, xcdb) t3d.genTest(type, xcdb);
t3d.genTest(type, xcdb) };
}
nocoTestSuite("graphql", false);
nocoTestSuite('graphql', false)
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -55,7 +53,3 @@ nocoTestSuite('graphql', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

54
scripts/cypress/integration/test/gqlViews.js

@ -1,34 +1,32 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t4a = require("../common/4a_table_view_grid_gallery_form");
let t4a = require('../common/4a_table_view_grid_gallery_form') let t4b = require("../common/4b_table_view_share");
let t4b = require('../common/4b_table_view_share') let t4c = require("../common/4c_form_view_detailed");
let t4c = require('../common/4c_form_view_detailed') let t4d = require("../common/4d_table_view_grid_locked");
let t4d = require('../common/4d_table_view_grid_locked') let t4e = require("../common/4e_form_view_share");
let t4e = require('../common/4e_form_view_share') let t4f = require("../common/4f_grid_view_share");
let t4f = require('../common/4f_grid_view_share')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
if (0 == executionMode) { t0.genTest(type, xcdb);
t0.genTest(type, xcdb) } else {
} else { t01.genTest(type, xcdb);
t01.genTest(type, xcdb) }
}
t4a.genTest(type, xcdb);
t4a.genTest(type, xcdb) t4b.genTest(type, xcdb);
t4b.genTest(type, xcdb) t4c.genTest(type, xcdb);
t4c.genTest(type, xcdb) t4d.genTest(type, xcdb);
t4d.genTest(type, xcdb) t4e.genTest(type, xcdb);
t4e.genTest(type, xcdb) t4f.genTest(type, xcdb);
t4f.genTest(type, xcdb) };
}
nocoTestSuite("graphql", false);
nocoTestSuite('graphql', false)
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -51,7 +49,3 @@ nocoTestSuite('graphql', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

110
scripts/cypress/integration/test/masterSuiteGql.js

@ -1,66 +1,64 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t00 = require("../common/00_pre_configurations");
let t00 = require('../common/00_pre_configurations') let t1a = require("../common/1a_table_operations");
let t1a = require('../common/1a_table_operations') let t1b = require("../common/1b_table_column_operations");
let t1b = require('../common/1b_table_column_operations') let t1c = require("../common/1c_table_row_operations");
let t1c = require('../common/1c_table_row_operations') let t2a = require("../common/2a_table_with_belongs_to_colulmn");
let t2a = require('../common/2a_table_with_belongs_to_colulmn') let t2b = require("../common/2b_table_with_m2m_column");
let t2b = require('../common/2b_table_with_m2m_column') let t3a = require("../common/3a_filter_sort_fields_operations");
let t3a = require('../common/3a_filter_sort_fields_operations') let t3b = require("../common/3b_formula_column");
let t3b = require('../common/3b_formula_column') let t3c = require("../common/3c_lookup_column");
let t3c = require('../common/3c_lookup_column') let t3d = require("../common/3d_rollup_column");
let t3d = require('../common/3d_rollup_column') let t4a = require("../common/4a_table_view_grid_gallery_form");
let t4a = require('../common/4a_table_view_grid_gallery_form') let t4b = require("../common/4b_table_view_share");
let t4b = require('../common/4b_table_view_share') let t4c = require("../common/4c_form_view_detailed");
let t4c = require('../common/4c_form_view_detailed') let t4d = require("../common/4d_table_view_grid_locked");
let t4d = require('../common/4d_table_view_grid_locked') let t4e = require("../common/4e_form_view_share");
let t4e = require('../common/4e_form_view_share') let t4f = require("../common/4f_grid_view_share");
let t4f = require('../common/4f_grid_view_share') let t5a = require("../common/5a_user_role");
let t5a = require('../common/5a_user_role') let t5b = require("../common/5b_preview_role");
let t5b = require('../common/5b_preview_role')
// merged with t1a: let t6a = require('../common/6a_audit') // merged with t1a: let t6a = require('../common/6a_audit')
let t6c = require('../common/6c_swagger_api') let t6c = require("../common/6c_swagger_api");
let t6d = require('../common/6d_language_validation') let t6d = require("../common/6d_language_validation");
let t6e = require('../common/6e_project_operations') let t6e = require("../common/6e_project_operations");
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb);
} else {
t00.genTest(type, xcdb);
}
if (0 == executionMode) { t1a.genTest(type, xcdb);
t0.genTest(type, xcdb) t1b.genTest(type, xcdb);
} else { // merged with t1b: t1c.genTest(type, xcdb)
t00.genTest(type, xcdb) t2a.genTest(type, xcdb);
} t2b.genTest(type, xcdb);
t3a.genTest(type, xcdb);
t1a.genTest(type, xcdb) t3b.genTest(type, xcdb);
t1b.genTest(type, xcdb) t3c.genTest(type, xcdb);
// merged with t1b: t1c.genTest(type, xcdb) t3d.genTest(type, xcdb);
t2a.genTest(type, xcdb) t4a.genTest(type, xcdb);
t2b.genTest(type, xcdb) t4b.genTest(type, xcdb);
t3a.genTest(type, xcdb) t4c.genTest(type, xcdb);
t3b.genTest(type, xcdb) t4d.genTest(type, xcdb);
t3c.genTest(type, xcdb) t4e.genTest(type, xcdb);
t3d.genTest(type, xcdb) t4f.genTest(type, xcdb);
t4a.genTest(type, xcdb) t5a.genTest(type, xcdb);
t4b.genTest(type, xcdb) t5b.genTest(type, xcdb);
t4c.genTest(type, xcdb) // merged with t1a: t6a.genTest(type, xcdb)
t4d.genTest(type, xcdb) t6c.genTest(type, xcdb);
t4e.genTest(type, xcdb) t6d.genTest(type, xcdb);
t4f.genTest(type, xcdb) // **deletes created project, hence place it @ end
t5a.genTest(type, xcdb) t6e.genTest(type, xcdb);
t5b.genTest(type, xcdb) };
// merged with t1a: t6a.genTest(type, xcdb)
t6c.genTest(type, xcdb)
t6d.genTest(type, xcdb)
// **deletes created project, hence place it @ end
t6e.genTest(type, xcdb)
}
// nocoTestSuite('rest', false) // nocoTestSuite('rest', false)
nocoTestSuite('graphql', false) nocoTestSuite("graphql", false);
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -83,7 +81,3 @@ nocoTestSuite('graphql', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

110
scripts/cypress/integration/test/masterSuiteRest.js

@ -1,65 +1,63 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t00 = require("../common/00_pre_configurations");
let t00 = require('../common/00_pre_configurations') let t1a = require("../common/1a_table_operations");
let t1a = require('../common/1a_table_operations') let t1b = require("../common/1b_table_column_operations");
let t1b = require('../common/1b_table_column_operations') let t1c = require("../common/1c_table_row_operations");
let t1c = require('../common/1c_table_row_operations') let t2a = require("../common/2a_table_with_belongs_to_colulmn");
let t2a = require('../common/2a_table_with_belongs_to_colulmn') let t2b = require("../common/2b_table_with_m2m_column");
let t2b = require('../common/2b_table_with_m2m_column') let t3a = require("../common/3a_filter_sort_fields_operations");
let t3a = require('../common/3a_filter_sort_fields_operations') let t3b = require("../common/3b_formula_column");
let t3b = require('../common/3b_formula_column') let t3c = require("../common/3c_lookup_column");
let t3c = require('../common/3c_lookup_column') let t3d = require("../common/3d_rollup_column");
let t3d = require('../common/3d_rollup_column') let t4a = require("../common/4a_table_view_grid_gallery_form");
let t4a = require('../common/4a_table_view_grid_gallery_form') let t4b = require("../common/4b_table_view_share");
let t4b = require('../common/4b_table_view_share') let t4c = require("../common/4c_form_view_detailed");
let t4c = require('../common/4c_form_view_detailed') let t4d = require("../common/4d_table_view_grid_locked");
let t4d = require('../common/4d_table_view_grid_locked') let t4e = require("../common/4e_form_view_share");
let t4e = require('../common/4e_form_view_share') let t4f = require("../common/4f_grid_view_share");
let t4f = require('../common/4f_grid_view_share') let t5a = require("../common/5a_user_role");
let t5a = require('../common/5a_user_role') let t5b = require("../common/5b_preview_role");
let t5b = require('../common/5b_preview_role')
// merged with t1a: let t6a = require('../common/6a_audit') // merged with t1a: let t6a = require('../common/6a_audit')
let t6c = require('../common/6c_swagger_api') let t6c = require("../common/6c_swagger_api");
let t6d = require('../common/6d_language_validation') let t6d = require("../common/6d_language_validation");
let t6e = require('../common/6e_project_operations') let t6e = require("../common/6e_project_operations");
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb);
} else {
t00.genTest(type, xcdb);
}
if (0 == executionMode) { t1a.genTest(type, xcdb);
t0.genTest(type, xcdb) t1b.genTest(type, xcdb);
} else { // merged with t1b: t1c.genTest(type, xcdb)
t00.genTest(type, xcdb) t2a.genTest(type, xcdb);
} t2b.genTest(type, xcdb);
t3a.genTest(type, xcdb);
t1a.genTest(type, xcdb) t3b.genTest(type, xcdb);
t1b.genTest(type, xcdb) t3c.genTest(type, xcdb);
// merged with t1b: t1c.genTest(type, xcdb) t3d.genTest(type, xcdb);
t2a.genTest(type, xcdb) t4a.genTest(type, xcdb);
t2b.genTest(type, xcdb) t4b.genTest(type, xcdb);
t3a.genTest(type, xcdb) t4c.genTest(type, xcdb);
t3b.genTest(type, xcdb) t4d.genTest(type, xcdb);
t3c.genTest(type, xcdb) t4e.genTest(type, xcdb);
t3d.genTest(type, xcdb) t4f.genTest(type, xcdb);
t4a.genTest(type, xcdb) t5a.genTest(type, xcdb);
t4b.genTest(type, xcdb) t5b.genTest(type, xcdb);
t4c.genTest(type, xcdb) // merged with t1a: t6a.genTest(type, xcdb)
t4d.genTest(type, xcdb) t6c.genTest(type, xcdb);
t4e.genTest(type, xcdb) t6d.genTest(type, xcdb);
t4f.genTest(type, xcdb) // **deletes created project, hence place it @ end
t5a.genTest(type, xcdb) t6e.genTest(type, xcdb);
t5b.genTest(type, xcdb) };
// merged with t1a: t6a.genTest(type, xcdb)
t6c.genTest(type, xcdb)
t6d.genTest(type, xcdb)
// **deletes created project, hence place it @ end
t6e.genTest(type, xcdb)
}
nocoTestSuite('rest', false) nocoTestSuite("rest", false);
// nocoTestSuite('graphql', false) // nocoTestSuite('graphql', false)
/** /**
@ -83,7 +81,3 @@ nocoTestSuite('rest', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

66
scripts/cypress/integration/test/restMisc.js

@ -1,40 +1,38 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t6b = require("../common/6b_downloadCsv");
let t6b = require('../common/6b_downloadCsv') let t6c = require("../common/6c_swagger_api");
let t6c = require('../common/6c_swagger_api') let t6d = require("../common/6d_language_validation");
let t6d = require('../common/6d_language_validation') let t6e = require("../common/6e_project_operations");
let t6e = require('../common/6e_project_operations') let t6f = require("../common/6f_attachments");
let t6f = require('../common/6f_attachments') let t6g = require("../common/6g_base_share");
let t6g = require('../common/6g_base_share') let t7a = require("../common/7a_create_project_from_excel");
let t7a = require('../common/7a_create_project_from_excel')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
if (0 == executionMode) { t0.genTest(type, xcdb);
t0.genTest(type, xcdb) } else {
} else { t01.genTest(type, xcdb);
t01.genTest(type, xcdb) }
}
t6b.genTest(type, xcdb);
t6b.genTest(type, xcdb) t6d.genTest(type, xcdb);
t6d.genTest(type, xcdb) t6c.genTest(type, xcdb);
t6c.genTest(type, xcdb) t6f.genTest(type, xcdb);
t6f.genTest(type, xcdb) t6g.genTest(type, xcdb);
t6g.genTest(type, xcdb) // **deletes created project, hence place it @ end
// **deletes created project, hence place it @ end t6e.genTest(type, xcdb);
t6e.genTest(type, xcdb)
// intended to keep this after earlier project deletion
// intended to keep this after earlier project deletion // creates project using excel & deletes it
// creates project using excel & deletes it t7a.genTest(type, xcdb);
t7a.genTest(type, xcdb) };
}
nocoTestSuite("rest", false);
nocoTestSuite('rest', false)
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -57,7 +55,3 @@ nocoTestSuite('rest', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

34
scripts/cypress/integration/test/restRoles.js

@ -1,26 +1,24 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t5a = require("../common/5a_user_role");
let t5a = require('../common/5a_user_role') let t5b = require("../common/5b_preview_role");
let t5b = require('../common/5b_preview_role')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
t0.genTest(type, xcdb);
} else {
t01.genTest(type, xcdb);
}
if (0 == executionMode) { t5a.genTest(type, xcdb);
t0.genTest(type, xcdb) t5b.genTest(type, xcdb);
} else { };
t01.genTest(type, xcdb)
}
t5a.genTest(type, xcdb)
t5b.genTest(type, xcdb)
}
nocoTestSuite('rest', false) nocoTestSuite("rest", false);
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -43,7 +41,3 @@ nocoTestSuite('rest', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

62
scripts/cypress/integration/test/restTableOps.js

@ -1,38 +1,36 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t1a = require("../common/1a_table_operations");
let t1a = require('../common/1a_table_operations') let t1b = require("../common/1b_table_column_operations");
let t1b = require('../common/1b_table_column_operations') let t2a = require("../common/2a_table_with_belongs_to_colulmn");
let t2a = require('../common/2a_table_with_belongs_to_colulmn') let t2b = require("../common/2b_table_with_m2m_column");
let t2b = require('../common/2b_table_with_m2m_column') let t3a = require("../common/3a_filter_sort_fields_operations");
let t3a = require('../common/3a_filter_sort_fields_operations') let t3b = require("../common/3b_formula_column");
let t3b = require('../common/3b_formula_column') let t3c = require("../common/3c_lookup_column");
let t3c = require('../common/3c_lookup_column') let t3d = require("../common/3d_rollup_column");
let t3d = require('../common/3d_rollup_column')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
if (0 == executionMode) { t0.genTest(type, xcdb);
t0.genTest(type, xcdb) } else {
} else { t01.genTest(type, xcdb);
t01.genTest(type, xcdb) }
}
t1a.genTest(type, xcdb);
t1a.genTest(type, xcdb) t1b.genTest(type, xcdb);
t1b.genTest(type, xcdb) t2a.genTest(type, xcdb);
t2a.genTest(type, xcdb) t2b.genTest(type, xcdb);
t2b.genTest(type, xcdb) t3a.genTest(type, xcdb);
t3a.genTest(type, xcdb) t3b.genTest(type, xcdb);
t3b.genTest(type, xcdb) t3c.genTest(type, xcdb);
t3c.genTest(type, xcdb) t3d.genTest(type, xcdb);
t3d.genTest(type, xcdb) };
}
nocoTestSuite("rest", false);
nocoTestSuite('rest', false)
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -55,7 +53,3 @@ nocoTestSuite('rest', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

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

@ -1,34 +1,32 @@
let t0 = require("./explicitLogin");
let t0 = require('./explicitLogin') let t01 = require("../common/00_pre_configurations");
let t01 = require('../common/00_pre_configurations') let t4a = require("../common/4a_table_view_grid_gallery_form");
let t4a = require('../common/4a_table_view_grid_gallery_form') let t4b = require("../common/4b_table_view_share");
let t4b = require('../common/4b_table_view_share') let t4c = require("../common/4c_form_view_detailed");
let t4c = require('../common/4c_form_view_detailed') let t4d = require("../common/4d_table_view_grid_locked");
let t4d = require('../common/4d_table_view_grid_locked') let t4e = require("../common/4e_form_view_share");
let t4e = require('../common/4e_form_view_share') let t4f = require("../common/4f_grid_view_share");
let t4f = require('../common/4f_grid_view_share')
// use 0 as mode to execute individual files (debug mode, skip pre-configs) // use 0 as mode to execute individual files (debug mode, skip pre-configs)
// use 1 mode if noco.db doesnt contain user credentials (full run over GIT) // use 1 mode if noco.db doesnt contain user credentials (full run over GIT)
const executionMode = 1 const executionMode = 1;
const nocoTestSuite = (type, xcdb) => { const nocoTestSuite = (type, xcdb) => {
if (0 == executionMode) {
if (0 == executionMode) { t0.genTest(type, xcdb);
t0.genTest(type, xcdb) } else {
} else { t01.genTest(type, xcdb);
t01.genTest(type, xcdb) }
}
t4a.genTest(type, xcdb);
t4a.genTest(type, xcdb) t4b.genTest(type, xcdb);
t4b.genTest(type, xcdb) t4c.genTest(type, xcdb);
t4c.genTest(type, xcdb) t4d.genTest(type, xcdb);
t4d.genTest(type, xcdb) t4e.genTest(type, xcdb);
t4e.genTest(type, xcdb) t4f.genTest(type, xcdb);
t4f.genTest(type, xcdb) };
}
nocoTestSuite("rest", false);
nocoTestSuite('rest', false)
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
@ -51,7 +49,3 @@ nocoTestSuite('rest', false)
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */

35
scripts/cypress/plugins/index.js

@ -11,10 +11,10 @@
// This function is called when a project is opened or re-opened (e.g. due to // This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing) // the project's config changing)
const { rmdir } = require('fs') const { rmdir } = require("fs");
// https://stackoverflow.com/questions/61934443/read-excel-files-in-cypress // https://stackoverflow.com/questions/61934443/read-excel-files-in-cypress
const readXlsx = require('./read-xlsx') const readXlsx = require("./read-xlsx");
/** /**
* @type {Cypress.PluginConfig} * @type {Cypress.PluginConfig}
@ -25,28 +25,27 @@ module.exports = (on, config) => {
// `config` is the resolved Cypress config // `config` is the resolved Cypress config
// register utility tasks to read and parse Excel files // register utility tasks to read and parse Excel files
on('task', { on("task", {
deleteFolder (folderName) { deleteFolder(folderName) {
console.log('deleting folder %s', folderName) console.log("deleting folder %s", folderName);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => { rmdir(folderName, { maxRetries: 10, recursive: true }, (err) => {
if (err) { if (err) {
console.error(err) console.error(err);
return reject(err) return reject(err);
} }
resolve(null) resolve(null);
}) });
}) });
}, },
'readXlsx': readXlsx.read, readXlsx: readXlsx.read,
'readSheetList': readXlsx.sheetList, readSheetList: readXlsx.sheetList,
log(message) { log(message) {
console.log(message) console.log(message);
return null return null;
} },
}) });
} };

34
scripts/cypress/plugins/read-xlsx.js

@ -1,14 +1,14 @@
// https://stackoverflow.com/questions/61934443/read-excel-files-in-cypress // https://stackoverflow.com/questions/61934443/read-excel-files-in-cypress
const fs = require('fs'); const fs = require("fs");
const XLSX = require('xlsx'); const XLSX = require("xlsx");
const read = ({file, sheet}) => { const read = ({ file, sheet }) => {
const buf = fs.readFileSync(file); const buf = fs.readFileSync(file);
const workbook = XLSX.read(buf, { type: 'buffer' }); const workbook = XLSX.read(buf, { type: "buffer" });
const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]); const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
return rows return rows;
} };
// const read = ({file, sheet}) => { // const read = ({file, sheet}) => {
// const buf = fs.readFileSync(file); // const buf = fs.readFileSync(file);
@ -20,14 +20,14 @@ const read = ({file, sheet}) => {
// return rows // return rows
// } // }
const sheetList = ({file}) => { const sheetList = ({ file }) => {
const buf = fs.readFileSync(file); const buf = fs.readFileSync(file);
const workbook = XLSX.read(buf, { type: 'buffer' }); const workbook = XLSX.read(buf, { type: "buffer" });
const rows = workbook.SheetNames const rows = workbook.SheetNames;
return rows return rows;
} };
module.exports = { module.exports = {
read, read,
sheetList, sheetList,
} };

341
scripts/cypress/support/commands.js

@ -24,259 +24,272 @@
// -- This will overwrite an existing command -- // -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
import 'cypress-file-upload'; import "cypress-file-upload";
require('@4tw/cypress-drag-drop') require("@4tw/cypress-drag-drop");
// for waiting until page load // for waiting until page load
Cypress.Commands.add('waitForSpinners', () => { Cypress.Commands.add("waitForSpinners", () => {
cy.visit('http://localhost:3000', { cy.visit("http://localhost:3000", {
retryOnNetworkFailure: true, retryOnNetworkFailure: true,
timeout: 1200000, timeout: 1200000,
headers: { headers: {
"Accept-Encoding": "gzip, deflate" "Accept-Encoding": "gzip, deflate",
} },
}) });
cy.get('#nuxt-loading', {timeout: 10_0000}).should('have.length', 0) cy.get("#nuxt-loading", { timeout: 10_0000 }).should("have.length", 0);
}) });
Cypress.Commands.add('signinOrSignup', (_args) => { Cypress.Commands.add("signinOrSignup", (_args) => {
const args = Object.assign({username: 'user@nocodb.com', password: 'Password123.'}, _args) const args = Object.assign(
{ username: "user@nocodb.com", password: "Password123." },
_args
);
// signin/signup // signin/signup
cy.get('body').then(($body) => { cy.get("body").then(($body) => {
// cy.wait(1000) // cy.wait(1000)
cy.url().then(url => { cy.url().then((url) => {
if (!url.includes('/projects')) { if (!url.includes("/projects")) {
// handle initial load // handle initial load
if ($body.find('.welcome-page').length > 0) { if ($body.find(".welcome-page").length > 0) {
cy.wait(8000); cy.wait(8000);
cy.get('body').trigger('mousemove'); cy.get("body").trigger("mousemove");
cy.contains('Let\'s Begin').click(); cy.contains("Let's Begin").click();
cy.get('input[type="text"]', { timeout: 12000 }).type(args.username); cy.get('input[type="text"]', { timeout: 12000 }).type(args.username);
cy.get('input[type="password"]').type(args.password); cy.get('input[type="password"]').type(args.password);
cy.get('button:contains("SIGN UP")').click() cy.get('button:contains("SIGN UP")').click();
// handle signin // handle signin
} else { } else {
cy.get('input[type="text"]', { timeout: 12000 }).type(args.username); cy.get('input[type="text"]', { timeout: 12000 }).type(args.username);
cy.get('input[type="password"]').type(args.password); cy.get('input[type="password"]').type(args.password);
cy.get('button:contains("SIGN IN")').click() cy.get('button:contains("SIGN IN")').click();
} }
} }
}) });
}) });
// indicates page-load complete // indicates page-load complete
cy.get('.nc-noco-brand-icon', { timeout: 12000 }).should('exist') cy.get(".nc-noco-brand-icon", { timeout: 12000 }).should("exist");
}); });
// for opening/creating a rest project // for opening/creating a rest project
Cypress.Commands.add('openOrCreateRestProject', (_args) => { Cypress.Commands.add("openOrCreateRestProject", (_args) => {
const args = Object.assign({new: false}, _args) const args = Object.assign({ new: false }, _args);
// signin/signup // signin/signup
cy.signinOrSignup() cy.signinOrSignup();
cy.get('.nc-new-project-menu').should('exist') cy.get(".nc-new-project-menu").should("exist");
cy.get('body').then($body => { cy.get("body").then(($body) => {
const filter = args.meta ? '.nc-meta-project-row' : ':not(.nc-meta-project-row)'; const filter = args.meta
// if project exist open ? ".nc-meta-project-row"
if ($body.find('.nc-rest-project-row').filter(filter).length && !args.new) { : ":not(.nc-meta-project-row)";
cy.get('.nc-rest-project-row').filter(filter).first().click() // if project exist open
if ($body.find(".nc-rest-project-row").filter(filter).length && !args.new) {
cy.get(".nc-rest-project-row").filter(filter).first().click();
} else {
cy.contains("New Project").trigger("onmouseover").trigger("mouseenter");
if (args.meta) {
cy.get(".nc-create-xc-db-project").click();
cy.url({ timeout: 6000 }).should("contain", "#/project/xcdb");
cy.get(".nc-metadb-project-name").type("test_proj" + Date.now());
cy.contains("button", "Create", { timeout: 3000 }).click();
} else { } else {
cy.contains('New Project').trigger('onmouseover').trigger('mouseenter'); cy.get(".nc-create-external-db-project").click();
if (args.meta) { cy.url({ timeout: 6000 }).should("contain", "#/project");
cy.get('.nc-create-xc-db-project').click() cy.get(".database-field input").click().clear().type("sakila");
cy.url({timeout: 6000}).should('contain', '#/project/xcdb') cy.contains("Test Database Connection").click();
cy.get('.nc-metadb-project-name').type('test_proj' + Date.now()) cy.contains("Ok & Save Project", { timeout: 3000 }).click();
cy.contains('button','Create', {timeout: 3000}).click()
} else {
cy.get('.nc-create-external-db-project').click()
cy.url({timeout: 6000}).should('contain', '#/project')
cy.get('.database-field input').click().clear().type('sakila')
cy.contains('Test Database Connection').click()
cy.contains('Ok & Save Project', {timeout: 3000}).click()
}
} }
}) }
cy.url({timeout: 20000}).should('contain', '#/nc/') });
cy.url({ timeout: 20000 }).should("contain", "#/nc/");
} });
)
// tn: table name // tn: table name
// rc: row count. validate row count if rc!=0 // rc: row count. validate row count if rc!=0
Cypress.Commands.add('openTableTab', (tn, rc) => { Cypress.Commands.add("openTableTab", (tn, rc) => {
cy.get('.nc-project-tree') cy.get(".nc-project-tree")
.find('.v-list-item__title:contains(Tables)', { timeout: 10000 }) .find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
.should('exist') .should("exist")
.first().click() .first()
.click();
cy.get('.nc-project-tree') cy.get(".nc-project-tree")
.contains(tn, { timeout: 6000 }) .contains(tn, { timeout: 6000 })
.first() .first()
.click({ force: true }); .click({ force: true });
cy.get(`.project-tab:contains(${tn}):visible`) cy.get(`.project-tab:contains(${tn}):visible`).should("exist");
.should('exist')
cy.get(".nc-project-tree")
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
.first()
.click();
cy.get('.nc-project-tree')
.find('.v-list-item__title:contains(Tables)', { timeout: 10000 })
.first().click()
// wait for page rendering to complete // wait for page rendering to complete
if (rc != 0) { if (rc != 0) {
cy.get('.nc-grid-row').should('have.length', rc) cy.get(".nc-grid-row").should("have.length", rc);
} }
}) });
Cypress.Commands.add('closeTableTab', (tn) => { Cypress.Commands.add("closeTableTab", (tn) => {
cy.get(`[href="#table||db||${tn}"]`).find('button.mdi-close').click() cy.get(`[href="#table||db||${tn}"]`).find("button.mdi-close").click();
}) });
Cypress.Commands.add('openOrCreateGqlProject', (_args) => { Cypress.Commands.add("openOrCreateGqlProject", (_args) => {
const args = Object.assign({new: false, meta: false}, _args) const args = Object.assign({ new: false, meta: false }, _args);
cy.signinOrSignup() cy.signinOrSignup();
cy.get('.nc-new-project-menu').should('exist') cy.get(".nc-new-project-menu").should("exist");
cy.get('body').then($body => { cy.get("body").then(($body) => {
const filter = args.meta ? '.nc-meta-project-row' : ':not(.nc-meta-project-row)'; const filter = args.meta
? ".nc-meta-project-row"
: ":not(.nc-meta-project-row)";
// if project exist open // if project exist open
if ($body.find('.nc-graphql-project-row').filter(filter).length && !args.new) { if (
cy.get('.nc-graphql-project-row').filter(filter).first().click() $body.find(".nc-graphql-project-row").filter(filter).length &&
!args.new
) {
cy.get(".nc-graphql-project-row").filter(filter).first().click();
} else { } else {
cy.contains('New Project').trigger('onmouseover').trigger('mouseenter'); cy.contains("New Project").trigger("onmouseover").trigger("mouseenter");
if (args.meta) { if (args.meta) {
cy.get('.nc-create-xc-db-project').click() cy.get(".nc-create-xc-db-project").click();
cy.url({timeout: 6000}).should('contain', '#/project/xcdb') cy.url({ timeout: 6000 }).should("contain", "#/project/xcdb");
cy.contains('GRAPHQL APIs').closest('label').click(); cy.contains("GRAPHQL APIs").closest("label").click();
cy.get('.nc-metadb-project-name').type('test_proj' + Date.now()) cy.get(".nc-metadb-project-name").type("test_proj" + Date.now());
cy.contains('button','Create', {timeout: 3000}).click() cy.contains("button", "Create", { timeout: 3000 }).click();
} else { } else {
cy.get('.nc-create-external-db-project').click() cy.get(".nc-create-external-db-project").click();
cy.url({timeout: 6000}).should('contain', '#/project') cy.url({ timeout: 6000 }).should("contain", "#/project");
cy.contains('GRAPHQL APIs').closest('label').click() cy.contains("GRAPHQL APIs").closest("label").click();
cy.get('.database-field input').click().clear().type('sakila') cy.get(".database-field input").click().clear().type("sakila");
cy.contains('Test Database Connection').click() cy.contains("Test Database Connection").click();
cy.contains('Ok & Save Project', {timeout: 3000}).click() cy.contains("Ok & Save Project", { timeout: 3000 }).click();
} }
} }
}) });
cy.url({timeout: 20000}).should('contain', '#/nc/') cy.url({ timeout: 20000 }).should("contain", "#/nc/");
});
})
let LOCAL_STORAGE_MEMORY = {}; let LOCAL_STORAGE_MEMORY = {};
Cypress.Commands.add("saveLocalStorage", () => { Cypress.Commands.add("saveLocalStorage", () => {
Object.keys(localStorage).forEach(key => { Object.keys(localStorage).forEach((key) => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key]; LOCAL_STORAGE_MEMORY[key] = localStorage[key];
}); });
}); });
Cypress.Commands.add("restoreLocalStorage", () => { Cypress.Commands.add("restoreLocalStorage", () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => { Object.keys(LOCAL_STORAGE_MEMORY).forEach((key) => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]); localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
}); });
}); });
Cypress.Commands.add("getActiveModal", () => { Cypress.Commands.add("getActiveModal", () => {
return cy.get('.v-dialog.v-dialog--active').last() return cy.get(".v-dialog.v-dialog--active").last();
}); });
Cypress.Commands.add("getActiveMenu", () => { Cypress.Commands.add("getActiveMenu", () => {
return cy.get('.menuable__content__active').last() return cy.get(".menuable__content__active").last();
}); });
Cypress.Commands.add("getActiveContentModal", () => { Cypress.Commands.add("getActiveContentModal", () => {
return cy.get('.v-dialog__content--active').last() return cy.get(".v-dialog__content--active").last();
}); });
Cypress.Commands.add("createTable", (name) => {
cy.get(".add-btn").click();
cy.get('.nc-create-table-card .nc-table-name input[type="text"]')
.first()
.click()
.clear()
.type(name);
cy.get('.nc-create-table-card .nc-table-name-alias input[type="text"]')
.first()
.should("have.value", name.toLowerCase());
cy.get(".nc-create-table-card .nc-create-table-submit").first().click();
cy.toastWait(`Create table.${name} successful`);
cy.get(`.project-tab:contains(${name})`).should("exist");
cy.url().should("contain", `name=${name}`);
});
Cypress.Commands.add('createTable', (name) => { Cypress.Commands.add("deleteTable", (name) => {
cy.get('.add-btn').click(); cy.get(".nc-project-tree")
cy.get('.nc-create-table-card .nc-table-name input[type="text"]').first().click().clear().type(name) .find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
cy.get('.nc-create-table-card .nc-table-name-alias input[type="text"]').first().should('have.value', name.toLowerCase()) .first()
cy.get('.nc-create-table-card .nc-create-table-submit').first().click() .click();
cy.toastWait(`Create table.${name} successful`) cy.get(".nc-project-tree")
cy.get(`.project-tab:contains(${name})`).should('exist') .contains(name, { timeout: 6000 })
cy.url().should('contain', `name=${name}`) .first()
}) .click({ force: true });
cy.get(`.project-tab:contains(${name}):visible`).should("exist");
Cypress.Commands.add('deleteTable', (name) => { cy.get(".nc-table-delete-btn:visible").click();
cy.get('.nc-project-tree').find('.v-list-item__title:contains(Tables)', {timeout: 10000}) cy.get("button:contains(Submit)").click();
.first().click() cy.toastWait(`Delete table.${name} successful`);
cy.get('.nc-project-tree').contains(name, {timeout: 6000}).first().click({force: true}); });
cy.get(`.project-tab:contains(${name}):visible`).should('exist')
cy.get('.nc-table-delete-btn:visible').click() Cypress.Commands.add("renameTable", (oldName, newName) => {
cy.get('button:contains(Submit)').click()
cy.toastWait(`Delete table.${name} successful`)
})
Cypress.Commands.add('renameTable', (oldName, newName) => {
// expand project tree // expand project tree
cy.get('.nc-project-tree') cy.get(".nc-project-tree")
.find('.v-list-item__title:contains(Tables)', { timeout: 10000 }) .find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
.first() .first()
.click() .click();
// right click on project table name // right click on project table name
cy.get('.nc-project-tree') cy.get(".nc-project-tree")
.contains(oldName, { timeout: 6000 }) .contains(oldName, { timeout: 6000 })
.first() .first()
.rightclick() .rightclick();
// choose rename option from menu // choose rename option from menu
cy.getActiveMenu() cy.getActiveMenu()
.find('[role="menuitem"]') .find('[role="menuitem"]')
.contains('Table Rename') .contains("Table Rename")
.click({ force: true }) .click({ force: true });
// feed new name // feed new name
cy.getActiveContentModal() cy.getActiveContentModal().find("input").clear().type(newName);
.find('input')
.clear()
.type(newName)
// submit // submit
cy.getActiveContentModal() cy.getActiveContentModal().find("button").contains("Submit").click();
.find('button')
.contains('Submit')
.click()
cy.toastWait('Table renamed successfully')
// close expanded project tree cy.toastWait("Table renamed successfully");
cy.get('.nc-project-tree')
.find('.v-list-item__title:contains(Tables)', { timeout: 10000 }) // close expanded project tree
cy.get(".nc-project-tree")
.find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
.first() .first()
.click() .click();
}) });
Cypress.Commands.add('createColumn', (table, columnName) => { Cypress.Commands.add("createColumn", (table, columnName) => {
cy.get('.nc-project-tree').find('.v-list-item__title:contains(Tables)', {timeout: 10000}) cy.get(".nc-project-tree")
.first().click() .find(".v-list-item__title:contains(Tables)", { timeout: 10000 })
cy.get('.nc-project-tree').contains(table, {timeout: 6000}).first().click({force: true}); .first()
cy.get(`.project-tab:contains(${table}):visible`).should('exist') .click();
cy.get('.v-window-item--active .nc-grid tr > th:last button').click({force: true}); cy.get(".nc-project-tree")
cy.get('.nc-column-name-input input').clear().type(columnName) .contains(table, { timeout: 6000 })
cy.get('.nc-col-create-or-edit-card').contains('Save').click() .first()
cy .click({ force: true });
.get('th:contains(new_column)') cy.get(`.project-tab:contains(${table}):visible`).should("exist");
.should('exist'); cy.get(".v-window-item--active .nc-grid tr > th:last button").click({
}) force: true,
});
Cypress.Commands.add('toastWait', (msg) => { cy.get(".nc-column-name-input input").clear().type(columnName);
cy.get('.toasted:visible', { timout: 6000 }) cy.get(".nc-col-create-or-edit-card").contains("Save").click();
.contains(msg) cy.get("th:contains(new_column)").should("exist");
.should('exist') });
cy.get('.toasted:visible', { timout: 6000 })
.contains(msg)
.should('not.exist')
})
Cypress.Commands.add("toastWait", (msg) => {
cy.get(".toasted:visible", { timout: 6000 }).contains(msg).should("exist");
cy.get(".toasted:visible", { timout: 6000 })
.contains(msg)
.should("not.exist");
});
// Drag n Drop // Drag n Drop
// refer: https://stackoverflow.com/a/55409853 // refer: https://stackoverflow.com/a/55409853
@ -388,5 +401,3 @@ Cypress.Commands.addAll(
} }
) )
*/ */

17
scripts/cypress/support/index.js

@ -14,20 +14,19 @@
// *********************************************************** // ***********************************************************
// Import commands.js using ES2015 syntax: // Import commands.js using ES2015 syntax:
import './commands' import "./commands";
// https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/ // https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/
import 'cypress-iframe' import "cypress-iframe";
// Alternatively you can use CommonJS syntax: // Alternatively you can use CommonJS syntax:
// require('./commands') // require('./commands')
Cypress.on("uncaught:exception", (err, runnable) => {
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from // returning false here prevents Cypress from
// failing the test // failing the test
console.log('uncaught:exception') console.log("uncaught:exception");
console.log(err) console.log(err);
console.log(runnable) console.log(runnable);
return false return false;
}) });

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

@ -1,4 +1,3 @@
const path = require("path"); const path = require("path");
/** /**
@ -6,334 +5,384 @@ const path = require("path");
* slate before starting. * slate before starting.
*/ */
export const deleteDownloadsFolder = () => { export const deleteDownloadsFolder = () => {
const downloadsFolder = Cypress.config('downloadsFolder') const downloadsFolder = Cypress.config("downloadsFolder");
cy.task('deleteFolder', downloadsFolder) cy.task("deleteFolder", downloadsFolder);
} };
// main page // main page
export class _mainPage { export class _mainPage {
constructor() {
constructor() { // Top Right items
this.SHARE = 0;
// Top Right items this.THEME_BODY = 1;
this.SHARE = 0 this.THEME_HEADER = 2;
this.THEME_BODY = 1 this.ALERT = 3;
this.THEME_HEADER = 2 this.LANGUAGE = 4;
this.ALERT = 3 this.USER = 5;
this.LANGUAGE = 4
this.USER = 5 // Top Left items
this.HOME = 0;
// Top Left items this.GIT_HOME = 1;
this.HOME = 0 this.GIT_STAR = 2;
this.GIT_HOME = 1 this.GIT_DOCS = 3;
this.GIT_STAR = 2
this.GIT_DOCS = 3 this.AUDIT = 0;
this.APPSTORE = 2;
this.AUDIT = 0 this.TEAM_N_AUTH = 3;
this.APPSTORE = 2 this.PROJ_METADATA = 4;
this.TEAM_N_AUTH = 3 this.ROLE_VIEW = 5;
this.PROJ_METADATA = 4 this.ROLE_VIEW_EDITOR = 6;
this.ROLE_VIEW = 5 this.ROLE_VIEW_COMMENTER = 7;
this.ROLE_VIEW_EDITOR = 6 this.ROLE_VIEW_VIEWER = 8;
this.ROLE_VIEW_COMMENTER = 7 this.ROLE_VIEW_RESET = 9;
this.ROLE_VIEW_VIEWER = 8
this.ROLE_VIEW_RESET = 9 this.roleURL = {};
}
this.roleURL = {}
} toolBarTopLeft(toolBarItem) {
return cy
toolBarTopLeft(toolBarItem) { .get("header.v-toolbar", { timeout: 20000 })
return cy.get('header.v-toolbar', {timeout: 20000}).eq(0).find('a').eq(toolBarItem) .eq(0)
.find("a")
.eq(toolBarItem);
}
toolBarTopRight(toolBarItem) {
return cy
.get("header.v-toolbar", { timeout: 20000 })
.eq(0)
.find("button")
.eq(toolBarItem);
}
navigationDraw(item) {
// if (item == this.ROLE_VIEW)
// return cy.get('.nc-nav-drawer').find('.v-list').last()
// else
// return cy.get('.nc-nav-drawer').find('.v-list > .v-list-item').eq(item)
switch (item) {
case this.AUDIT:
return cy.get(".nc-treeview-item-Audit");
case this.APPSTORE:
return cy.get(".nc-settings-appstore");
case this.TEAM_N_AUTH:
return cy.get(".nc-settings-teamauth");
case this.PROJ_METADATA:
return cy.get(".nc-settings-projmeta");
case this.ROLE_VIEW_EDITOR:
return cy.get(".nc-preview-editor");
case this.ROLE_VIEW_COMMENTER:
return cy.get(".nc-preview-commenter");
case this.ROLE_VIEW_VIEWER:
return cy.get(".nc-preview-viewer");
case this.ROLE_VIEW_RESET:
return cy.get(".nc-preview-reset");
} }
}
toolBarTopRight(toolBarItem) {
return cy.get('header.v-toolbar', {timeout: 20000}).eq(0).find('button').eq(toolBarItem) // add new user to specified role
} //
addNewUserToProject = (userCred, roleType) => {
navigationDraw(item) { let linkText;
// if (item == this.ROLE_VIEW)
// return cy.get('.nc-nav-drawer').find('.v-list').last() // click on New User button, feed details
// else cy.get('button:contains("New User")').first().click();
// return cy.get('.nc-nav-drawer').find('.v-list > .v-list-item').eq(item) cy.get('label:contains("Email")')
.next("input")
switch (item) { .type(userCred.username)
case this.AUDIT: .trigger("input");
return cy.get('.nc-treeview-item-Audit') cy.get('label:contains("Select User roles")').click();
case this.APPSTORE:
return cy.get('.nc-settings-appstore') // opt-in requested role & submit
case this.TEAM_N_AUTH: cy.getActiveMenu().contains(roleType).click();
return cy.get('.nc-settings-teamauth') cy.get(".nc-invite-or-save-btn").click();
case this.PROJ_METADATA:
return cy.get('.nc-settings-projmeta') cy.toastWait("Successfully updated the user details");
case this.ROLE_VIEW_EDITOR:
return cy.get('.nc-preview-editor') // get URL, invoke
case this.ROLE_VIEW_COMMENTER: cy.getActiveModal()
return cy.get('.nc-preview-commenter') .find(".v-alert")
case this.ROLE_VIEW_VIEWER: .then(($obj) => {
return cy.get('.nc-preview-viewer') linkText = $obj.text().trim();
case this.ROLE_VIEW_RESET: cy.log(linkText);
return cy.get('.nc-preview-reset') this.roleURL[roleType] = linkText;
}
} cy.get("body").click("right");
});
};
// add new user to specified role
addExistingUserToProject = (emailId, role) => {
cy.get('.v-list-item:contains("Team & Auth")').click();
cy.get(`tr:contains(${emailId})`)
.find(".mdi-plus", { timeout: 2000 })
.click();
cy.get(`tr:contains(${emailId})`)
.find(".mdi-pencil-outline", { timeout: 2000 })
.click();
cy.get("label:contains(Select User roles)").click();
// opt-in requested role & submit
// //
addNewUserToProject = (userCred, roleType) => { cy.getActiveMenu().contains(role).click();
cy.get(".nc-invite-or-save-btn").click();
let linkText cy.toastWait("Successfully updated the user details");
// click on New User button, feed details this.roleURL[role] = "http://localhost:3000/#/user/authentication/signin";
cy.get('button:contains("New User")').first().click() };
cy.get('label:contains("Email")').next('input').type(userCred.username).trigger('input')
cy.get('label:contains("Select User roles")').click() getCell = (columnHeader, cellNumber) => {
return cy.get(
// opt-in requested role & submit `tbody > :nth-child(${cellNumber}) > [data-col="${columnHeader}"]`
cy.getActiveMenu().contains(roleType).click() );
cy.get('.nc-invite-or-save-btn').click() };
cy.toastWait('Successfully updated the user details') getPagination = (pageNumber) => {
if (pageNumber == "<")
// get URL, invoke return cy.get(".nc-pagination .v-pagination > li:first-child");
cy.getActiveModal().find('.v-alert').then(($obj) => { if (pageNumber == ">")
linkText = $obj.text().trim() return cy.get(".nc-pagination .v-pagination > li:last-child");
cy.log(linkText)
this.roleURL[roleType] = linkText return cy.get(
`.nc-pagination .v-pagination > li:contains(${pageNumber}) button`
cy.get('body').click('right') );
}) };
}
getRow = (rowIndex) => {
addExistingUserToProject = (emailId, role) => { return cy.get(".xc-row-table").find("tr").eq(rowIndex);
};
cy.get('.v-list-item:contains("Team & Auth")').click()
cy.get(`tr:contains(${emailId})`).find('.mdi-plus', { timeout: 2000 }).click() addColumn = (colName, tableName) => {
cy.get(`tr:contains(${emailId})`).find('.mdi-pencil-outline', { timeout: 2000 }).click() cy.get(".v-window-item--active .nc-grid tr > th:last button").click({
force: true,
cy.get('label:contains(Select User roles)').click() });
cy.get(".nc-column-name-input input", { timeout: 3000 })
// opt-in requested role & submit .clear()
// .type(colName);
cy.getActiveMenu().contains(role).click() cy.get(".nc-col-create-or-edit-card").contains("Save").click();
cy.get('.nc-invite-or-save-btn').click() cy.toastWait(`Update table.${tableName} successful`);
cy.toastWait('Successfully updated the user details') };
this.roleURL[role] = "http://localhost:3000/#/user/authentication/signin" addColumnWithType = (colName, colType, tableName) => {
} cy.get(".v-window-item--active .nc-grid tr > th:last button").click({
force: true,
getCell = (columnHeader, cellNumber) => { });
return cy.get(`tbody > :nth-child(${cellNumber}) > [data-col="${columnHeader}"]`) cy.get(".nc-column-name-input input", { timeout: 3000 })
} .clear()
.type(colName);
getPagination = (pageNumber) => {
if (pageNumber == '<') // Column data type: to be set to lookup in this context
return cy.get('.nc-pagination .v-pagination > li:first-child') cy.get(".nc-ui-dt-dropdown").click();
if (pageNumber == '>') cy.getActiveMenu().contains(colType).click();
return cy.get('.nc-pagination .v-pagination > li:last-child')
cy.get(".nc-col-create-or-edit-card").contains("Save").click();
return cy.get(`.nc-pagination .v-pagination > li:contains(${pageNumber}) button`) cy.toastWait(`Update table.${tableName} successful`);
} };
getRow = (rowIndex) => { deleteColumn = (colName) => {
return cy.get('.xc-row-table').find('tr').eq(rowIndex) cy.get(`th:contains(${colName}) .mdi-menu-down`)
} .trigger("mouseover")
.click();
addColumn = (colName, tableName) => {
cy.get('.v-window-item--active .nc-grid tr > th:last button').click({ force: true }); cy.get(".nc-column-delete", { timeout: 5000 }).click();
cy.get('.nc-column-name-input input', { timeout: 3000 }).clear().type(colName) cy.get("button:contains(Confirm)").click();
cy.get('.nc-col-create-or-edit-card').contains('Save').click() };
cy.toastWait(`Update table.${tableName} successful`)
} getAuthToken = () => {
let obj = JSON.parse(localStorage["vuex"]);
addColumnWithType = (colName, colType, tableName) => { return obj["users"]["token"];
cy.get('.v-window-item--active .nc-grid tr > th:last button').click({ force: true }); };
cy.get('.nc-column-name-input input', { timeout: 3000 }).clear().type(colName)
configureSMTP = (from, host, port, secure) => {
// Column data type: to be set to lookup in this context cy.get(".v-card__title.title")
cy.get('.nc-ui-dt-dropdown').click() .contains("SMTP")
cy.getActiveMenu().contains(colType).click() .parents(".elevatio")
.find("button")
cy.get('.nc-col-create-or-edit-card').contains('Save').click() .contains(" Install ")
cy.toastWait(`Update table.${tableName} successful`) .click({ force: true });
} cy.getActiveModal()
.find('[placeholder="eg: admin@example.com"]')
deleteColumn = (colName) => { .click()
cy.get(`th:contains(${colName}) .mdi-menu-down`) .type(from);
.trigger('mouseover') cy.getActiveModal()
.click() .find('[placeholder="eg: smtp.example.com"]')
.click()
cy.get('.nc-column-delete', {timeout: 5000}).click() .type(host);
cy.get('button:contains(Confirm)').click() cy.getActiveModal().find('[placeholder="Port"]').click().type(port);
} cy.getActiveModal().find('[placeholder="Secure"]').click().type(secure);
cy.getActiveModal().find("button").contains("Save").click();
getAuthToken = () => { cy.toastWait(
let obj = JSON.parse(localStorage['vuex']) "Successfully installed and email notification will use SMTP configuration"
return obj["users"]["token"] );
} };
configureSMTP = (from, host, port, secure) => { resetSMTP = () => {
cy.get('.v-card__title.title') cy.get(".v-card__title.title")
.contains('SMTP') .contains("SMTP")
.parents('.elevatio') .parents(".elevatio")
.find('button') .find("button")
.contains(" Install ") .contains(" Reset ")
.click({ force: true }) .click({ force: true });
cy.getActiveModal().find('[placeholder="eg: admin@example.com"]').click().type(from) cy.getActiveModal().find("button").contains("Submit").click();
cy.getActiveModal().find('[placeholder="eg: smtp.example.com"]').click().type(host) cy.toastWait("Plugin uninstalled successfully");
cy.getActiveModal().find('[placeholder="Port"]').click().type(port) };
cy.getActiveModal().find('[placeholder="Secure"]').click().type(secure)
cy.getActiveModal().find('button').contains('Save').click() hideField = (field) => {
cy.toastWait('Successfully installed and email notification will use SMTP configuration') cy.get(".nc-grid-header-cell").contains(field).should("be.visible");
} cy.get(".nc-fields-menu-btn").click();
cy.get(
resetSMTP = () => { `.menuable__content__active .v-list-item label:contains(${field})`
cy.get('.v-card__title.title') ).click();
.contains('SMTP') cy.get(".nc-fields-menu-btn").click();
.parents('.elevatio') cy.get(".nc-grid-header-cell").contains(field).should("not.be.visible");
.find('button') };
.contains(" Reset ")
.click({ force: true }) unhideField = (field) => {
cy.getActiveModal().find('button').contains('Submit').click() cy.get(".nc-grid-header-cell").contains(field).should("not.be.visible");
cy.toastWait('Plugin uninstalled successfully') cy.get(".nc-fields-menu-btn").click();
} cy.get(
`.menuable__content__active .v-list-item label:contains(${field})`
hideField = (field) => { ).click();
cy.get('.nc-grid-header-cell').contains(field).should('be.visible') cy.get(".nc-fields-menu-btn").click();
cy.get('.nc-fields-menu-btn').click() cy.get(".nc-grid-header-cell").contains(field).should("be.visible");
cy.get(`.menuable__content__active .v-list-item label:contains(${field})`).click() };
cy.get('.nc-fields-menu-btn').click()
cy.get('.nc-grid-header-cell').contains(field).should('not.be.visible') sortField = (field, criteria) => {
} cy.get(".nc-sort-menu-btn").click();
cy.contains("Add Sort Option").click();
unhideField = (field) => { cy.get(".nc-sort-field-select div").first().click();
cy.get('.nc-grid-header-cell').contains(field).should('not.be.visible') cy.get(
cy.get('.nc-fields-menu-btn').click() `.menuable__content__active .v-list-item:contains(${field})`
cy.get(`.menuable__content__active .v-list-item label:contains(${field})`).click() ).click();
cy.get('.nc-fields-menu-btn').click() cy.get(".nc-sort-dir-select div").first().click();
cy.get('.nc-grid-header-cell').contains(field).should('be.visible') cy.get(
} `.menuable__content__active .v-list-item:contains(${criteria})`
).click();
sortField = (field, criteria) => { cy.get(".nc-sort-menu-btn").click();
cy.get('.nc-sort-menu-btn').click() };
cy.contains('Add Sort Option').click();
cy.get('.nc-sort-field-select div').first().click() clearSort = () => {
cy.get(`.menuable__content__active .v-list-item:contains(${field})`).click() cy.get(".nc-sort-menu-btn").click();
cy.get('.nc-sort-dir-select div').first().click() cy.get(".nc-sort-item-remove-btn").click();
cy.get(`.menuable__content__active .v-list-item:contains(${criteria})`).click() cy.get(".nc-sort-menu-btn").click();
cy.get('.nc-sort-menu-btn').click() };
}
filterField = (field, operation, value) => {
clearSort = () => { cy.get(".nc-filter-menu-btn").click();
cy.get('.nc-sort-menu-btn').click() cy.contains("Add Filter").click();
cy.get('.nc-sort-item-remove-btn').click()
cy.get('.nc-sort-menu-btn').click() cy.get(".nc-filter-field-select").last().click();
cy.getActiveMenu().find(`.v-list-item:contains(${field})`).first().click();
cy.get(".nc-filter-operation-select").last().click();
cy.getActiveMenu().find(`.v-list-item:contains(${operation})`).click();
if (operation != "is null" && operation != "is not null") {
cy.get(".nc-filter-value-select input:text").last().type(`${value}`);
} }
filterField = (field, operation, value) => { cy.get(".nc-filter-field-select")
cy.get('.nc-filter-menu-btn').click() .find(".v-select__slot")
cy.contains('Add Filter').click(); .contains(field)
.should("exist");
cy.get('.nc-filter-field-select').last().click(); cy.get(".nc-filter-operation-select")
cy.getActiveMenu().find(`.v-list-item:contains(${field})`).first().click() .find(".v-select__slot")
cy.get('.nc-filter-operation-select').last().click(); .contains(operation)
cy.getActiveMenu().find(`.v-list-item:contains(${operation})`).click() .should("exist");
if ((operation != 'is null') && (operation != 'is not null')) {
cy.get('.nc-filter-value-select input:text').last().type(`${value}`); cy.get(".nc-filter-menu-btn").click();
};
filterReset = () => {
cy.get(".nc-filter-menu-btn").click();
cy.get(".nc-filter-item-remove-btn").click();
cy.get(".nc-filter-menu-btn").click();
};
// delete created views
//
deleteCreatedViews = () => {
cy.get(".v-navigation-drawer__content > .container")
.find(".v-list > .v-list-item")
.contains("Share View")
.parent()
.find("button.mdi-dots-vertical")
.click();
cy.getActiveMenu().find(".v-list-item").contains("Views List").click();
cy.wait(1000);
// cy.get('.container').find('button.mdi-delete-outline')
cy.get('th:contains("View Link")')
.should("exist")
.parent()
.parent()
.next()
.find("tr")
.each(($tableRow) => {
cy.log($tableRow[0].childElementCount);
// one of the row would contain seggregation header ('other views)
if (4 == $tableRow[0].childElementCount) {
cy.wrap($tableRow).find("button").last().click();
cy.wait(1000);
} }
})
cy.get('.nc-filter-field-select').find('.v-select__slot').contains(field).should('exist') .then(() => {
cy.get('.nc-filter-operation-select').find('.v-select__slot').contains(operation).should('exist') cy.get(".v-overlay__content > .d-flex > .v-icon").click();
cy.toastWait("Deleted shared view successfully");
cy.get('.nc-filter-menu-btn').click() });
} };
filterReset = () => { // download CSV & verify
cy.get('.nc-filter-menu-btn').click() // download folder is configurable in cypress.
cy.get('.nc-filter-item-remove-btn').click() // trigger download
cy.get('.nc-filter-menu-btn').click() // wait for a while & check in configured download folder for the intended file
} // if it exists, verify it against 'expectedRecords' passed in as parameter
//
// delete created views downloadAndVerifyCsv = (filename, verifyCsv) => {
// cy.get(".nc-actions-menu-btn").click();
deleteCreatedViews = () => { cy.get(
cy.get('.v-navigation-drawer__content > .container') `.menuable__content__active .v-list-item span:contains("Download as CSV")`
.find('.v-list > .v-list-item') ).click();
.contains('Share View')
.parent().find('button.mdi-dots-vertical').click() cy.toastWait("Successfully exported all table data").then(() => {
// download folder path, read from config file
cy.getActiveMenu().find('.v-list-item').contains('Views List').click() const downloadsFolder = Cypress.config("downloadsFolder");
let filePath = path.join(downloadsFolder, filename);
cy.wait(1000)
// append download folder path with filename to generate full file path, retrieve file
// cy.get('.container').find('button.mdi-delete-outline') cy.readFile(filePath).then((fileData) => {
// from CSV, split into records (rows)
cy.get('th:contains("View Link")').should('exist').parent().parent() const rows = fileData.replace(/\r\n/g, "\n").split("\n");
.next().find('tr').each(($tableRow) => { verifyCsv(rows);
cy.log($tableRow[0].childElementCount) deleteDownloadsFolder();
});
// one of the row would contain seggregation header ('other views) });
if (4 == $tableRow[0].childElementCount) { };
cy.wrap($tableRow).find('button').last().click()
cy.wait(1000) getIFrameCell = (columnHeader, cellNumber) => {
} return cy
}) .iframe()
.then(() => { .find(`tbody > :nth-child(${cellNumber}) > [data-col="${columnHeader}"]`);
cy.get('.v-overlay__content > .d-flex > .v-icon').click() };
cy.toastWait('Deleted shared view successfully')
}) // https://docs.cypress.io/guides/core-concepts/variables-and-aliases#Sharing-Context
} getDatatype = (tableName, columnName) => {
cy.window().then((win) => {
// download CSV & verify const col = win.$nuxt.$store.state.meta.metas[tableName].columns;
// download folder is configurable in cypress. let dataType = "";
// trigger download col.forEach((element) => {
// wait for a while & check in configured download folder for the intended file if (element.cn == columnName) dataType = element.uidt;
// if it exists, verify it against 'expectedRecords' passed in as parameter });
// cy.wrap(dataType).as("ncDatatype");
downloadAndVerifyCsv = (filename, verifyCsv) => { });
cy.get('.nc-actions-menu-btn').click() };
cy.get(`.menuable__content__active .v-list-item span:contains("Download as CSV")`).click()
cy.toastWait('Successfully exported all table data')
.then(() => {
// download folder path, read from config file
const downloadsFolder = Cypress.config("downloadsFolder")
let filePath = path.join(downloadsFolder, filename)
// append download folder path with filename to generate full file path, retrieve file
cy.readFile(filePath)
.then((fileData) => {
// from CSV, split into records (rows)
const rows = fileData.replace(/\r\n/g, '\n').split('\n');
verifyCsv(rows)
deleteDownloadsFolder()
})
})
}
getIFrameCell = (columnHeader, cellNumber) => {
return cy.iframe().find(`tbody > :nth-child(${cellNumber}) > [data-col="${columnHeader}"]`)
}
// https://docs.cypress.io/guides/core-concepts/variables-and-aliases#Sharing-Context
getDatatype = (tableName, columnName) => {
cy.window().then(win => {
const col = win.$nuxt.$store.state.meta.metas[tableName].columns
let dataType = ''
col.forEach(element => {
if(element.cn == columnName)
dataType = element.uidt
})
cy.wrap(dataType).as('ncDatatype')
})
}
} }
export const mainPage = new _mainPage();
export const mainPage = new _mainPage;
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

524
scripts/cypress/support/page_objects/navigation.js

@ -1,269 +1,305 @@
import { roles, staticProjects, defaultDbParams } from "./projectConstants";
import { roles, staticProjects, defaultDbParams } from "./projectConstants"
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// Sign in/ Sign up page // Sign in/ Sign up page
// list of hard-wired URL that can be used by nocodb // list of hard-wired URL that can be used by nocodb
// suffix to baseUrl needs to be defined here // suffix to baseUrl needs to be defined here
// //
const urlPool = { const urlPool = {
ncUrlBase: "/", ncUrlBase: "/",
ncUrlSignUp: "#/user/authentication/signup", ncUrlSignUp: "#/user/authentication/signup",
ncUrlSignIn: "#/user/authentication/signin" ncUrlSignIn: "#/user/authentication/signin",
} };
export class _loginPage { export class _loginPage {
// prefix: baseUrl
// prefix: baseUrl go(urlKey) {
go(urlKey) { cy.visit(urlKey);
cy.visit(urlKey) }
}
// visit SignIn URL, enter credentials passed as parameters
// visit SignIn URL, enter credentials passed as parameters //
// signIn(userCredentials) {
signIn(userCredentials) { this.go(urlPool.ncUrlSignIn);
this.go(urlPool.ncUrlSignIn)
cy.get('input[type="text"]', { timeout: 20000 }).type(
cy.get('input[type="text"]', {timeout: 20000}).type(userCredentials.username) userCredentials.username
cy.get('input[type="password"]').type(userCredentials.password) );
cy.get('button:contains("SIGN IN")').click() cy.get('input[type="password"]').type(userCredentials.password);
cy.get('button:contains("SIGN IN")').click();
this.waitProjectPageLoad()
this.waitProjectPageLoad();
}
// visit SignUp URL, enter credentials passed as parameters
//
signUp(userCredentials) {
this.go(urlPool.ncUrlSignUp);
cy.get('input[type="text"]', { timeout: 20000 }).type(
userCredentials.username
);
cy.get('input[type="password"]').type(userCredentials.password);
cy.get('button:contains("SIGN UP")').click();
this.waitProjectPageLoad();
}
// delay/ wait utility routines
//
waitProjectPageLoad() {
cy.url({ timeout: 6000 }).should("contain", "#/project");
cy.get(".nc-new-project-menu").should("exist");
}
// standard pre-project activity
//
loginAndOpenProject(apiType, xcdb) {
loginPage.signIn(roles.owner.credentials);
if (!xcdb) {
if ("rest" == apiType)
projectsPage.openProject(staticProjects.externalREST.basic.name);
else projectsPage.openProject(staticProjects.externalGQL.basic.name);
} else {
if ("rest" == apiType)
projectsPage.openProject(staticProjects.sampleREST.basic.name);
else projectsPage.openProject(staticProjects.sampleGQL.basic.name);
} }
}
// visit SignUp URL, enter credentials passed as parameters
//
signUp(userCredentials) {
this.go(urlPool.ncUrlSignUp)
cy.get('input[type="text"]', {timeout: 20000}).type(userCredentials.username)
cy.get('input[type="password"]').type(userCredentials.password)
cy.get('button:contains("SIGN UP")').click()
this.waitProjectPageLoad()
}
// delay/ wait utility routines
//
waitProjectPageLoad() {
cy.url({ timeout: 6000 }).should('contain', '#/project')
cy.get('.nc-new-project-menu').should('exist')
}
// standard pre-project activity
//
loginAndOpenProject(apiType, xcdb) {
loginPage.signIn(roles.owner.credentials)
if(!xcdb) {
if ('rest' == apiType)
projectsPage.openProject(staticProjects.externalREST.basic.name)
else
projectsPage.openProject(staticProjects.externalGQL.basic.name)
}
else {
if ('rest' == apiType)
projectsPage.openProject(staticProjects.sampleREST.basic.name)
else
projectsPage.openProject(staticProjects.sampleGQL.basic.name)
}
}
} }
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// Projects page // Projects page
export class _projectsPage { export class _projectsPage {
// Project creation options
// Project creation options //
//
// {dbType, apiType, name}
// {dbType, apiType, name} // for external database, {databaseType, hostAddress, portNumber, username, password, databaseName}
// for external database, {databaseType, hostAddress, portNumber, username, password, databaseName}
// Open existing project
// Open existing project // TODO: add projectName validation
// TODO: add projectName validation //
// openProject(projectName) {
openProject(projectName) { cy.get("tbody").contains("tr", projectName).should("exist").click();
cy.get('tbody').contains('tr', projectName).should('exist').click()
// takes a while to load project
// takes a while to load project this.waitHomePageLoad();
this.waitHomePageLoad() }
}
// Create new project
// Create new project // Input:
// Input: // projectData {dbType, apiType, name}
// projectData {dbType, apiType, name} // dbCredentials {databaseType, hostAddress, portNumber, username, password, databaseName}
// dbCredentials {databaseType, hostAddress, portNumber, username, password, databaseName} // Returns: projectName
// Returns: projectName //
// // To configure
// To configure // SSL & advanced parameters
// SSL & advanced parameters // Database type selection
// Database type selection //
// createProject(projectData, cred) {
createProject(projectData, cred) { cy.get("body", { timeout: 2000 });
cy.get('body', { timeout: 2000 }) let projectName = projectData.name;
let projectName = projectData.name if (projectData.name == "") projectName = "test_proj" + Date.now();
if (projectData.name == '') // click on "New Project"
projectName = 'test_proj' + Date.now() cy.get(":nth-child(5) > .v-btn", { timeout: 20000 }).click();
// click on "New Project" if ("none" == projectData.dbType) {
cy.get(':nth-child(5) > .v-btn', {timeout: 20000}).click() // Subsequent form, select (+ Create) option
cy.get(".nc-create-xc-db-project", { timeout: 20000 }).click({
if ('none' == projectData.dbType) { force: true,
});
// Subsequent form, select (+ Create) option
cy.get('.nc-create-xc-db-project', {timeout: 20000}).click({ force: true }) // feed project name
cy.get(".nc-metadb-project-name", { timeout: 20000 }).type(projectName);
// feed project name
cy.get('.nc-metadb-project-name', {timeout: 20000}).type(projectName) // Radio button: defaults to NC_REST
if ("GQL" == projectData.apiType) {
// Radio button: defaults to NC_REST cy.contains("GRAPHQL APIs").closest("label").click();
if ('GQL' == projectData.apiType) { }
cy.contains('GRAPHQL APIs').closest('label').click();
} // Submit
cy.contains("button", "Create", { timeout: 20000 }).click();
// Submit
cy.contains('button', 'Create', { timeout: 20000 }).click() // takes a while to load project
this.waitHomePageLoad();
// takes a while to load project
this.waitHomePageLoad() return projectName;
return projectName
}
// dbType == 'external'
else {
// Subsequent form, select (+ Create by connection to external database) option
cy.get('.nc-create-external-db-project', {timeout: 20000}).click({ force: true })
// feed project name
//cy.get('.nc-metadb-project-name').type(projectName)
cy.contains('Enter Project Name', {timeout: 20000}).parent().find('input').clear().type(projectName)
// Radio button: defaults to NC_REST
if ('GQL' == projectData.apiType) {
cy.contains('GRAPHQL APIs').closest('label').click();
}
if (cred.hostAddress != '') cy.contains('Host Address').parent().find('input').clear().type(cred.hostAddress)
if (cred.portNumber != '') cy.contains('Port Number').parent().find('input').clear().type(cred.portNumber)
if (cred.username != '') cy.contains('Username').parent().find('input').clear().type(cred.username)
if (cred.password != '') cy.contains('Password').parent().find('input').clear().type(cred.password)
if (cred.databaseName != '') cy.contains('Database : create if not exists').parent().find('input').clear().type(cred.databaseName)
// Test database connection
cy.contains('Test Database Connection', {timeout: 20000}).click()
// Create project
cy.contains('Ok & Save Project', { timeout: 20000 }).click()
// takes a while to load project
this.waitHomePageLoad()
return projectName
}
}
// create REST default project (sakila DB)
//
createDefaulRestProject() {
return this.createProject({ dbType: 1, apiType: 0, name: '' }, defaultDbParams )
}
// create GraphQL default project (sakila DB)
//
createDefaultGraphQlProject() {
return this.createProject({ dbType: 1, apiType: 1, name: '' }, defaultDbParams )
}
// Click on refresh key on projects page
//
refreshProject() {
cy.contains('My Projects').parent().find('button').click();
}
// search project with given key
// return project-name array
//
searchProject(projectNameKey) {
cy.get('input[placeholder="Search Project"]').type(projectNameKey)
const projectName = []
cy.get('table tr').each((tableRow) => {
cy.wrap(tableRow).find('td').eq(0).find('.title').then((input) => {
projectName.push(input.text())
})
})
.then(() => {
// TBD: validate project name to contain search key
console.log(projectName)
return projectName
})
}
// remove specified project entry
// TODO: error handling
//
deleteProject(name) {
// delete icon
cy.get('tbody').contains('tr', name).find('.mdi-delete-circle-outline').click()
cy.toastWait('deleted successfully')
// this.waitDeletePageLoad()
// pop-up, submit
cy.get('body').then((body) => {
cy.wrap(body).find('button').contains('Submit').click()
})
} }
// remove all projects created // dbType == 'external'
// else {
// 1. read all project names to be deleted, store in array // Subsequent form, select (+ Create by connection to external database) option
// 2. invoke delete project for each entry in array cy.get(".nc-create-external-db-project", { timeout: 20000 }).click({
// force: true,
// deleteAllProject() { });
// const projectName = [] // feed project name
//cy.get('.nc-metadb-project-name').type(projectName)
// cy.get('table tr').each((tableRow) => { cy.contains("Enter Project Name", { timeout: 20000 })
.parent()
// cy.wrap(tableRow).find('td').eq(0).find('.title').then((input) => { .find("input")
// projectName.push(input.text()) .clear()
// }) .type(projectName);
// })
// .then(() => { // Radio button: defaults to NC_REST
// console.log(projectName) if ("GQL" == projectData.apiType) {
// projectName.forEach(element => { cy.contains("GRAPHQL APIs").closest("label").click();
}
// // bring back the DOM to normalcy
// cy.get('div').parentsUntil('body') if (cred.hostAddress != "")
// this.deleteProject(element) cy.contains("Host Address")
.parent()
// // wait needed for pop up to disapper .find("input")
// this.waitDeletePageLoad() .clear()
// }) .type(cred.hostAddress);
// }) if (cred.portNumber != "")
// } cy.contains("Port Number")
.parent()
waitHomePageLoad() { .find("input")
cy.url({ timeout: 50000 }).should('contain', '&dbalias=') .clear()
.type(cred.portNumber);
if (cred.username != "")
cy.contains("Username")
.parent()
.find("input")
.clear()
.type(cred.username);
if (cred.password != "")
cy.contains("Password")
.parent()
.find("input")
.clear()
.type(cred.password);
if (cred.databaseName != "")
cy.contains("Database : create if not exists")
.parent()
.find("input")
.clear()
.type(cred.databaseName);
// Test database connection
cy.contains("Test Database Connection", { timeout: 20000 }).click();
// Create project
cy.contains("Ok & Save Project", { timeout: 20000 }).click();
// takes a while to load project
this.waitHomePageLoad();
return projectName;
} }
}
// create REST default project (sakila DB)
//
createDefaulRestProject() {
return this.createProject(
{ dbType: 1, apiType: 0, name: "" },
defaultDbParams
);
}
// create GraphQL default project (sakila DB)
//
createDefaultGraphQlProject() {
return this.createProject(
{ dbType: 1, apiType: 1, name: "" },
defaultDbParams
);
}
// Click on refresh key on projects page
//
refreshProject() {
cy.contains("My Projects").parent().find("button").click();
}
// search project with given key
// return project-name array
//
searchProject(projectNameKey) {
cy.get('input[placeholder="Search Project"]').type(projectNameKey);
const projectName = [];
cy.get("table tr")
.each((tableRow) => {
cy.wrap(tableRow)
.find("td")
.eq(0)
.find(".title")
.then((input) => {
projectName.push(input.text());
});
})
.then(() => {
// TBD: validate project name to contain search key
console.log(projectName);
return projectName;
});
}
// remove specified project entry
// TODO: error handling
//
deleteProject(name) {
// delete icon
cy.get("tbody")
.contains("tr", name)
.find(".mdi-delete-circle-outline")
.click();
cy.toastWait("deleted successfully");
// this.waitDeletePageLoad()
// pop-up, submit
cy.get("body").then((body) => {
cy.wrap(body).find("button").contains("Submit").click();
});
}
// remove all projects created
//
// 1. read all project names to be deleted, store in array
// 2. invoke delete project for each entry in array
//
// deleteAllProject() {
// const projectName = []
// cy.get('table tr').each((tableRow) => {
// cy.wrap(tableRow).find('td').eq(0).find('.title').then((input) => {
// projectName.push(input.text())
// })
// })
// .then(() => {
// console.log(projectName)
// projectName.forEach(element => {
// // bring back the DOM to normalcy
// cy.get('div').parentsUntil('body')
// this.deleteProject(element)
// // wait needed for pop up to disapper
// this.waitDeletePageLoad()
// })
// })
// }
waitHomePageLoad() {
cy.url({ timeout: 50000 }).should("contain", "&dbalias=");
}
} }
export const loginPage = new _loginPage; export const loginPage = new _loginPage();
export const projectsPage = new _projectsPage; export const projectsPage = new _projectsPage();
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

198
scripts/cypress/support/page_objects/projectConstants.js

@ -1,12 +1,11 @@
export const defaultDbParams = { export const defaultDbParams = {
databaseType: 0, // MySQL databaseType: 0, // MySQL
hostAddress: 'localhost', hostAddress: "localhost",
portNumber: '3306', portNumber: "3306",
username: 'root', username: "root",
password: 'password', password: "password",
databaseName: 'sakila' databaseName: "sakila",
} };
// database // database
// validation details // validation details
@ -16,92 +15,133 @@ export const defaultDbParams = {
// editComment: add comment // editComment: add comment
// shareView: right navigation bar (share options) // shareView: right navigation bar (share options)
export const roles = { export const roles = {
owner: { owner: {
name: 'owner', name: "owner",
credentials: { username: 'user@nocodb.com', password: 'Password123.' }, credentials: { username: "user@nocodb.com", password: "Password123." },
validations: { advSettings: true, editSchema: true, editData: true, editComment: true, shareView: true } validations: {
advSettings: true,
editSchema: true,
editData: true,
editComment: true,
shareView: true,
}, },
creator: { },
name: 'creator', creator: {
credentials: { username: 'creator@nocodb.com', password: 'Password123.' }, name: "creator",
validations: { advSettings: true, editSchema: true, editData: true, editComment: true, shareView: true } credentials: { username: "creator@nocodb.com", password: "Password123." },
validations: {
advSettings: true,
editSchema: true,
editData: true,
editComment: true,
shareView: true,
}, },
editor: { },
name: 'editor', editor: {
credentials: { username: 'editor@nocodb.com', password: 'Password123.' }, name: "editor",
validations: { advSettings: false, editSchema: false, editData: true, editComment: true, shareView: false } credentials: { username: "editor@nocodb.com", password: "Password123." },
validations: {
advSettings: false,
editSchema: false,
editData: true,
editComment: true,
shareView: false,
}, },
commenter: { },
name: 'commenter', commenter: {
credentials: { username: 'commenter@nocodb.com', password: 'Password123.' }, name: "commenter",
validations: { advSettings: false, editSchema: false, editData: false, editComment: true, shareView: false } credentials: { username: "commenter@nocodb.com", password: "Password123." },
validations: {
advSettings: false,
editSchema: false,
editData: false,
editComment: true,
shareView: false,
}, },
viewer: { },
name: 'viewer', viewer: {
credentials: { username: 'viewer@nocodb.com', password: 'Password123.' }, name: "viewer",
validations: { advSettings: false, editSchema: false, editData: false, editComment: false, shareView: false } credentials: { username: "viewer@nocodb.com", password: "Password123." },
} validations: {
} advSettings: false,
editSchema: false,
editData: false,
editComment: false,
shareView: false,
},
},
};
// default projects // default projects
// //
export const staticProjects = { export const staticProjects = {
sampleREST: { sampleREST: {
basic: { dbType: 'none', apiType: 'REST', name: 'sampleREST' }, basic: { dbType: "none", apiType: "REST", name: "sampleREST" },
config: {} config: {},
}, },
sampleGQL: { sampleGQL: {
basic: { dbType: 'none', apiType: 'GQL', name: 'sampleGQL' }, basic: { dbType: "none", apiType: "GQL", name: "sampleGQL" },
config: {} config: {},
}, },
externalREST: { externalREST: {
basic: { dbType: 'external', apiType: 'REST', name: 'externalREST' }, basic: { dbType: "external", apiType: "REST", name: "externalREST" },
config: defaultDbParams config: defaultDbParams,
}, },
externalGQL: { externalGQL: {
basic: { dbType: 'external', apiType: 'GQL', name: 'externalGQL' }, basic: { dbType: "external", apiType: "GQL", name: "externalGQL" },
config: defaultDbParams config: defaultDbParams,
} },
} };
// return TRUE if test suite specified is activated from env-variables // return TRUE if test suite specified is activated from env-variables
// //
export const isTestSuiteActive = (type, xcdb) => { export const isTestSuiteActive = (type, xcdb) => {
const env = Cypress.env('testMode') const env = Cypress.env("testMode");
if( !xcdb ) { if (!xcdb) {
switch( type ) { switch (type) {
case 'rest': return env.includes('extREST')?true:false; case "rest":
case 'graphql': return env.includes('extGQL')?true:false; return env.includes("extREST") ? true : false;
} case "graphql":
} else { return env.includes("extGQL") ? true : false;
switch( type ) { }
case 'rest': return env.includes('xcdbREST')?true:false; } else {
case 'graphql': return env.includes('xcdbGQL')?true:false; switch (type) {
} case "rest":
return env.includes("xcdbREST") ? true : false;
case "graphql":
return env.includes("xcdbGQL") ? true : false;
} }
} }
};
// expecting different modes to be seperated by a . // expecting different modes to be seperated by a .
export const getPrimarySuite = () => { export const getPrimarySuite = () => {
const env = Cypress.env('testMode').split('.') const env = Cypress.env("testMode").split(".");
switch(env[0]) { switch (env[0]) {
case 'extREST': return staticProjects.externalREST; case "extREST":
case 'extGQL': return staticProjects.externalGQL; return staticProjects.externalREST;
case 'xcdbREST': return staticProjects.sampleREST; case "extGQL":
case 'xcdbGQL': return staticProjects.sampleGQL; return staticProjects.externalGQL;
} case "xcdbREST":
} return staticProjects.sampleREST;
case "xcdbGQL":
return staticProjects.sampleGQL;
}
};
export const isSecondarySuite = (proj, xcdb) => { export const isSecondarySuite = (proj, xcdb) => {
if(!isTestSuiteActive(proj, xcdb)) if (!isTestSuiteActive(proj, xcdb)) return false;
return false;
const env = Cypress.env("testMode").split(".");
const env = Cypress.env('testMode').split('.')
switch (env[0]) {
switch(env[0]) { case "extREST":
case 'extREST': return (proj=='rest' && !xcdb)?false:true; return proj == "rest" && !xcdb ? false : true;
case 'extGQL': return (proj=='graphql' && !xcdb)?false:true; case "extGQL":
case 'xcdbREST': return (proj=='rest' && xcdb)?false:true; return proj == "graphql" && !xcdb ? false : true;
case 'xcdbGQL': return (proj=='graphql' && xcdb)?false:true; case "xcdbREST":
} return proj == "rest" && xcdb ? false : true;
} case "xcdbGQL":
return proj == "graphql" && xcdb ? false : true;
}
};

Loading…
Cancel
Save