├── .eslintrc.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── cypress.config.js ├── cypress.env.json ├── cypress ├── e2e │ ├── home.cy.js │ ├── listShopping.cy.js │ ├── login.cy.js │ ├── product.cy.js │ ├── report.cy.js │ ├── user.cy.js │ └── userAdm.cy.js ├── fixtures │ └── cy.png ├── plugins │ └── index.js └── support │ ├── apiCommands.js │ ├── commands.js │ └── e2e.js ├── package.json └── reporter-config.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: [ 7 | 'airbnb-base', 8 | 'plugin:cypress/recommended', 9 | ], 10 | parserOptions: { 11 | ecmaVersion: 12, 12 | sourceType: 'module', 13 | }, 14 | rules: { 15 | 'no-console': 'off', 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: main 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | #schedule: 9 | # - cron: '35 16 * * 2' 10 | 11 | jobs: 12 | ci: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: Use Node.js 20 | uses: actions/setup-node@v2 21 | with: 22 | node-version: 14.x 23 | - run: npm install 24 | - run: npx cypress run --env grepTags=smoke 25 | - run: npm run cy:run 26 | continue-on-error: true 27 | - run: npm run report:merge 28 | - run: npm run report:mocha 29 | 30 | - name: Deploy to GitHub Pages 31 | uses: JamesIves/github-pages-deploy-action@4.1.7 32 | with: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | BRANCH: gh-pages 35 | FOLDER: mochawesome-report 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node 2 | # Edit at https://www.gitignore.io/?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional REPL history 61 | .node_repl_history 62 | 63 | # Output of 'npm pack' 64 | *.tgz 65 | 66 | # Yarn Integrity file 67 | .yarn-integrity 68 | 69 | # dotenv environment variables file 70 | .env 71 | .env.test 72 | 73 | # parcel-bundler cache (https://parceljs.org/) 74 | .cache 75 | 76 | # next.js build output 77 | .next 78 | 79 | # nuxt.js build output 80 | .nuxt 81 | 82 | # react / gatsby 83 | public/ 84 | 85 | # vuepress build output 86 | .vuepress/dist 87 | 88 | # Serverless directories 89 | .serverless/ 90 | 91 | # FuseBox cache 92 | .fusebox/ 93 | 94 | # DynamoDB Local files 95 | .dynamodb/ 96 | 97 | #Visual Studio Code 98 | .vscode 99 | 100 | #Cypress 101 | cypress/screenshots 102 | cypress/videos 103 | mochawesome-report 104 | index.json 105 | package-lock.json 106 | .DS_Store 107 | 108 | # End of https://www.gitignore.io/api/node -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Misael Reis 4 | 5 | A permissão é concedida, gratuitamente, a qualquer pessoa que obtenha uma cópia 6 | deste software e arquivos de documentação associados (o "Software"), para lidar 7 | no Software sem restrição, incluindo, sem limitação, os direitos 8 | para usar, copiar, modificar, mesclar, publicar, distribuir, sublicenciar e / ou vender 9 | cópias do Software, e para permitir que as pessoas a quem o Software é 10 | fornecido para fazê-lo, sujeito às seguintes condições: 11 | 12 | O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todos 13 | cópias ou partes substanciais do Software. 14 | 15 | O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU 16 | IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, 17 | ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA E NÃO VIOLAÇÃO. EM NENHUMA HIPÓTESE O 18 | AUTORES OU TITULARES DE DIREITOS AUTORAIS SÃO RESPONSÁVEIS POR QUALQUER RECLAMAÇÃO, DANOS OU OUTROS 19 | RESPONSABILIDADE, SEJA EM AÇÃO DE CONTRATO, DELITO OU DE OUTRA FORMA, DECORRENTE DE, 20 | FORA DE OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO 21 | PROGRAMAS. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## __Apresentação__ ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/Misaelreis/test-e2e-serverest/main) [![Badge ServeRest](https://img.shields.io/badge/API-ServeRest-green)](https://github.com/ServeRest/ServeRest/) 2 | Teste e2e da aplicação [serverest](https://front.serverest.dev/) 3 | 4 | [Relatório de execução](https://misaelreis.github.io/test-e2e-serverest/) 5 | ## __Requisitos__ 6 | 1. [Node](https://nodejs.org/pt-br/) 7 | 2. Chrome 8 | 9 | ## __Instalando Dependências__ 10 | 1. Rodar o comando 11 | ``` 12 | npm install 13 | ``` 14 | 2. Para abrir o Cypress Application use o comando 15 | ``` 16 | npm run cy:open 17 | ```` 18 | 19 | 3. Para rodar o Cypress Headless use o comando 20 | ``` 21 | npm run cy:run 22 | ```` 23 | -------------------------------------------------------------------------------- /cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('cypress') 2 | 3 | module.exports = defineConfig({ 4 | watchForFileChanges: false, 5 | defaultCommandTimeout: 20000, 6 | reporter: 'cypress-multi-reporters', 7 | reporterOptions: { 8 | configFile: 'reporter-config.json', 9 | }, 10 | e2e: { 11 | // We've imported your old cypress plugins here. 12 | // You may want to clean this up later by importing these. 13 | setupNodeEvents(on, config) { 14 | return require('./cypress/plugins/index.js')(on, config) 15 | }, 16 | baseUrl: 'https://front.serverest.dev/', 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /cypress.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "admUser": "misael@gmail.com.br", 3 | "user": "misael@gmail.com", 4 | "password": "teste" 5 | } 6 | -------------------------------------------------------------------------------- /cypress/e2e/home.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | const baseUrl = Cypress.config('baseUrl'); 3 | 4 | describe('Testes Home - Adm', () => { 5 | beforeEach(() => { 6 | cy.createLoginAdm(); 7 | cy.visit('admin/home'); 8 | }); 9 | 10 | it('valida home - Adm', { tags: 'smoke' }, () => { 11 | cy.get('.imagem').should('be.visible'); 12 | }); 13 | 14 | it('Cadastrar usuário - btn', () => { 15 | cy.get('[data-testid=cadastrarUsuarios]').click(); 16 | cy.url().should('be.equal', `${baseUrl}admin/cadastrarusuarios`); 17 | }); 18 | 19 | it('Cadastrar usuário - btn menu', () => { 20 | cy.get('[data-testid=cadastrar-usuarios]').click(); 21 | cy.url().should('be.equal', `${baseUrl}admin/cadastrarusuarios`); 22 | }); 23 | 24 | it('Listar usuário - btn', () => { 25 | cy.get('[data-testid=listarUsuarios]').click(); 26 | cy.url().should('be.equal', `${baseUrl}admin/listarusuarios`); 27 | }); 28 | 29 | it('Listar usuário - btn menu', () => { 30 | cy.get('[data-testid=listar-usuarios]').click(); 31 | cy.url().should('be.equal', `${baseUrl}admin/listarusuarios`); 32 | }); 33 | 34 | it('Cadastrar produto - btn', () => { 35 | cy.get('[data-testid=cadastrarProdutos]').click(); 36 | cy.url().should('be.equal', `${baseUrl}admin/cadastrarprodutos`); 37 | }); 38 | 39 | it('Cadastrar produto - btn menu', () => { 40 | cy.get('[data-testid=cadastrar-produtos]').click(); 41 | cy.url().should('be.equal', `${baseUrl}admin/cadastrarprodutos`); 42 | }); 43 | 44 | it('Listar produto - btn', () => { 45 | cy.get('[data-testid=listarProdutos]').click(); 46 | cy.url().should('be.equal', `${baseUrl}admin/listarprodutos`); 47 | }); 48 | 49 | it('Listar produto - btn menu', () => { 50 | cy.get('[data-testid=listar-produtos]').click(); 51 | cy.url().should('be.equal', `${baseUrl}admin/listarprodutos`); 52 | }); 53 | 54 | it('Listar relatório - btn', () => { 55 | cy.get('[data-testid=relatorios]').click(); 56 | cy.url().should('be.equal', `${baseUrl}admin/relatorios`); 57 | }); 58 | 59 | it('Listar produto - btn menu', () => { 60 | cy.get('[data-testid=link-relatorios]').click(); 61 | cy.url().should('be.equal', `${baseUrl}admin/relatorios`); 62 | }); 63 | 64 | it('Valida texto', () => { 65 | cy.get('.lead').should('have.text', 'Este é seu sistema para administrar seu ecommerce.'); 66 | }); 67 | 68 | it('Home', () => { 69 | cy.get('[data-testid=link-relatorios]').click(); 70 | cy.get('[data-testid=home]').click(); 71 | cy.url().should('be.equal', `${baseUrl}admin/home`); 72 | }); 73 | 74 | it('Logout', () => { 75 | cy.get('[data-testid=logout]').click(); 76 | cy.url().should('be.equal', `${baseUrl}login`); 77 | }); 78 | }); 79 | 80 | describe('Testes Home - User', () => { 81 | beforeEach(() => { 82 | cy.createLoginUser(); 83 | cy.visit('home'); 84 | }); 85 | 86 | it('valida home user', { tags: 'smoke' }, () => { 87 | cy.url().should('be.equal', `${baseUrl}home`); 88 | cy.get('#navbarTogglerDemo01 > .imagem').should('be.visible'); 89 | }); 90 | 91 | it('Listar carrinho', () => { 92 | cy.get('[data-testid=carrinho]').click(); 93 | cy.url().should('be.equal', `${baseUrl}carrinho`); 94 | }); 95 | 96 | it('Home', () => { 97 | cy.get('[data-testid=carrinho]').should('be.visible'); 98 | cy.get('[data-testid=home]').click(); 99 | cy.url().should('be.equal', `${baseUrl}home`); 100 | }); 101 | 102 | it('Lista de compra', () => { 103 | cy.get('[data-testid=lista-de-compras]').click(); 104 | cy.url().should('be.equal', `${baseUrl}minhaListaDeProdutos`); 105 | }); 106 | 107 | it('Logout', () => { 108 | cy.get('[data-testid=logout]').click(); 109 | cy.url().should('be.equal', `${baseUrl}login`); 110 | }); 111 | 112 | it('Pesquisando produtos', () => { 113 | cy.createProduct(); 114 | cy.get('[data-testid=pesquisar]').type('Teste Zael Uai'); 115 | cy.get('[data-testid=botaoPesquisar]').click(); 116 | cy.get('.card').should('be.visible'); 117 | }); 118 | 119 | it('Pesquisando produto inexistente', () => { 120 | cy.get('[data-testid=pesquisar]').type('ok obrigado'); 121 | cy.get('[data-testid=botaoPesquisar]').click(); 122 | cy.contains('.espacamento > .col-12 > .row', 'Nenhum produto foi encontrado').should('be.visible'); 123 | }); 124 | }); 125 | -------------------------------------------------------------------------------- /cypress/e2e/listShopping.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | const baseUrl = Cypress.config('baseUrl'); 3 | const btnCarSelecto = '.card-link'; 4 | 5 | describe('Testes - Acessar lista de compra', () => { 6 | beforeEach(() => { 7 | cy.createLoginUser(); 8 | cy.visit('minhaListaDeProdutos'); 9 | }); 10 | 11 | it('Valida lista de compra', () => { 12 | cy.contains('h1', 'Lista de Compras').should('be.visible'); 13 | cy.get('[data-testid=shopping-cart-empty-message]').should('have.text', 14 | 'Seu carrinho está vazio'); 15 | }); 16 | 17 | it('Voltar para a home', () => { 18 | cy.get('[data-testid=paginaInicial]').click(); 19 | cy.url().should('be.equal', `${baseUrl}home`); 20 | }); 21 | }); 22 | 23 | describe('Testes - Acessar lista de compra com produto', () => { 24 | beforeEach(() => { 25 | cy.createProduct(); 26 | cy.createLoginUser(); 27 | cy.visit('home'); 28 | cy.get('[data-testid=pesquisar]').type('Teste Zael Uai'); 29 | cy.get('[data-testid=botaoPesquisar]').click(); 30 | }); 31 | 32 | it('Valida detalhes produto - voltar', { tags: 'smoke' }, () => { 33 | cy.get(btnCarSelecto).click(); 34 | cy.contains('h1', 'Detalhes do produto').should('be.visible'); 35 | cy.get('[data-testid=product-detail-name]').should('have.text', 'Teste Zael Uai'); 36 | cy.get('[data-testid=voltarHome]').click(); 37 | cy.url().should('be.equal', `${baseUrl}home`); 38 | }); 39 | 40 | it('Valida detalhes produto - adicionar lista', { tags: 'smoke' }, () => { 41 | cy.get(btnCarSelecto).click(); 42 | cy.contains('h1', 'Detalhes do produto').should('be.visible'); 43 | cy.get('[data-testid=product-detail-name]').should('have.text', 'Teste Zael Uai'); 44 | cy.get('[data-testid=adicionarNaLista]').click(); 45 | cy.url().should('be.equal', `${baseUrl}minhaListaDeProdutos`); 46 | cy.get('[data-testid=limparLista]').click(); 47 | cy.contains('[data-testid=shopping-cart-empty-message]', 'Seu carrinho está vazio').should('be.visible'); 48 | }); 49 | 50 | it('Valida detalhes produto - adicionar lista e carrinho', () => { 51 | cy.get(btnCarSelecto).click(); 52 | cy.contains('h1', 'Detalhes do produto').should('be.visible'); 53 | cy.get('[data-testid=product-detail-name]').should('have.text', 'Teste Zael Uai'); 54 | cy.get('[data-testid=adicionarNaLista]').click(); 55 | cy.get('[data-testid="adicionar carrinho"]').click(); 56 | cy.contains('h1', 'Em construção aguarde').should('be.visible'); 57 | }); 58 | 59 | it('Valida detalhes produto - Adicionar produtos', () => { 60 | cy.get(btnCarSelecto).click(); 61 | cy.contains('h1', 'Detalhes do produto').should('be.visible'); 62 | cy.get('[data-testid=product-detail-name]').should('have.text', 'Teste Zael Uai'); 63 | cy.get('[data-testid=adicionarNaLista]').click(); 64 | cy.get('[data-testid=product-increase-quantity]').click(); 65 | cy.get('.row > :nth-child(3)').should('have.text', 2); 66 | }); 67 | 68 | it('Valida detalhes produto - Remover produtos', { tags: 'smoke' }, () => { 69 | cy.get(btnCarSelecto).click(); 70 | cy.contains('h1', 'Detalhes do produto').should('be.visible'); 71 | cy.get('[data-testid=product-detail-name]').should('have.text', 'Teste Zael Uai'); 72 | cy.get('[data-testid=adicionarNaLista]').click(); 73 | cy.get('[data-testid=product-increase-quantity]').click(); 74 | cy.get('.row > :nth-child(3)').should('have.text', 2); 75 | cy.get('[data-testid=product-decrease-quantity]').click(); 76 | cy.get('.row > :nth-child(3)').should('have.text', 1); 77 | }); 78 | 79 | it('Valida detalhes produto - Adicionar Lista', () => { 80 | cy.get('[data-testid=adicionarNaLista]').click(); 81 | cy.url().should('be.equal', `${baseUrl}minhaListaDeProdutos`); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /cypress/e2e/login.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | const baseUrl = Cypress.config('baseUrl'); 3 | const alertSelector = '.alert'; 4 | const passwordSelector = '[data-testid=senha]'; 5 | const emailSelector = '[data-testid=email]'; 6 | const btnLoginSelector = '[data-testid=entrar]'; 7 | 8 | describe('Testes de Login', () => { 9 | beforeEach(() => { 10 | cy.visit(''); 11 | }); 12 | 13 | it('valida página de login', () => { 14 | cy.url().should('be.equal', `${baseUrl}login`); 15 | }); 16 | 17 | it('valida login adm sucesso', { tags: 'smoke' }, () => { 18 | cy.login(Cypress.env('admUser'), Cypress.env('password')); 19 | cy.url().should('be.equal', `${baseUrl}admin/home`); 20 | }); 21 | 22 | it('valida login user sucesso', { tags: 'smoke' }, () => { 23 | cy.login(Cypress.env('user'), Cypress.env('password')); 24 | cy.url().should('be.equal', `${baseUrl}home`); 25 | }); 26 | 27 | it('valida email incorreto', () => { 28 | cy.login('misael@qc.com.br', Cypress.env('password')); 29 | cy.contains(alertSelector, 'Email e/ou senha inválidos').should('be.visible'); 30 | }); 31 | 32 | it('valida senha incorreta', () => { 33 | cy.login(Cypress.env('user'), 'testing'); 34 | cy.contains(alertSelector, 'Email e/ou senha inválidos').should('be.visible'); 35 | }); 36 | 37 | it('valida logout sucesso', { tags: 'smoke' }, () => { 38 | cy.login(Cypress.env('user'), Cypress.env('password')); 39 | cy.get('[data-testid=logout]').click(); 40 | cy.url().should('be.equal', `${baseUrl}login`); 41 | }); 42 | 43 | it('valida login sem senha', () => { 44 | cy.get(emailSelector).type(Cypress.env('user')); 45 | cy.get(btnLoginSelector).click(); 46 | cy.contains(alertSelector, 'Password é obrigatório').should('be.visible'); 47 | }); 48 | 49 | it('valida email invalido', () => { 50 | cy.login('m@m', Cypress.env('password')); 51 | cy.contains(alertSelector, 'Email deve ser um email válido').should('be.visible'); 52 | }); 53 | 54 | it('valida login sem email', () => { 55 | cy.get(passwordSelector).type(Cypress.env('password')); 56 | cy.get(btnLoginSelector).click(); 57 | cy.contains(alertSelector, 'Email é obrigatório').should('be.visible'); 58 | }); 59 | 60 | it('valida login sem email e senha', () => { 61 | cy.get(btnLoginSelector).click(); 62 | cy.contains(alertSelector, 'Email é obrigatório').should('be.visible'); 63 | cy.contains(alertSelector, 'Password é obrigatório').should('be.visible'); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /cypress/e2e/product.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const faker = require('faker'); 4 | 5 | const baseUrl = Cypress.config('baseUrl'); 6 | const imageSelector = '[data-testid=imagem]'; 7 | const nameSelector = '[data-testid=nome]'; 8 | const descriptionSelector = '[data-testid=descricao]'; 9 | const priceSelector = '[data-testid=preco]'; 10 | const alertSelector = '.alert'; 11 | const quantitySelector = '[data-testid=quantity]'; 12 | const btnCreateSelector = '[data-testid=cadastarProdutos]'; 13 | 14 | describe('Testes - Cadastro de produtos', () => { 15 | const prod = { 16 | nome: faker.name.firstName(), 17 | preco: 10, 18 | descricao: faker.internet.email(), 19 | quantidade: 10, 20 | }; 21 | 22 | beforeEach(() => { 23 | cy.createLoginAdm(); 24 | cy.visit('admin/cadastrarprodutos'); 25 | }); 26 | 27 | it('valida página de cadastro', () => { 28 | cy.contains('h1', 'Cadastro de Produtos').should('be.visible'); 29 | }); 30 | 31 | it('Cadastrar produto com sucesso', { tags: 'smoke' }, () => { 32 | cy.get(imageSelector).attachFile('cy.png'); 33 | cy.get(nameSelector).type(prod.nome); 34 | cy.get(descriptionSelector).type(prod.descricao); 35 | cy.get(priceSelector).type(prod.preco); 36 | cy.get(quantitySelector).type(prod.quantidade); 37 | cy.get(btnCreateSelector).click(); 38 | cy.url().should('be.equal', `${baseUrl}admin/listarprodutos`); 39 | }); 40 | 41 | it('Cadastrar produto sem nome', () => { 42 | cy.get(descriptionSelector).type(prod.descricao); 43 | cy.get(priceSelector).type(prod.preco); 44 | cy.get(quantitySelector).type(prod.quantidade); 45 | cy.get(btnCreateSelector).click(); 46 | cy.contains(alertSelector, 'Nome é obrigatório').should('be.visible'); 47 | }); 48 | 49 | it('Cadastrar produto sem descrição', () => { 50 | cy.get(nameSelector).type(prod.nome); 51 | cy.get(priceSelector).type(prod.preco); 52 | cy.get(quantitySelector).type(prod.quantidade); 53 | cy.get(btnCreateSelector).click(); 54 | cy.contains(alertSelector, 'Descricao é obrigatório').should('be.visible'); 55 | }); 56 | 57 | it('Cadastrar produto sem preço', () => { 58 | cy.get(imageSelector).attachFile('cy.png'); 59 | cy.get(nameSelector).type(prod.nome); 60 | cy.get(descriptionSelector).type(prod.descricao); 61 | cy.get(quantitySelector).type(prod.quantidade); 62 | cy.get(btnCreateSelector).click(); 63 | cy.contains(alertSelector, 'Preco é obrigatório').should('be.visible'); 64 | }); 65 | 66 | it('Cadastrar produto tipo de preço incorreto', () => { 67 | cy.get(imageSelector).attachFile('cy.png'); 68 | cy.get(nameSelector).type(prod.nome); 69 | cy.get(descriptionSelector).type(prod.descricao); 70 | cy.get(priceSelector).type('a'); 71 | cy.get(quantitySelector).type(prod.quantidade); 72 | cy.get(btnCreateSelector).click(); 73 | cy.contains(alertSelector, 'Preco é obrigatório').should('be.visible'); 74 | }); 75 | 76 | it('Cadastrar produto sem quantidade', () => { 77 | cy.get(imageSelector).attachFile('cy.png'); 78 | cy.get(nameSelector).type(prod.nome); 79 | cy.get(descriptionSelector).type(prod.descricao); 80 | cy.get(priceSelector).type(prod.preco); 81 | cy.get(btnCreateSelector).click(); 82 | cy.contains(alertSelector, 'Quantidade é obrigatório').should('be.visible'); 83 | }); 84 | 85 | it('Cadastrar produtos - campos obrigatórios', () => { 86 | cy.get(btnCreateSelector).click(); 87 | cy.contains(alertSelector, 'Preco é obrigatório').should('be.visible'); 88 | cy.contains(alertSelector, 'Quantidade é obrigatório').should('be.visible'); 89 | cy.contains(alertSelector, 'Nome é obrigatório').should('be.visible'); 90 | cy.contains(alertSelector, 'Descricao é obrigatório').should('be.visible'); 91 | }); 92 | }); 93 | 94 | describe('Testes - Excluir produtos', () => { 95 | beforeEach(() => { 96 | cy.createLoginAdm(); 97 | cy.visit('admin/listarprodutos'); 98 | }); 99 | 100 | it('valida página de listagem', () => { 101 | cy.contains('h1', 'Lista dos Produtos').should('be.visible'); 102 | }); 103 | 104 | it('excluir produto', () => { 105 | cy.get(':nth-child(1) > :nth-child(6) > .row > .btn-danger').click(); 106 | }); 107 | 108 | describe('Testes - Editar produtos', () => { 109 | // funcionalidade não desenvolvida ainda 110 | beforeEach(() => { 111 | cy.createLoginAdm(); 112 | cy.visit('admin/listarprodutos'); 113 | }); 114 | }); 115 | }); 116 | -------------------------------------------------------------------------------- /cypress/e2e/report.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | const baseUrl = Cypress.config('baseUrl'); 3 | 4 | describe('Testes - relatório', () => { 5 | beforeEach(() => { 6 | cy.createLoginAdm(); 7 | cy.visit('admin/relatorios'); 8 | }); 9 | 10 | it('valida página de cadastro', () => { 11 | cy.url().should('be.equal', `${baseUrl}admin/relatorios`); 12 | cy.contains('h1', 'Em construção aguarde').should('be.visible'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /cypress/e2e/user.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const faker = require('faker'); 4 | 5 | const baseUrl = Cypress.config('baseUrl'); 6 | const alertSelector = '.alert'; 7 | const passwordSelector = '[data-testid=password]'; 8 | const nameSelector = '[data-testid=nome]'; 9 | const emailSelector = '[data-testid=email]'; 10 | const btnCreateSelector = '[data-testid=cadastrar]'; 11 | 12 | describe('Testes - Cadastro de usuário', () => { 13 | const user = { 14 | name: faker.name.firstName(), 15 | email: faker.internet.email(), 16 | password: 'teste', 17 | }; 18 | 19 | beforeEach(() => { 20 | cy.visit('cadastrarusuarios'); 21 | }); 22 | 23 | it('valida cadastro usuário adm sucesso', { tags: 'smoke' }, () => { 24 | user.email = faker.internet.email(); 25 | cy.createUserAdm(user.name, user.email, user.password); 26 | cy.contains(alertSelector, 'Cadastro realizado com sucesso').should('be.visible'); 27 | cy.url().should('be.equal', `${baseUrl}admin/home`); 28 | }); 29 | 30 | it('valida cadastro usuário sucesso', { tags: 'smoke' }, () => { 31 | user.email = faker.internet.email(); 32 | cy.createUser(user.name, user.email, user.password); 33 | cy.contains(alertSelector, 'Cadastro realizado com sucesso').should('be.visible'); 34 | cy.url().should('be.equal', `${baseUrl}home`); 35 | }); 36 | 37 | it('valida cadastro sem senha', () => { 38 | cy.get(nameSelector).type(user.name); 39 | cy.get(emailSelector).type(user.email); 40 | cy.get(btnCreateSelector).click(); 41 | cy.contains(alertSelector, 'Password é obrigatório').should('be.visible'); 42 | }); 43 | 44 | it('valida email invalido', () => { 45 | cy.get(nameSelector).type('Maria'); 46 | cy.get(emailSelector).type('m@m'); 47 | cy.get(passwordSelector).type('teste'); 48 | cy.get(btnCreateSelector).click(); 49 | cy.contains(alertSelector, 'Email deve ser um email válido').should('be.visible'); 50 | }); 51 | 52 | it('valida cadastro sem email', () => { 53 | cy.get(nameSelector).type('Maria'); 54 | cy.get(passwordSelector).type('teste'); 55 | cy.get(btnCreateSelector).click(); 56 | cy.contains(alertSelector, 'Email é obrigatório').should('be.visible'); 57 | }); 58 | 59 | it('valida sem nome', () => { 60 | cy.get(emailSelector).type('misael@email.com'); 61 | cy.get(passwordSelector).type('teste'); 62 | cy.get(btnCreateSelector).click(); 63 | cy.contains(alertSelector, 'Nome é obrigatório').should('be.visible'); 64 | }); 65 | 66 | it('valida cadastro sem email, senha e nome', () => { 67 | cy.get(btnCreateSelector).click(); 68 | cy.contains(alertSelector, 'Email é obrigatório').should('be.visible'); 69 | cy.contains(alertSelector, 'Password é obrigatório').should('be.visible'); 70 | cy.contains(alertSelector, 'Nome é obrigatório').should('be.visible'); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /cypress/e2e/userAdm.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const faker = require('faker'); 4 | 5 | const baseUrl = Cypress.config('baseUrl'); 6 | const alertSelector = '.alert'; 7 | const passwordSelector = '[data-testid=password]'; 8 | const nameSelector = '[data-testid=nome]'; 9 | const emailSelector = '[data-testid=email]'; 10 | const btnCreateSelector = '[data-testid=cadastrarUsuario]'; 11 | 12 | describe('Testes - Cadastro de usuário Adm', () => { 13 | // Não tem mensagem de sucesso 14 | const user = { 15 | name: faker.name.firstName(), 16 | email: faker.internet.email(), 17 | password: 'teste', 18 | }; 19 | 20 | beforeEach(() => { 21 | cy.createLoginAdm(); 22 | cy.visit('admin/cadastrarusuarios'); 23 | }); 24 | 25 | it('valida cadastro usuário adm sucesso', { tags: 'smoke' }, () => { 26 | user.email = faker.internet.email(); 27 | cy.createUserAdminAdm(user.name, user.email, user.password); 28 | cy.url().should('be.equal', `${baseUrl}admin/listarusuarios`); 29 | }); 30 | 31 | it('valida cadastro usuário sucesso', { tags: 'smoke' }, () => { 32 | user.email = faker.internet.email(); 33 | cy.createAdminUser(user.name, user.email, user.password); 34 | cy.url().should('be.equal', `${baseUrl}admin/listarusuarios`); 35 | }); 36 | 37 | it('valida cadastro sem senha', () => { 38 | cy.get(nameSelector).type(user.name); 39 | cy.get(emailSelector).type(user.email); 40 | cy.get(btnCreateSelector).click(); 41 | cy.contains(alertSelector, 'Password é obrigatório').should('be.visible'); 42 | }); 43 | 44 | it('valida email invalido', () => { 45 | cy.get(nameSelector).type(user.name); 46 | cy.get(emailSelector).type('m@m'); 47 | cy.get(passwordSelector).type('teste'); 48 | cy.get(btnCreateSelector).click(); 49 | cy.contains(alertSelector, 'Email deve ser um email válido').should('be.visible'); 50 | }); 51 | 52 | it('valida cadastro sem email', () => { 53 | cy.get(nameSelector).type(user.name); 54 | cy.get(passwordSelector).type('teste'); 55 | cy.get(btnCreateSelector).click(); 56 | cy.contains(alertSelector, 'Email é obrigatório').should('be.visible'); 57 | }); 58 | 59 | it('valida sem nome', () => { 60 | cy.get(emailSelector).type('misael@mailer.com'); 61 | cy.get(passwordSelector).type('teste'); 62 | cy.get(btnCreateSelector).click(); 63 | cy.contains(alertSelector, 'Nome é obrigatório').should('be.visible'); 64 | }); 65 | 66 | it('valida cadastro sem email, senha e nome', () => { 67 | cy.get(btnCreateSelector).click(); 68 | cy.contains(alertSelector, 'Email é obrigatório').should('be.visible'); 69 | cy.contains(alertSelector, 'Nome é obrigatório').should('be.visible'); 70 | cy.contains(alertSelector, 'Password é obrigatório').should('be.visible'); 71 | }); 72 | }); 73 | 74 | describe('Testes - Listar usuários Adm', () => { 75 | beforeEach(() => { 76 | cy.createLoginAdm(); 77 | cy.visit('admin/listarusuarios'); 78 | }); 79 | 80 | it('valida página - listagem de usuários', () => { 81 | cy.contains('h1', 'Lista dos usuários').should('be.visible'); 82 | cy.contains('thead > tr > :nth-child(1)', 'Nome').should('be.visible'); 83 | cy.contains('thead > tr > :nth-child(2)', 'Email').should('be.visible'); 84 | cy.contains('thead > tr > :nth-child(3)', 'Senha').should('be.visible'); 85 | cy.contains('thead > tr > :nth-child(4)', 'Administrador').should('be.visible'); 86 | cy.contains('thead > tr > :nth-child(5)', 'Ações').should('be.visible'); 87 | cy.get(':nth-child(1) > :nth-child(5) > .row > .btn-info').should('be.visible'); 88 | cy.get(':nth-child(4) > :nth-child(5) > .row > .btn-danger').should('be.visible'); 89 | }); 90 | }); 91 | 92 | describe('Testes - Editar usuários', () => { 93 | // Feature não desenvolvida ainda 94 | }); 95 | 96 | describe('Testes - Listar usuários Adm', () => { 97 | beforeEach(() => { 98 | cy.createLoginAdm(); 99 | cy.visit('admin/listarusuarios'); 100 | }); 101 | 102 | it('Teste excluir primeiro usuário', () => { 103 | cy.get(':nth-child(4) > :nth-child(5) > .row > .btn-danger').click(); 104 | cy.url().should('be.equal', `${baseUrl}admin/listarusuarios`); 105 | // não tem mensagem de exclusão de usuário 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /cypress/fixtures/cy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/misaelreis/test-e2e-serverest/c1e7ce77c6dcca3ab2491046d7c17855e9c4a675/cypress/fixtures/cy.png -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | /* eslint-disable global-require */ 3 | module.exports = (on, config) => { 4 | require('cypress-grep/src/plugin')(config); 5 | }; 6 | -------------------------------------------------------------------------------- /cypress/support/apiCommands.js: -------------------------------------------------------------------------------- 1 | Cypress.Commands.add('createUserFix', () => { 2 | cy.request({ 3 | method: 'POST', 4 | failOnStatusCode: false, 5 | Headers: { accept: '/' }, 6 | url: 'https://serverest.dev/usuarios', 7 | body: { 8 | nome: 'Misael Adm', 9 | email: Cypress.env('admUser'), 10 | password: Cypress.env('password'), 11 | administrador: 'true', 12 | }, 13 | }); 14 | 15 | cy.request({ 16 | method: 'POST', 17 | failOnStatusCode: false, 18 | Headers: { accept: '/' }, 19 | url: 'https://serverest.dev/usuarios', 20 | body: { 21 | nome: 'Misael Usuario', 22 | email: Cypress.env('user'), 23 | password: Cypress.env('password'), 24 | administrador: 'false', 25 | }, 26 | }); 27 | }); 28 | 29 | Cypress.Commands.add('createLoginAdm', () => { 30 | cy.createUserFix(); 31 | cy.request({ 32 | method: 'POST', 33 | Headers: { accept: '/' }, 34 | url: 'https://serverest.dev/login', 35 | body: { 36 | email: Cypress.env('admUser'), 37 | password: Cypress.env('password'), 38 | }, 39 | }).then(({ body }) => { 40 | window.localStorage.setItem('serverest/userNome', 'Misael Adm'); 41 | window.localStorage.setItem('serverest/userEmail', Cypress.env('admUser')); 42 | window.localStorage.setItem('serverest/userToken', (body.authorization)); 43 | }); 44 | }); 45 | 46 | Cypress.Commands.add('createLoginUser', () => { 47 | cy.createUserFix(); 48 | cy.request({ 49 | method: 'POST', 50 | Headers: { accept: '/' }, 51 | url: 'https://serverest.dev/login', 52 | body: { 53 | email: Cypress.env('user'), 54 | password: Cypress.env('password'), 55 | }, 56 | }).then(({ body }) => { 57 | window.localStorage.setItem('serverest/userNome', 'Misael Usuario'); 58 | window.localStorage.setItem('serverest/userEmail', Cypress.env('user')); 59 | window.localStorage.setItem('serverest/userToken', (body.authorization)); 60 | }); 61 | }); 62 | 63 | Cypress.Commands.add('createProduct', () => { 64 | cy.createLoginAdm().then(({ body }) => { 65 | cy.request({ 66 | failOnStatusCode: false, 67 | method: 'POST', 68 | headers: { Authorization: body.authorization }, 69 | url: 'https://serverest.dev/produtos', 70 | body: { 71 | nome: 'Teste Zael Uai', 72 | preco: 470, 73 | descricao: 'Mouse', 74 | quantidade: 381, 75 | }, 76 | }); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | /// 2 | import 'cypress-file-upload'; 3 | 4 | Cypress.Commands.add('login', (user, password) => { 5 | cy.createUserFix(); 6 | cy.get('[data-testid=email]').type(user); 7 | cy.get('[data-testid=senha]').type(password, { log: false }); 8 | cy.get('[data-testid=entrar]').click(); 9 | }); 10 | 11 | Cypress.Commands.add('createUserAdm', (name, email, password) => { 12 | cy.get('[data-testid=nome]').type(name); 13 | cy.get('[data-testid=email]').type(email); 14 | cy.get('[data-testid=password]').type(password); 15 | cy.get('[data-testid=checkbox]').check(); 16 | cy.get('[data-testid=cadastrar]').click(); 17 | }); 18 | 19 | Cypress.Commands.add('createUser', (name, email, password) => { 20 | cy.get('[data-testid=nome]').type(name); 21 | cy.get('[data-testid=email]').type(email); 22 | cy.get('[data-testid=password]').type(password); 23 | cy.get('[data-testid=cadastrar]').click(); 24 | }); 25 | 26 | Cypress.Commands.add('createUserAdminAdm', (name, email, password) => { 27 | cy.get('[data-testid=nome]').type(name); 28 | cy.get('[data-testid=email]').type(email); 29 | cy.get('[data-testid=password]').type(password); 30 | cy.get('[data-testid=checkbox]').check(); 31 | cy.get('[data-testid=cadastrarUsuario]').click(); 32 | }); 33 | 34 | Cypress.Commands.add('createAdminUser', (name, email, password) => { 35 | cy.get('[data-testid=nome]').type(name); 36 | cy.get('[data-testid=email]').type(email); 37 | cy.get('[data-testid=password]').type(password); 38 | cy.get('[data-testid=cadastrarUsuario]').click(); 39 | }); 40 | -------------------------------------------------------------------------------- /cypress/support/e2e.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | /* eslint-disable import/extensions */ 3 | import './commands.js'; 4 | import './apiCommands.js'; 5 | 6 | require('cypress-grep')(); 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-e2e-serverest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "cy:open": "npx cypress open", 8 | "cy:run": "npx cypress run", 9 | "report:merge": "mochawesome-merge > index.json", 10 | "report:mocha": "marge index.json", 11 | "report:cleam": "rimraf mochawesome-report index.js" 12 | }, 13 | "keywords": [], 14 | "author": "Misael Reis", 15 | "license": "ISC", 16 | "dependencies": { 17 | "faker": "5.5.3" 18 | }, 19 | "devDependencies": { 20 | "cypress": "^10.1.0", 21 | "cypress-file-upload": "^5.0.8", 22 | "cypress-grep": "^2.5.3", 23 | "cypress-multi-reporters": "^1.5.0", 24 | "eslint": "^7.32.0", 25 | "eslint-config-airbnb-base": "^14.2.1", 26 | "eslint-plugin-cypress": "^2.12.1", 27 | "eslint-plugin-import": "^2.24.2", 28 | "mochawesome": "^7.0.1", 29 | "mochawesome-merge": "^4.2.1", 30 | "mochawesome-report-generator": "^6.0.1", 31 | "rimraf": "^3.0.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /reporter-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "reporterEnabled": "mochawesome", 3 | "mochawesomeReporterOptions": { 4 | "reporterDir": "mochawesome-report", 5 | "quiet": true, 6 | "overwrite": false, 7 | "html": false, 8 | "json": true 9 | } 10 | } --------------------------------------------------------------------------------