diff --git a/cypress.config.ts b/cypress.config.ts index e5daee0..dd6c8b7 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -4,9 +4,18 @@ require('dotenv').config(); export default defineConfig({ projectId: process.env.CYPRESS_PROJECT_ID, e2e: { + pageLoadTimeout: 10000, baseUrl: 'https://demoqa.com', setupNodeEvents(on, config) { // implement node event listeners here + on('task', { + pause(ms) { + return new Promise((resolve) => { + // tasks should not resolve with undefined + setTimeout(() => resolve(null), ms); + }); + }, + }); }, }, }); diff --git a/cypress/e2e/elements/apresentacao.cy.ts b/cypress/e2e/elements/apresentacao.cy.ts index a12ea38..97f775e 100644 --- a/cypress/e2e/elements/apresentacao.cy.ts +++ b/cypress/e2e/elements/apresentacao.cy.ts @@ -1,10 +1,7 @@ -import HomePage from '../../pageObjects/home/HomePage'; import ElementsLink from '../../support/Enum/links/Elements'; -const Home = new HomePage(); beforeEach(() => { - cy.visitarToolsQA(); - Home.elements().click(); + cy.visitarToolsQA(ElementsLink.Elements); }); describe('Testes da página Elements', () => { diff --git a/cypress/e2e/elements/buttons.cy.ts b/cypress/e2e/elements/buttons.cy.ts new file mode 100644 index 0000000..39f2c59 --- /dev/null +++ b/cypress/e2e/elements/buttons.cy.ts @@ -0,0 +1,39 @@ +import ButtonsPage from '../../pageObjects/buttons/ButtonsPage'; +import ElementsLink from '../../support/Enum/links/Elements'; + +const Buttons = new ButtonsPage(); + +beforeEach(() => { + cy.visitarToolsQA(ElementsLink.Buttons); +}); + +describe('Botão Double Click', () => { + it('Verificar se o botão Double Click funciona e apresenta mensagem', () => { + Buttons.dbClickButton(true); + Buttons.dbClickMsg(true); + }); + + it('Verificar se DB click não funciona apenas com 1 click e não apresenta mensagem', () => { + Buttons.dbClickButton(false); + Buttons.dbClickMsg(false); + }); +}); + +describe('Botão Right Click', () => { + it('Verificar se Right click fubciona e apresenta mensagem', () => { + Buttons.rightClick(true); + Buttons.rightClickMsg(true); + }); + + it('Verificar se Right Click não funciona com Left Click e não apresenta mensagem', () => { + Buttons.rightClick(false); + Buttons.rightClickMsg(false); + }); +}); + +describe('Dynamic Click', () => { + it('Verificar se o clique dinâmico funciona e apresenta mensagem', () => { + Buttons.dynamicClick(); + Buttons.dynamicClickMsg(); + }); +}); diff --git a/cypress/e2e/elements/checkBox.cy.ts b/cypress/e2e/elements/checkBox.cy.ts index 1bee4bf..2ec56e3 100644 --- a/cypress/e2e/elements/checkBox.cy.ts +++ b/cypress/e2e/elements/checkBox.cy.ts @@ -1,15 +1,11 @@ -import HomePage from '../../pageObjects/home/HomePage'; import ElementsLink from '../../support/Enum/links/Elements'; import CheckBoxPage from '../../pageObjects/checkBox/CheckBoxPage'; import CheckBoxText from '../../support/Enum/CheckBoxText'; -const Home = new HomePage(); const CheckBox = new CheckBoxPage(); beforeEach(() => { - cy.visitarToolsQA(); - Home.elements().click(); - CheckBox.checkBoxMenu(); + cy.visitarToolsQA(ElementsLink.Checkbox); }); describe('Testes da tela com Check Box', () => { @@ -23,6 +19,7 @@ describe('Testes da tela com Check Box', () => { .should('be.visible') .and('contain.text', CheckBoxText.Home); + // TODO: Usar Within logo abaixo CheckBox.collapseExpandNode('home').then(() => { CheckBox.getNodeByLabel('desktop') .should('be.visible') @@ -120,6 +117,7 @@ describe('Testes da tela com Check Box', () => { CheckBox.expandAll(); CheckBox.getTreeNode().then(() => { + // TODO: Criar método para verificar visibilidade CheckBox.getNodeByLabel('desktop').should('be.visible'); CheckBox.getNodeByLabel('documents').should('be.visible'); CheckBox.getNodeByLabel('downloads').should('be.visible'); @@ -144,6 +142,7 @@ describe('Testes da tela com Check Box', () => { it('Home', () => { CheckBox.collapseExpandNode('home'); CheckBox.collapseExpandNode('home').then(() => { + // TODO: Criar método para verificar invisibilidade CheckBox.getNodeByLabel('desktop').should('not.exist'); CheckBox.getNodeByLabel('documents').should('not.exist'); CheckBox.getNodeByLabel('downloads').should('not.exist'); diff --git a/cypress/e2e/elements/radioButton.cy.ts b/cypress/e2e/elements/radioButton.cy.ts index a3e8324..cd9655b 100644 --- a/cypress/e2e/elements/radioButton.cy.ts +++ b/cypress/e2e/elements/radioButton.cy.ts @@ -1,14 +1,10 @@ -import HomePage from '../../pageObjects/home/HomePage'; import ElementsLink from '../../support/Enum/links/Elements'; import RadioButtonPage from '../../pageObjects/radioButton/RadioBtnPage'; -const Home = new HomePage(); const RadioButton = new RadioButtonPage(); beforeEach(() => { - cy.visitarToolsQA(); - Home.elements().click(); - RadioButton.radioBtnMenu(); + cy.visitarToolsQA(ElementsLink.RadioButton); }); describe('Testes da página de Radio Button', () => { @@ -16,6 +12,9 @@ describe('Testes da página de Radio Button', () => { cy.url().should('include', ElementsLink.RadioButton); }); + // TODO: Criar método checkRadio('radio:TypeRadio') + // TODO: criar método verifyRadio('checked:boolean, disabled?:boolean') + describe('Verificar os itens que foram marcados', () => { it('Marcar Yes', () => { RadioButton.yesByRadio().should('not.be.checked'); diff --git a/cypress/e2e/elements/textBox.cy.ts b/cypress/e2e/elements/textBox.cy.ts index 47937d2..8aa88e6 100644 --- a/cypress/e2e/elements/textBox.cy.ts +++ b/cypress/e2e/elements/textBox.cy.ts @@ -1,15 +1,11 @@ -import HomePage from '../../pageObjects/home/HomePage'; import TextBoxPage from '../../pageObjects/textBox/TextBoxPage'; import ElementsLink from '../../support/Enum/links/Elements'; -const Home = new HomePage(); const TextBox = new TextBoxPage(); - +const usuarioValidoFixture = '/usuarios/valido'; +const usuarioVazio = '/usuarios/vazio'; beforeEach(() => { - cy.visitarToolsQA(); - Home.elements().click(); - cy.fixture('/usuarios/valido').as('usuarioValido.fixture'); - TextBox.textBoxMenu(); + cy.visitarToolsQA(ElementsLink.Text_box); }); describe('Teste da tela com Text Box', () => { @@ -18,14 +14,17 @@ describe('Teste da tela com Text Box', () => { }); describe('Partição Valida', () => { + // TODO: Pegar dado por userForm e usar within + it('Preencher todos os campos com dados válidos', () => { - cy.fixture('/usuarios/valido').then((usuario) => { + cy.fixture(usuarioValidoFixture).then((usuario) => { TextBox.username().type(usuario.name); TextBox.email().type(usuario.email); TextBox.currentAddress().type(usuario.currentAddress); TextBox.permanentAddress().type(usuario.permanentAddress); TextBox.submitButton().click(); + // TODO: Passar o label para um enum TextBox.outputName() .should('contain.text', 'Name') .and('contain.text', usuario.name); @@ -42,7 +41,7 @@ describe('Teste da tela com Text Box', () => { }); it('Preencher somente o campo de Nome', () => { - cy.fixture('/usuarios/valido').then((usuario) => { + cy.fixture(usuarioValidoFixture).then((usuario) => { TextBox.username().type(usuario.name); TextBox.submitButton().click(); @@ -55,7 +54,7 @@ describe('Teste da tela com Text Box', () => { }); }); it('Preencher somente o campo de E-mail', () => { - cy.fixture('/usuarios/valido').then((usuario) => { + cy.fixture(usuarioValidoFixture).then((usuario) => { TextBox.email().type(usuario.email); TextBox.submitButton().click(); @@ -68,7 +67,7 @@ describe('Teste da tela com Text Box', () => { }); }); it('Preencher somente o campo de Endereço Atual', () => { - cy.fixture('/usuarios/valido').then((usuario) => { + cy.fixture(usuarioValidoFixture).then((usuario) => { TextBox.currentAddress().type(usuario.currentAddress); TextBox.submitButton().click(); @@ -81,7 +80,7 @@ describe('Teste da tela com Text Box', () => { }); }); it('Preencher somente o campo de Endereço Permanente', () => { - cy.fixture('/usuarios/valido').then((usuario) => { + cy.fixture(usuarioValidoFixture).then((usuario) => { TextBox.permanentAddress().type(usuario.permanentAddress); TextBox.submitButton().click(); @@ -97,7 +96,7 @@ describe('Teste da tela com Text Box', () => { describe('Partição Inválida', () => { it.skip('Preencher todos os campos com espaço em branco', () => { - cy.fixture('/usuarios/vazio').then((usuario) => { + cy.fixture(usuarioVazio).then((usuario) => { TextBox.username().type(usuario.name); TextBox.email().type(usuario.email); TextBox.currentAddress().type(usuario.currentAddress); @@ -112,7 +111,7 @@ describe('Teste da tela com Text Box', () => { TextBox.validateErrorEmail(); }); }); - it('Preencher campo de e-mail com e-mail inválido', () => { + it.skip('Preencher campo de e-mail com e-mail inválido', () => { cy.fixture('/usuarios/invalido').then((usuario) => { TextBox.username().type(usuario.name); TextBox.email().type(usuario.email); diff --git a/cypress/e2e/elements/webTables.cy.ts b/cypress/e2e/elements/webTables.cy.ts new file mode 100644 index 0000000..c99207b --- /dev/null +++ b/cypress/e2e/elements/webTables.cy.ts @@ -0,0 +1,222 @@ +import WebTablesPage from '../../pageObjects/webTables/WebTablePage'; +import ElementsLink from '../../support/Enum/links/Elements'; + +const WebTables = new WebTablesPage(); + +const msgTabbleNotFound = 'No rows found'; +const webTableDataFixture = '/webTables/data'; +const colunasFixture = '/webTables/colunas'; +const usuariosFixture = '/webTables/data'; +const validUserFixture = '/webTables/validUser'; +const emptyUserFixture = '/webTables/emptyUser'; +const invalidUserFixture = '/webTables/invalidUser'; +const editUserFixture = '/webTables/editUser'; + +beforeEach(() => { + cy.visitarToolsQA(ElementsLink.WebTables); +}); + +describe('Testes na WebTable', () => { + describe('Verifica apresentação dos usuários na tabela', () => { + it('Verifica as colunas ', () => { + WebTables.headerTable().within(($headerTable) => { + cy.fixture(colunasFixture).then((coluna) => { + expect($headerTable).to.contain(coluna.firstname); + expect($headerTable).to.contain(coluna.lastname); + expect($headerTable).to.contain(coluna.age); + expect($headerTable).to.contain(coluna.salary); + expect($headerTable).to.contain(coluna.department); + expect($headerTable).to.contain(coluna.action); + }); + }); + }); + + it('Verifica os dados da fixture por ordenação e valor', () => { + cy.fixture(usuariosFixture).then((usuario) => { + for (let i in usuario) { + WebTables.rowTable(parseInt(i)).within(($row) => { + expect($row).to.contain(usuario[i].firstname); + expect($row).to.contain(usuario[i].lastname); + expect($row).to.contain(usuario[i].age); + expect($row).to.contain(usuario[i].salary); + expect($row).to.contain(usuario[i].department); + }); + } + }); + }); + }); + + describe('Verifica a pesquisa dos usuários apresentados na tabela', () => { + it('Pesquisar usuário Inexistente - dado utilizado:Firstname', () => { + WebTables.searchUser(false, 'Inexistente'); + WebTables.verifyMsgTable(msgTabbleNotFound); + }); + + it('Pesquisar usuário com espaço em branco', () => { + WebTables.searchUser(false, ' '); + WebTables.verifyMsgTable(msgTabbleNotFound); + }); + + it('Pesquisar usuário com informação completa e com enter - dado utilizado:Firstname', () => { + cy.fixture(webTableDataFixture).then((data) => { + let firstname = data[0].firstname; + + WebTables.setSearchBox(`${firstname}{ENTER}`); + WebTables.verifyDataRowTable(firstname, true); + }); + }); + + it('Pesquisar usuário com informação incompleta - dado utilizado:Firstname', () => { + cy.fixture(webTableDataFixture).then((data) => { + let firstname = data[0].firstname; + + WebTables.setSearchBox(`${firstname}{BACKSPACE}{BACKSPACE}{BACKSPACE}`); + WebTables.searchBtn(); + WebTables.verifyDataRowTable(firstname, true); + }); + }); + + it('Pesquisar usuário com informação LowerCase - dado utilizado:Firstname', () => { + cy.fixture(webTableDataFixture).then((data) => { + let firstname = data[0].firstname; + + WebTables.setSearchBox(firstname.toLowerCase()); + WebTables.searchBtn(); + WebTables.verifyDataRowTable(firstname, true); + }); + }); + + it('Pesquisar usuário com informação UpperCase - dado utilizado:Firstname', () => { + cy.fixture(webTableDataFixture).then((data) => { + let firstname = data[0].firstname; + + WebTables.setSearchBox(firstname.toUpperCase()); + WebTables.searchBtn(); + WebTables.verifyDataRowTable(firstname, true); + }); + }); + }); + + describe('Adicionar usuário e verificar adição de usuário', () => { + it('Abrir e fechar modal', () => { + WebTables.modalVisible(false); + WebTables.newUserBtn(); + WebTables.modalVisible(true); + WebTables.modalClose(); + WebTables.modalVisible(false); + }); + + describe('Partição Válida', () => { + it('Adicionar usuário com todos os Dados válidos', () => { + WebTables.newUserBtn(); + cy.fixture(validUserFixture).then((user) => { + WebTables.createUser(user); + WebTables.verifyDataRowTable(user.firstname, true); + WebTables.verifyDataRowTable(user.lastname, true); + WebTables.verifyDataRowTable(user.age, true); + WebTables.verifyDataRowTable(user.email, true); + WebTables.verifyDataRowTable(user.salary, true); + WebTables.verifyDataRowTable(user.department, true); + }); + }); + }); + + describe('Partição inválida', () => { + it('Não preencher os campos e clicar em salvar', () => { + WebTables.newUserBtn(); + WebTables.formSubmit(); + WebTables.validateEmptyForm(); + }); + + it('Preenche os campos com espaço em branco e clicar em salvar', () => { + WebTables.newUserBtn(); + cy.fixture(emptyUserFixture).then((user) => { + WebTables.createUser(user); + }); + WebTables.validateEmptyForm(); + }); + + it('Preencher os campos com dados inválidos e clicar em salvar', () => { + WebTables.newUserBtn(); + cy.fixture(invalidUserFixture).then((user) => { + WebTables.createUser(user); + + WebTables.validateEmail(); + WebTables.validateSalary(); + WebTables.validateAge(); + + WebTables.verifyDataRowTable(user.firstname, false); + WebTables.verifyDataRowTable(user.lastname, false); + WebTables.verifyDataRowTable(user.email, false); + WebTables.verifyDataRowTable(user.age, false); + WebTables.verifyDataRowTable(user.salary, false); + WebTables.verifyDataRowTable(user.department, false); + }); + }); + }); + }); + + describe('Editar usuário verificar edição de usuário', () => { + it('Verificar visibilidade do modal', () => { + WebTables.modalVisible(false); + WebTables.newUserBtn(); + WebTables.modalVisible(true); + WebTables.modalClose(); + WebTables.modalVisible(false); + }); + + describe('Partição válida', () => { + it('Editar usuário com dados válidos', async () => { + let indiceRow = 0; + let row = WebTables.rowTable(indiceRow); + let oldUser = await WebTables.getDataRow(row); + + WebTables.editUserAction(indiceRow); + + cy.fixture(editUserFixture).then((editUser) => { + WebTables.editUser(oldUser, editUser); + + WebTables.verifyDataRowTable(editUser.firstname, true); + WebTables.verifyDataRowTable(editUser.lastname, true); + WebTables.verifyDataRowTable(editUser.age, true); + WebTables.verifyDataRowTable(editUser.email, true); + WebTables.verifyDataRowTable(editUser.salary, true); + WebTables.verifyDataRowTable(editUser.department, true); + + for (let dado of oldUser) { + WebTables.verifyDataRowTable(dado, false); + } + }); + }); + }); + + describe('Partição inválida', () => { + it('Editar usuário com campos vazios', async () => { + let indiceRow = 0; + let row = WebTables.rowTable(indiceRow); + let oldUser = await WebTables.getDataRow(row); + + WebTables.editUserAction(indiceRow); + + cy.fixture(emptyUserFixture).then((user) => { + WebTables.editUser(oldUser, user); + WebTables.validateEmptyForm(); + }); + }); + }); + }); + + describe('Excluir usuário', () => { + it.only('Excluir usuário e verificar exclusão', async () => { + let indiceRow = 0; + let row = WebTables.rowTable(indiceRow); + let oldUser = WebTables.getDataRow(row); + + WebTables.deleteUserAction(indiceRow); + + (await oldUser).forEach((dado) => { + WebTables.verifyDataRowTable(dado, false); + }); + }); + }); +}); diff --git a/cypress/e2e/home.cy.ts b/cypress/e2e/home.cy.ts index de42ee8..ffbdf33 100644 --- a/cypress/e2e/home.cy.ts +++ b/cypress/e2e/home.cy.ts @@ -4,7 +4,7 @@ import HomeLinks from '../support/Enum/links/Home'; const Home = new HomePage(); beforeEach(() => { - cy.visitarToolsQA(); + cy.visitarToolsQA('/'); }); describe('Teste de Home', () => { diff --git a/cypress/fixtures/webTables/colunas.json b/cypress/fixtures/webTables/colunas.json new file mode 100644 index 0000000..2013ff6 --- /dev/null +++ b/cypress/fixtures/webTables/colunas.json @@ -0,0 +1,9 @@ +{ + "firstname": "First Name", + "lastname": "Last Name", + "age": "Age", + "email": "Email", + "salary": "Salary", + "department": "Department", + "action": "Action" +} diff --git a/cypress/fixtures/webTables/data.json b/cypress/fixtures/webTables/data.json new file mode 100644 index 0000000..eb3eebc --- /dev/null +++ b/cypress/fixtures/webTables/data.json @@ -0,0 +1,26 @@ +{ + "0": { + "firstname": "Cierra", + "lastname": "Vega", + "age": "39", + "email": "cierra@example.com", + "salary": "10000", + "department": "Insurance" + }, + "01": { + "firstname": "Alden", + "lastname": "Cantrell", + "age": "45", + "email": "alden@example.com", + "salary": "12000", + "department": "Compliance" + }, + "02": { + "firstname": "Kierra", + "lastname": "Gentry", + "age": "29", + "email": "kierra@example.com", + "salary": "2000", + "department": "Legal" + } +} diff --git a/cypress/fixtures/webTables/editUser.json b/cypress/fixtures/webTables/editUser.json new file mode 100644 index 0000000..6333c6a --- /dev/null +++ b/cypress/fixtures/webTables/editUser.json @@ -0,0 +1,8 @@ +{ + "firstname": "firstname Editado", + "lastname": "lastname Editado", + "age": "20", + "email": "userEdit@example.com", + "salary": "2000", + "department": "Edição" +} diff --git a/cypress/fixtures/webTables/emptyUser.json b/cypress/fixtures/webTables/emptyUser.json new file mode 100644 index 0000000..c034756 --- /dev/null +++ b/cypress/fixtures/webTables/emptyUser.json @@ -0,0 +1,8 @@ +{ + "firstname": " ", + "lastname": " ", + "age": " ", + "email": " ", + "salary": " ", + "department": " " +} diff --git a/cypress/fixtures/webTables/invalidUser.json b/cypress/fixtures/webTables/invalidUser.json new file mode 100644 index 0000000..07198fe --- /dev/null +++ b/cypress/fixtures/webTables/invalidUser.json @@ -0,0 +1,8 @@ +{ + "firstname": "Maria", + "lastname": "Da Silva", + "age": "xxx", + "email": "m4ria", + "salary": "XXXX", + "department": "Garçom" +} diff --git a/cypress/fixtures/webTables/validUser.json b/cypress/fixtures/webTables/validUser.json new file mode 100644 index 0000000..19e5e0d --- /dev/null +++ b/cypress/fixtures/webTables/validUser.json @@ -0,0 +1,8 @@ +{ + "firstname": "Maria", + "lastname": "Da Silva", + "age": "45", + "email": "m4ria.silva@example.com", + "salary": "1412", + "department": "Garçom" +} diff --git a/cypress/pageObjects/buttons/ButtonsLocatos.ts b/cypress/pageObjects/buttons/ButtonsLocatos.ts new file mode 100644 index 0000000..b4a0ed9 --- /dev/null +++ b/cypress/pageObjects/buttons/ButtonsLocatos.ts @@ -0,0 +1,10 @@ +const ButtonsLocators = { + dbClickBtn: 'button#doubleClickBtn', + rightClickBtn: 'button#rightClickBtn', + dynamicBtnByXpath: '//button[text() = "Click Me"]', + dbClickMsg: 'p#doubleClickMessage', + rightClickMsg: 'p#rightClickMessage', + dynamicClickMsg: 'p#dynamicClickMessage', +}; + +export default ButtonsLocators; diff --git a/cypress/pageObjects/buttons/ButtonsPage.ts b/cypress/pageObjects/buttons/ButtonsPage.ts new file mode 100644 index 0000000..6fffd3e --- /dev/null +++ b/cypress/pageObjects/buttons/ButtonsPage.ts @@ -0,0 +1,50 @@ +import locator from './ButtonsLocatos'; +import mensagens from '../../support/Enum/ButtonsMsg'; + +class ButtonsPage { + dbClickButton(dbClick: boolean) { + dbClick === true + ? cy.get(locator.dbClickBtn).dblclick() + : cy.get(locator.dbClickBtn).click(); + } + + dbClickMsg(exist: boolean) { + exist === true + ? cy + .get(locator.dbClickMsg) + .should('exist') + .and('contain.text', mensagens.DbClickMsg) + .and('be.visible') + : cy.get(locator.dbClickMsg).should('not.exist'); + } + + rightClick(rightClick: boolean) { + rightClick === true + ? cy.get(locator.rightClickBtn).rightclick() + : cy.get(locator.rightClickBtn).click(); + } + + rightClickMsg(exist: boolean) { + exist === true + ? cy + .get(locator.rightClickMsg) + .should('exist') + .and('contain.text', mensagens.RightClickMsg) + .and('be.visible') + : cy.get(locator.rightClickMsg).should('not.exist'); + } + + dynamicClick() { + cy.xpath(locator.dynamicBtnByXpath).click(); + } + + dynamicClickMsg() { + cy + .get(locator.dynamicClickMsg) + .should('exist') + .and('contain.text', mensagens.DynamiClickMsg) + .and('be.visible'); + } +} + +export default ButtonsPage; diff --git a/cypress/pageObjects/checkBox/CheckBoxLocators.ts b/cypress/pageObjects/checkBox/CheckBoxLocators.ts index d65fcf9..191900f 100644 --- a/cypress/pageObjects/checkBox/CheckBoxLocators.ts +++ b/cypress/pageObjects/checkBox/CheckBoxLocators.ts @@ -1,4 +1,3 @@ -import CheckBoxNode from '../../support/Types/CheckBoxNode'; const CheckBoxLocators = { itemMenu: 'Check Box', collapseExpandBtn: 'button.rct-collapse-btn', diff --git a/cypress/pageObjects/textBox/TextBoxPage.ts b/cypress/pageObjects/textBox/TextBoxPage.ts index b862385..fa70012 100644 --- a/cypress/pageObjects/textBox/TextBoxPage.ts +++ b/cypress/pageObjects/textBox/TextBoxPage.ts @@ -46,6 +46,7 @@ class ElementsPage { return cy.get(locators.output).find(locators.permanentAddressInput); } + // TODO: Chamar commands validateErrorEmail() { return cy .get(locators.emailInput, { timeout: 6000 }) diff --git a/cypress/pageObjects/webTables/WebTableLocators.ts b/cypress/pageObjects/webTables/WebTableLocators.ts new file mode 100644 index 0000000..6c86eec --- /dev/null +++ b/cypress/pageObjects/webTables/WebTableLocators.ts @@ -0,0 +1,24 @@ +const WebTablesLocators = { + itemMenu: 'Web Tables', + searchInput: '#searchBox', + searchBtn: '.input-group-append', + headerTable: 'div.ReactTable div.rt-thead.-header', + rowTable: 'div[role="rowgroup"]', + newUserBtn: '#addNewRecordButton', + modal: 'div.modal-dialog[role="document"]', + modalCloseBtn: 'button.close', + userForm: '#userForm', + firstnameInput: 'input#firstName', + lasnameInput: 'input#lastName', + emailInput: 'input#userEmail', + ageInput: 'input#age', + salaryInput: 'input#salary', + departmentInput: 'input#department', + submitBtn: 'button[type="submit"]', + rowMsg: 'div.rt-noData', + divRow: 'div[role="row"]', + actionEdit: 'div.action-buttons>span[title="Edit"]', + actionDelete: 'div.action-buttons>span[title="Delete"]', +}; + +export default WebTablesLocators; diff --git a/cypress/pageObjects/webTables/WebTablePage.ts b/cypress/pageObjects/webTables/WebTablePage.ts new file mode 100644 index 0000000..02c86c9 --- /dev/null +++ b/cypress/pageObjects/webTables/WebTablePage.ts @@ -0,0 +1,159 @@ +import locators from './WebTableLocators'; + +class WebTablesPage { + webTablesMenu() { + return cy.getItemMenu(locators.itemMenu).click(); + } + + headerTable() { + return cy.get(locators.headerTable); + } + + /** + * + * @param indice indice da linha da tabela + * @returns todas as linhas da tabela ou a linha desejada da tabela pelo indice + * @example WebTables.rowTable(0); + */ + rowTable(indice?: number) { + return indice == undefined + ? cy + .get(locators.rowTable, { timeout: 8000 }) + .first() + .children(locators.divRow) + : cy + .get(locators.rowTable, { timeout: 8000 }) + .eq(indice) + .children(locators.divRow); + } + + search(text: string) { + cy.get(locators.searchInput).type(text); + } + + searchBtn() { + cy.get(locators.searchInput).siblings(locators.searchBtn).click(); + } + + searchUser(exist: boolean, text: string) { + cy.get(locators.searchInput).type(text); + cy.get(locators.searchInput).siblings(locators.searchBtn).click(); + + let firstRow = cy.get(locators.rowTable).first(); + + exist + ? firstRow.should('contain.text', text) + : firstRow.should('not.contain.text', text); + } + + setSearchBox(text: string) { + cy.get(locators.searchInput).type(text); + } + + verifyMsgTable(msg: string) { + cy.get(locators.rowMsg).should('contain.text', msg); + } + + verifyDataRowTable(text: string, contain: boolean) { + contain === true + ? cy.get(locators.rowTable).should('contain.text', text) + : cy.get(locators.rowTable).should('not.contain.text', text); + } + + newUserBtn() { + cy.get(locators.newUserBtn).click(); + } + + modalVisible(visible: boolean) { + visible + ? cy.get(locators.modal).should('be.visible') + : cy.get(locators.modal).should('not.exist'); + } + + modalClose() { + cy.get(locators.modalCloseBtn).click(); + } + + createUser(userFixture: user) { + cy.get(locators.userForm).within(() => { + cy.get(locators.firstnameInput).type(userFixture.firstname); + cy.get(locators.lasnameInput).type(userFixture.lastname); + cy.get(locators.ageInput).type(userFixture.age); + cy.get(locators.emailInput).type(userFixture.email); + cy.get(locators.salaryInput).type(userFixture.salary); + cy.get(locators.departmentInput).type(userFixture.department); + cy.get(locators.submitBtn).click(); + }); + } + + formSubmit() { + cy.get(locators.submitBtn).click(); + } + + validateEmptyForm() { + const tipo = 'error'; + cy.validateColors(tipo, locators.emailInput); + cy.validateColors(tipo, locators.ageInput); + cy.validateColors(tipo, locators.salaryInput); + } + + validadeFirstname() { + cy.validateColors('error', locators.firstnameInput); + } + + validateEmail() { + cy.validateColors('error', locators.emailInput); + } + + validateSalary() { + cy.validateColors('error', locators.salaryInput); + } + + validateAge() { + cy.validateColors('error', locators.ageInput); + } + + editUserAction(indiceRow: number) { + cy.get(locators.actionEdit).eq(indiceRow).click(); + } + + deleteUserAction(indiceRow: number) { + cy.get(locators.actionDelete).eq(indiceRow).click(); + } + + getFistRow() { + return cy.get(locators.actionEdit).first().parents(locators.divRow); + } + + editUser(userData: Array, editUserFixture: user) { + cy.get(locators.userForm).within(() => { + cy.validateOldUserForm(userData, true); + + cy.get(locators.lasnameInput).clear().type(editUserFixture.lastname); + cy.get(locators.ageInput).clear().type(editUserFixture.age); + cy.get(locators.emailInput).clear().type(editUserFixture.email); + cy.get(locators.salaryInput).clear().type(editUserFixture.salary); + cy.get(locators.departmentInput).clear().type(editUserFixture.department); + cy.get(locators.firstnameInput).clear().type(editUserFixture.firstname); + cy.get(locators.submitBtn).click(); + }); + } + + getDataRow(row: any): string[] { + let userData: string[] = []; + + row.then(($row: any) => { + let celulas = $row[0].childNodes; + + celulas.forEach((celula: any, i: number) => { + if (i != celulas.length - 1) { + userData.push(celula.textContent); + } + }); + }); + + return userData; + } +} + +export default WebTablesPage; diff --git a/cypress/support/Enum/ButtonsMsg.ts b/cypress/support/Enum/ButtonsMsg.ts new file mode 100644 index 0000000..c5878fb --- /dev/null +++ b/cypress/support/Enum/ButtonsMsg.ts @@ -0,0 +1,7 @@ +enum ButtonsMsg { + DbClickMsg = 'You have done a double click', + RightClickMsg = 'You have done a right click', + DynamiClickMsg = 'You have done a dynamic click', +} + +export default ButtonsMsg; diff --git a/cypress/support/Enum/Colors.ts b/cypress/support/Enum/Colors.ts index 2180238..064f7bd 100644 --- a/cypress/support/Enum/Colors.ts +++ b/cypress/support/Enum/Colors.ts @@ -1,5 +1,7 @@ enum Colors { - Error = 'rgb(255, 0, 0)', + Error = 'rgb(220, 53, 69)', + Standard = 'rgb(73, 80, 87)', + Success = 'rgb(40, 167, 69)', } export default Colors; diff --git a/cypress/support/Enum/links/Elements.ts b/cypress/support/Enum/links/Elements.ts index b9c4846..422d53a 100644 --- a/cypress/support/Enum/links/Elements.ts +++ b/cypress/support/Enum/links/Elements.ts @@ -3,6 +3,8 @@ enum Elements { Text_box = '/text-box', Checkbox = '/checkbox', RadioButton = '/radio-button', + WebTables = '/webtables', + Buttons = '/buttons/', } export default Elements; diff --git a/cypress/support/Types/user.ts b/cypress/support/Types/user.ts new file mode 100644 index 0000000..368f514 --- /dev/null +++ b/cypress/support/Types/user.ts @@ -0,0 +1,8 @@ +type user = { + firstname: string; + lastname: string; + age: string; + email: string; + salary: string; + department: string; +}; diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 5e95d4f..e9645d9 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -1,19 +1,57 @@ Cypress.Commands.add('getItemMenu', (textoItem: string) => { + // TODO: Adicionar a um locator cy.xpath( `//div[contains(@class,'show') and contains(@class,'collapse') ]/ul/li/span[contains(.,'${textoItem}')]` ); }); Cypress.Commands.add('verificaMensagemInicial', () => { + // TODO: Adicionar a um enum const mensagem = 'Please select an item from left to start practice.'; + // TODO: Adicionar a um locator return cy .xpath(`//div[contains(@class,'playgound-body')][contains(.,'${mensagem}')]`) .should('be.visible'); }); -Cypress.Commands.add('visitarToolsQA', () => { - cy.visit('/', { failOnStatusCode: false }); - Cypress.on('uncaught:exception', (err, runnable) => { - return false; - }); +Cypress.Commands.add('visitarToolsQA', (url: string) => { + //colocando 1min de timeout apenenas para as páginas de carregamento + cy.visit(url, { failOnStatusCode: false, timeout: 130000 }); }); + +import Colors from './Enum/Colors'; +Cypress.Commands.add( + 'validateColors', + (tipo: ResponseType, locator: string) => { + if (tipo == 'error') { + cy.get(locator, { timeout: 6000 }).and('css', 'border-color', Colors.Error); + } else if (tipo == 'default') { + cy + .get(locator, { timeout: 6000 }) + .and('css', 'border-color', Colors.Standard); + } else if ('basic') { + cy + .get(locator, { timeout: 6000 }) + .and('css', 'border-color', Colors.Success); + } + } +); + +Cypress.Commands.add('verificaUrl', (partialURL: string) => { + cy.url().should('equal', Cypress.config('baseUrl') + partialURL); +}); + +Cypress.Commands.add( + 'validateOldUserForm', + (userData: Array, exist: boolean) => { + if (exist === true) { + userData.forEach((dado) => { + cy.get(`input[value="${dado}"]`).should('exist'); + }); + } else { + userData.forEach((dado) => { + cy.get(`input[value="${dado}"]`).should('not.exist'); + }); + } + } +); diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index d04e352..9130481 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -2,13 +2,35 @@ import './commands'; require('@cypress/xpath'); +beforeEach(() => { + cy.session( + 'performance', + () => { + cy.visit('/', { timeout: 100000 }); + }, + { cacheAcrossSpecs: true } + ); +}); + +Cypress.on('uncaught:exception', (err, runnable) => { + return false; +}); + declare global { namespace Cypress { interface Chainable { xpath(xpathSelector: string): Chainable; getItemMenu(textoItem: string): Chainable; verificaMensagemInicial(): Chainable; - visitarToolsQA(): Chainable; + visitarToolsQA(partialURL: string): Chainable; + validateColors(tipo: ResponseType, locator: string): Chainable; + /** + * @description Verifica se a URL da página atual é exatamente igual a URL base + URL parcial passada como parâmetro + * @param urlParcial URL parcial enviada, segue o padrão '/url-desejada' + * @example cy.verificaURL('/url-desejada/x') + */ + verificaUrl(partialURL: string): Chainable; + validateOldUserForm(userData: Array, exist: boolean): Chainable; } } }