├── .DS_Store ├── .all-contributorsrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package.json └── projetos ├── .DS_Store ├── apiTests ├── .gitignore ├── cypress.config.ts ├── cypress │ ├── e2e │ │ └── json.spec.cy.ts │ └── support │ │ ├── app.ts │ │ ├── e2e.ts │ │ ├── jsonActions.ts │ │ └── models │ │ └── post.ts ├── package.json └── tsconfig.json ├── multiplosAmbientes ├── README.md ├── cypress.config.js ├── cypress │ ├── e2e │ │ └── configBaseUrl.cy.js │ ├── fixtures │ │ └── example.json │ └── support │ │ ├── commands.js │ │ └── e2e.js └── package.json └── uncaughtException ├── README.md ├── cypress.config.js ├── cypress ├── e2e │ ├── comUncaughtException.cy.js │ └── semUncaughtException.cy.js ├── fixtures │ └── example.json └── support │ ├── commands.js │ └── e2e.js └── package.json /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driuzzo/cypress-faq/bdcfcb13df5d4058c5d58eea58d060743d255894/.DS_Store -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "commitType": "docs", 8 | "commitConvention": "angular", 9 | "contributors": [ 10 | { 11 | "login": "leolpc21", 12 | "name": "Leonardo Costa", 13 | "avatar_url": "https://avatars.githubusercontent.com/u/43275999?v=4", 14 | "profile": "https://github.com/leolpc21", 15 | "contributions": [ 16 | "code" 17 | ] 18 | }, 19 | { 20 | "login": "driuzzo", 21 | "name": "Adriano Driuzzo", 22 | "avatar_url": "https://avatars.githubusercontent.com/u/16465816?v=4", 23 | "profile": "https://github.com/driuzzo", 24 | "contributions": [ 25 | "code" 26 | ] 27 | }, 28 | { 29 | "login": "JarDeVSon", 30 | "name": "Jardeson Santos", 31 | "avatar_url": "https://avatars.githubusercontent.com/u/55422665?v=4", 32 | "profile": "https://www.linkedin.com/services/page/68082b316777464a2a/", 33 | "contributions": [ 34 | "code" 35 | ] 36 | }, 37 | { 38 | "login": "GiovaniRSantos", 39 | "name": "Giovani S Rodrigues", 40 | "avatar_url": "https://avatars.githubusercontent.com/u/71795768?v=4", 41 | "profile": "https://github.com/GiovaniRSantos", 42 | "contributions": [ 43 | "code" 44 | ] 45 | } 46 | ], 47 | "contributorsPerLine": 7, 48 | "skipCi": true, 49 | "repoType": "github", 50 | "repoHost": "https://github.com", 51 | "projectName": "cypress-faq", 52 | "projectOwner": "driuzzo" 53 | } 54 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Código de Conduta de Colaboração 3 | 4 | ## Nosso compromisso 5 | 6 | Como participantes, colaboradoras e líderes, nós nos comprometemos a fazer com que a participação em nossa comunidade seja uma experiência livre de assédio para todas as pessoas, independentemente de idade, tamanho do corpo, deficiência aparente ou não aparente, etnia, características sexuais, identidade ou expressão de gênero, nível de experiência, educação, situação sócio-econômica, nacionalidade, aparência pessoal, raça, casta, religião ou identidade e orientação sexuais. 7 | 8 | Comprometemo-nos a agir e interagir de maneiras que contribuam para uma comunidade aberta, acolhedora, diversificada, inclusiva e saudável. 9 | 10 | ## Nossos padrões 11 | 12 | Exemplos de comportamentos que contribuem para criar um ambiente positivo para a nossa comunidade incluem: 13 | 14 | * Demonstrar empatia e bondade com as outras pessoas 15 | * Respeitar opiniões, pontos de vista e experiências contrárias 16 | * Dar e receber feedbacks construtivos de maneira respeitosa 17 | * Assumir responsabilidade, pedir desculpas às pessoas afetadas por nossos erros e aprender com a experiência 18 | * Focar no que é melhor não só para nós individualmente, mas para a comunidade em geral 19 | 20 | Exemplos de comportamentos inaceitáveis incluem: 21 | 22 | * Uso de linguagem ou imagens sexualizadas, bem como o assédio sexual ou de qualquer natureza 23 | * Comentários insultuosos/depreciativos e ataques pessoais ou políticos (Trolling) 24 | * Assédio público ou privado 25 | * Publicar informações particulares de outras pessoas, como um endereço de e-mail ou endereço físico, sem a permissão explícita delas 26 | * Outras condutas que são normalmente consideradas inapropriadas em um ambiente profissional 27 | 28 | ## Aplicação das nossas responsabilidades 29 | 30 | A liderança da comunidade é responsável por esclarecer e aplicar nossos padrões de comportamento aceitáveis e tomará ações corretivas apropriadas e justas em resposta a qualquer comportamento que considerar impróprio, ameaçador, ofensivo ou problemático. 31 | 32 | A liderança da comunidade tem o direito e a responsabilidade de remover, editar ou rejeitar comentários, commits, códigos, edições na wiki, erros e outras contribuições que não estão alinhadas com este Código de Conduta e irá comunicar as razões por trás das decisões da moderação quando for apropriado. 33 | 34 | ## Escopo 35 | 36 | Este Código de Conduta se aplica dentro de todos os espaços da comunidade e também se aplica quando uma pessoa estiver representando oficialmente a comunidade em espaços públicos. Exemplos de representação da nossa comunidade incluem usar um endereço de e-mail oficial, postar em contas oficiais de mídias sociais ou atuar como uma pessoa indicada como representante em um evento online ou offline. 37 | 38 | ## Aplicação 39 | 40 | Ocorrências de comportamentos abusivos, de assédio ou que sejam inaceitáveis por qualquer outro motivo poderão ser reportadas para a liderança da comunidade, responsável pela aplicação, via contato [INSERIR MÉTODO DE CONTATO]. Todas as reclamações serão revisadas e investigadas imediatamente e de maneira justa. 41 | 42 | A liderança da comunidade tem a obrigação de respeitar a privacidade e a segurança de quem reportar qualquer incidente. 43 | 44 | ## Diretrizes de aplicação 45 | 46 | A liderança da comunidade seguirá estas Diretrizes de Impacto na Comunidade para determinar as consequências de qualquer ação que considerar violadora deste Código de Conduta: 47 | 48 | ### 1. Ação Corretiva 49 | 50 | **Impacto na comunidade**: Uso de linguagem imprópria ou outro comportamento considerado anti-profissional ou repudiado pela comunidade. 51 | 52 | **Consequência**: Aviso escrito e privado da liderança da comunidade, esclarecendo a natureza da violação e com a explicação do motivo pelo qual o comportamento era impróprio. Um pedido de desculpas público poderá ser solicitado. 53 | 54 | ### 2. Advertência 55 | 56 | **Impacto na comunidade**: Violação por meio de um incidente único ou atitudes repetidas. 57 | 58 | **Consequência**: Advertência com consequências para comportamento repetido. Não poderá haver interações com as pessoas envolvidas, incluindo interações não solicitadas com as pessoas que estiverem aplicando o Código de Conduta, por um período determinado. Isto inclui evitar interações em espaços da comunidade, bem como canais externos como as mídias sociais. A violação destes termos pode levar a um banimento temporário ou permanente. 59 | 60 | ### 3. Banimento Temporário 61 | 62 | **Impacto na comunidade**: Violação grave dos padrões da comunidade, incluindo a persistência do comportamento impróprio. 63 | 64 | **Consequência**: Banimento temporário de qualquer tipo de interação ou comunicação pública com a comunidade por um determinado período. Estarão proibidas as interações públicas ou privadas com as pessoas envolvidas, incluindo interações não solicitadas com as pessoas que estiverem aplicando o Código de Conduta. A violação destes termos pode resultar em um banimento permanente. 65 | 66 | ### 4. Banimento Permanente 67 | 68 | **Impacto na comunidade**: Demonstrar um padrão na violação das normas da comunidade, incluindo a persistência do comportamento impróprio, assédio a uma pessoa ou agressão ou depreciação a classes de pessoas. 69 | 70 | **Consequência**: Banimento permanente de qualquer tipo de interação pública dentro da comunidade. 71 | 72 | ## Atribuição 73 | 74 | Este Código de Conduta é adaptado do [Contributor Covenant][homepage], versão 2.1, disponível em [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 75 | 76 | As Diretrizes de Impacto na Comunidade foram inspiradas pela 77 | [Aplicação do código de conduta Mozilla][Mozilla CoC]. 78 | 79 | Para obter respostas a perguntas comuns sobre este código de conduta, veja a página de Perguntas Frequentes (FAQ) em [https://www.contributor-covenant.org/faq][FAQ]. Traduções estão disponíveis em [https://www.contributor-covenant.org/translations][translations]. 80 | 81 | [homepage]: https://www.contributor-covenant.org 82 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 83 | [Mozilla CoC]: https://github.com/mozilla/diversity 84 | [FAQ]: https://www.contributor-covenant.org/faq 85 | [translations]: https://www.contributor-covenant.org/translations 86 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Guia de Como Contribuir 2 | 3 | ## Para os novos contribuidores 4 | 5 | 1. Faça um fork desse repositório. 6 | 7 | 2. Clone seu fork para sua máquina: 8 | ```bash 9 | git clone https://github.com/SEU_USUARIO/cypress-faq.git 10 | ``` 11 | 3. Acesse o repositório. 12 | 13 | 4. Adicione o repositório original como upstream, usando o comando: 14 | ```bash 15 | git remote add upstream https://github.com/driuzzo/cypress-faq.git 16 | ``` 17 | 18 | 5. Crie uma nova branch com as suas alterações (altere `nome-branch` para um nome que faça sentido com o que você irá implementar): 19 | ```bash 20 | git checkout -b nome-branch 21 | ``` 22 | 23 | 6. Se você for contribuir apenas com texto no README, pule para o tópico 13. 24 | 25 | 7. Se você for adicionar códigos de exemplo para serem executados, acesse a pasta projetos e crie uma pasta com o título do assunto, por exemplo: `forceTrue`. 26 | 27 | 8. No terminal, acesse a pasta que você criou. 28 | ```bash 29 | cd projetos/suaPastaAqui 30 | ``` 31 | 32 | 9. Dentro da pasta que você criou, rode o comando abaixo para criar um arquivo package.json e siga as instruções que forem aparecendo: 33 | ```bash 34 | npm init 35 | ``` 36 | 37 | 10. Em seguida, instale o cypress na sua pasta: 38 | ```bash 39 | npm install cypress --save-dev 40 | ``` 41 | 11. Crie o arquivo de teste dentro da pasta e2e, com o mesmo nome da sua pasta. 42 | 43 | 12. Crie um arquivo README.md dentro da sua pasta e adicione o texto do assunto a ser tratado. 44 | 45 | 13. Caso sua contribuição não tenha código para ser executado, você pode adicionar o conteúdo no arquivo README.md na raiz do projeto. 46 | 47 | 14. Salve as alterações e crie uma mensagem de commit contando o que você fez: 48 | ```bash 49 | git commit -m "adicionado exemplo force true" 50 | ``` 51 | 15. Envie as suas alterações: 52 | ```bash 53 | git push origin nome-branch 54 | ``` 55 | 16. Verifique se a sua branch está atualizada com base no repositório `upstream` e submeta seu pull request! 56 | Ex: 57 | 58 | ```bash 59 | git fetch upstream 60 | git checkout main 61 | git reset --hard upstream/main 62 | git push origin main --force 63 | ``` 64 | 65 | ## Solução de problemas comuns 66 | 67 | Para atualizar a sua branch com as últimas alterações do repositório original, use: 68 | 69 | ```bash 70 | git fetch upstream 71 | git pull upstream main 72 | ``` -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Adriano Driuzzo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Cypress Brasil 🇧🇷 FAQ 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) 4 | 5 | 6 | Este documento foi criado para ajudar a solucionar os problemas mais comuns ao usar o Cypress. Se você não encontrar a resposta para sua pergunta aqui, fique à vontade para abrir uma issue e dar sua sugestão! 7 | 8 | ## Como contribuir 🤝 9 | 10 | Se você está interessado em ajudar no projeto, abra uma [issue](https://github.com/driuzzo/cypress-faq/issues) e explique qual tópico ou assunto você gostaria de adicionar. 11 | 12 | Você também pode enviar qualquer ideia/sugestão como issue. 13 | 14 | Todas as contribuições são muito bem-vindas! 15 | 16 | Leia nosso [guia de como contribuir](CONTRIBUTING.md). 17 | 18 | ## Acesse o menu rápido abaixo: 19 |
20 | 21 | Geral 22 | 23 | 24 | 25 | 26 | - [Cypress não abre após a instalação](#o-cypress-não-abre-após-a-instalação) 27 |
28 | 29 |
30 | 31 | force:true 32 | 33 | 34 | 35 | 36 | - [Evitando o uso do force:true](#evitando-o-uso-do-force-true) 37 |
38 | 39 |
40 | 41 | uncaught exception 42 | 43 | 44 | 45 | 46 | - [Lidando com uncaught exception](projetos/uncaughtException/README.md) 47 |
48 | 49 |
50 | 51 | múltiplos ambientes 52 | 53 | 54 | 55 | 56 | - [Lidando com múltiplos ambientes com Cypress](projetos/multiplosAmbientes/README.md) 57 |
58 | 59 | 60 | 61 | ## Geral 62 | ### O Cypress não abre após a instalação. 63 | 64 | Certifique-se de que você tenha a versão mínima necessária do Node.js e npm. Além disso, tente deletar a pasta `node_modules` e o arquivo `package-lock.json`, e então reinstale as dependências. Você pode deletar manualmente ou rodando o seguinte comando no terminal (lembre-se de estar na raiz do projeto): 65 | 66 | ```bash 67 | rm -rf node_modules package-lock.json 68 | npm install 69 | ``` 70 | ## Evitando o uso do force: true 71 | 72 | O `force: true` é usado quando o elemento a ser clicado está coberto ou fora de visualização. Ou seja, utilizar essa abordagem com frequência é uma má prática. Você pode usar algumas alternativas: 73 | 74 | ### Aguarde até que o elemento esteja visível: 75 | Pode ser que o elemento ainda não tenha sido renderizado na tela no momento do clique. Utilize should('be.visible') para garantir que o elemento esteja visível antes de tentar interagir com ele. 76 | 77 | ```javascript 78 | cy.get('seletor').should('be.visible').click(); 79 | ``` 80 | 81 | ### Scroll até o elemento 82 | Se o elemento não estiver no topo, você pode usar o comando `scrollIntoView` para garantir que o elemento esteja visível na janela de visualização. 83 | 84 | ```javascript 85 | cy.get('seletor').scrollIntoView().click(); 86 | ``` 87 | 88 | ### Aguarde até que o elemento não esteja oculto: 89 | Certifique-se de que o elemento não esteja oculto usando should('not.be.hidden'). 90 | 91 | ```javascript 92 | cy.get('seletor').should('not.be.hidden').click(); 93 | ``` 94 | 95 | ### Interagir com um elemento filho: 96 | Às vezes, clicar em um elemento filho pode ser mais eficaz. 97 | 98 | ```javascript 99 | cy.get('seletor').find('child-seletor').click(); 100 | ``` 101 | 102 | ### Ajustar a posição de clique: 103 | Especificar a posição do clique pode ajudar a evitar elementos sobrepostos. 104 | 105 | ```javascript 106 | cy.get('seletor').click('center'); 107 | ``` 108 | 109 | ### Verificar se há algum problema com a aplicação: 110 | Elementos sobrepostos ou fora de visualização podem indicar problemas na aplicação em si. Verifique se há algo errado no layout ou no comportamento da aplicação que possa ser corrigido. 111 | 112 | ### Usar force: true somente quando necessário: 113 | Em casos onde não é possível evitar o uso de force: true, documente bem o motivo e avalie se há melhorias que possam ser feitas no código ou no estrutura da aplicação para evitar a necessidade desse uso. 114 | 115 | ```javascript 116 | cy.get('seletor').click({ force: true }); 117 | ``` 118 | 119 | Ao seguir essas alternativas, você poderá criar testes mais robustos e evitar o uso do force: true, que pode mascarar problemas escondidos na aplicação. 120 | 121 | ___ 122 | 123 | Feito com ❤️ por Adriano Driuzzo 124 | 125 | 👋🏽 [Entre em contato!](https://www.linkedin.com/in/adriano-driuzzo/) 126 | 127 | ## Colaboradores ✨ 128 | 129 | Agradecimentos aos colaboradores: ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
Leonardo Costa
Leonardo Costa

💻
Adriano Driuzzo
Adriano Driuzzo

💻
Jardeson Santos
Jardeson Santos

💻
Giovani S Rodrigues
Giovani S Rodrigues

💻
144 | 145 | 146 | 147 | 148 | 149 | 150 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cypress-faq", 3 | "version": "1.0.0", 4 | "description": "Repositório criado para ser usado como um FAQ do framework Cypress", 5 | "main": "index.js", 6 | "scripts": { 7 | }, 8 | "author": "cypress-faq", 9 | "license": "MIT" 10 | } 11 | -------------------------------------------------------------------------------- /projetos/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driuzzo/cypress-faq/bdcfcb13df5d4058c5d58eea58d060743d255894/projetos/.DS_Store -------------------------------------------------------------------------------- /projetos/apiTests/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /package-lock.json -------------------------------------------------------------------------------- /projetos/apiTests/cypress.config.ts: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require("cypress"); 2 | 3 | 4 | module.exports = defineConfig({ 5 | viewportWidth: 1433, 6 | viewportHeight: 1366, 7 | chromeWebSecurity: false, 8 | waitForAnimations: true, 9 | reporter: "junit", 10 | requestTimeout: 60000, 11 | responsetimeout: 60000, 12 | 13 | reporterOptions: { 14 | mochaFile: "results/results-[hash].xml", 15 | toConsole: true, 16 | }, 17 | video: false, 18 | 19 | e2e: { 20 | setupNodeEvents(on, config) { 21 | 22 | } 23 | } 24 | }) 25 | 26 | -------------------------------------------------------------------------------- /projetos/apiTests/cypress/e2e/json.spec.cy.ts: -------------------------------------------------------------------------------- 1 | describe('Endpoint Json -', () => { 2 | it('Validar requisicao GET /todos no endpoint de json', () => { 3 | cy.getAllJson() 4 | }) 5 | it('Validar requisicao POST /posts no endpoint de json', () => { 6 | cy.createPost("Titulo Teste2", "Corpo do post2", 2) 7 | }) 8 | it('Atualizar post com requisicao PATCH /posts{id} no endpoint de json', () => { 9 | let postId = 1; 10 | cy.updatePost("Titulo Teste2 Editado", "Corpo do post Editado", postId) 11 | }) 12 | it('Deletar post com requisicao DELETE /posts{id} no endpoint de json', () => { 13 | cy.deletePost(1) 14 | }) 15 | }) -------------------------------------------------------------------------------- /projetos/apiTests/cypress/support/app.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare namespace Cypress { 4 | interface Chainable { 5 | /** 6 | * Faz uma requisição para o endpoint passado como parâmetro em `resource`, através da função `getEndpoint`. 7 | * A função `getEndpoint` é responsável por construir a URL completa da requisição com base no `resource` e outros parâmetros. 8 | * 9 | * @param {string} resource Parâmetro referente ao valor e "options" da função getEndpoint. 10 | * @param {string} [queryParam] Parâmetro de consulta opcional a ser adicionado à URL. 11 | * @param {Record} [headers] Headers personalizados para a requisição. 12 | * @returns {Chainable} Uma promessa que resolve para a resposta da requisição. 13 | * 14 | * @example 15 | * cy.getResource('todos').then((res) =>{ 16 | * .its('status').should('eq', 200) 17 | * }) 18 | * @description 19 | */ 20 | getResource(resource: string, queryParam?: string, headers?: Record): Chainable>; 21 | /** 22 | * Faz uma requisição POST para o endpoint especificado. 23 | * 24 | * @param {string} resource O endpoint para o qual a requisição será enviada. 25 | * @returns {Chainable} Uma promise que resolve para a resposta da requisição. 26 | 27 | * @example 28 | * cy.postResource('todos', { exemplo: "teste" }) 29 | * .its('status').should('eq', 201) 30 | */ 31 | postResource(resource: string, body: object): Chainable>; 32 | /** 33 | * Faz uma requisição uma requisição PATCH para o endpoint especificado. 34 | * 35 | * @param {string} resource O endpoint para o qual a requisição será enviada. 36 | * @param {object} body O corpo da requisição. 37 | * @param {number} [queryParam] Parâmetro de consulta opcional. 38 | * @param {object} [headers] Headers de requisição opcionais. 39 | * @returns {Chainable} Uma promise que resolve para a resposta da requisição. 40 | * 41 | * @example 42 | * cy.patchResource('users/123', { name: 'Giovani' }, 1) 43 | * .its('status').should('eq', 200) 44 | */ 45 | patchResource(resource: string, body: object, queryParam?: number, headers?: object): Chainable>; 46 | /** 47 | * Faz uma requisição uma requisição DELETE para o endpoint especificado. 48 | * 49 | * @param {string} resource O endpoint para o qual a requisição será enviada. 50 | * @param {number} [queryParam] Parâmetro de consulta opcional. 51 | * @returns {Chainable} Uma promise que resolve para a resposta da requisição. 52 | * 53 | * @example 54 | * cy.deleteResource('todos/123') 55 | * .its('status').should('eq', 204) 56 | */ 57 | deleteResource(resource: string, queryParam?: number): Chainable>; 58 | } 59 | 60 | } 61 | 62 | 63 | 64 | function getEndpoint(resource) { 65 | const baseEndpoint = Cypress.env('endpoint') 66 | 67 | let options = { 68 | todos: "/todos", 69 | posts: "/posts" 70 | } 71 | return baseEndpoint + options[resource] 72 | } 73 | 74 | Cypress.Commands.add("getResource", (resource, queryParam?: string, headers?: Object) => { 75 | const endpoint = getEndpoint(resource) 76 | let url: string 77 | url = endpoint 78 | 79 | if (queryParam) { 80 | url = endpoint + '/?' + queryParam 81 | } 82 | 83 | let requestInfo = { 84 | method: 'GET', 85 | url: url, 86 | headers 87 | } 88 | return cy.request(requestInfo) 89 | }) 90 | 91 | Cypress.Commands.add("postResource", (resource: string, body: object, headers?) => { 92 | const endpoint = getEndpoint(resource) 93 | 94 | let requestInfo = { 95 | method: 'POST', 96 | url: endpoint, 97 | body: body, 98 | 99 | } 100 | 101 | if (headers) { 102 | requestInfo['headers'] = headers 103 | } 104 | 105 | return cy.request(requestInfo) 106 | }) 107 | 108 | Cypress.Commands.add("patchResource", (resource: string, body: object, queryParam?: number, headers?) => { 109 | const endpoint = getEndpoint(resource) 110 | let url = endpoint 111 | 112 | if (queryParam) { 113 | url = url + `/${queryParam}` 114 | } 115 | 116 | let requestInfo = { 117 | method: 'PATCH', 118 | url: url, 119 | body: body, 120 | } 121 | 122 | if (headers) { 123 | requestInfo['headers'] = headers 124 | } 125 | return cy.request(requestInfo) 126 | }) 127 | 128 | Cypress.Commands.add("deleteResource", (resource: string, queryParam?: number) => { 129 | let endpoint = getEndpoint(resource) 130 | 131 | let requestInfo = { 132 | method: 'DELETE', 133 | url: endpoint + "/" + queryParam, 134 | } 135 | 136 | return cy.request(requestInfo) 137 | }) -------------------------------------------------------------------------------- /projetos/apiTests/cypress/support/e2e.ts: -------------------------------------------------------------------------------- 1 | import "./app" 2 | import "./jsonActions" -------------------------------------------------------------------------------- /projetos/apiTests/cypress/support/jsonActions.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare namespace Cypress { 4 | interface Chainable { 5 | /** 6 | * Obtém todos os dados do endpoint /todos. 7 | * 8 | * @returns Uma promessa que resolve para um array de objetos JSON. 9 | * 10 | * @example 11 | * cy.getAllJson().then(data => { 12 | * expect(data.length).to.be.greaterThan(0) 13 | * }) 14 | */ 15 | getAllJson(): Chainable 16 | 17 | /** 18 | * Cria um novo post. 19 | * 20 | * @param title Título do post. 21 | * @param body Corpo do post. 22 | * @param userId ID do usuário que criou o post. 23 | * 24 | * @returns Uma promessa que resolve para o objeto do post criado. 25 | * 26 | * @example 27 | * cy.createPost('Meu primeiro post', 'Conteúdo do post', 1) 28 | */ 29 | createPost(title: string, body: string, userId: number): Chainable 30 | 31 | /** 32 | * Atualiza um post existente. 33 | * 34 | * @param bodyEdit Novo corpo do post. 35 | * @param titleEdit Novo título do post. 36 | * 37 | * @returns Uma promessa que resolve para o objeto do post atualizado. 38 | * 39 | * @example 40 | * cy.updatePost('Novo corpo', 'Novo título') 41 | * .then(post => { 42 | * expect(post.title).to.equal('Novo título') 43 | * }) 44 | */ 45 | updatePost(bodyEdit: string, titleEdit: string, id: number): Chainable 46 | 47 | /** 48 | * Deleta um post. 49 | * 50 | * @returns Uma promessa que resolve quando a operação é concluída. 51 | * 52 | * @example 53 | * cy.deletePost() 54 | */ 55 | deletePost(id: number) 56 | 57 | } 58 | 59 | } 60 | 61 | Cypress.Commands.add("getAllJson", () => { 62 | return cy.getResource("todos").then((res) => { 63 | expect(res.status).eq(200) 64 | return res.body 65 | }) 66 | }) 67 | 68 | Cypress.Commands.add("createPost", (title: string, body: string, userId: number) => { 69 | return cy.postResource("posts", { 70 | body, 71 | title, 72 | userId, 73 | }) 74 | .then((res) => { 75 | if (res.status === 201) { 76 | const createdPost = res.body 77 | expect(createdPost).to.have.property('id') 78 | expect(res.body['title']).eq(title) 79 | expect(res.body['body']).eq(body) 80 | expect(res.body['userId']).eq(userId) 81 | return createdPost as Post 82 | } else { 83 | throw new Error('Falha ao criar o post') 84 | } 85 | }) 86 | }) 87 | 88 | 89 | 90 | Cypress.Commands.add("updatePost", (bodyEdit: string, titleEdit: string, id: number) => { 91 | return cy.patchResource("posts", { 92 | title: titleEdit, 93 | body: bodyEdit, 94 | }, id) 95 | .then((res) => { 96 | expect(res.status).to.eq(200) 97 | const updatedPost = res.body 98 | expect(updatedPost).to.deep.equal({ 99 | title: titleEdit, 100 | body: bodyEdit, 101 | userId: updatedPost['userId'], 102 | id: updatedPost['id'] 103 | }) 104 | return updatedPost as Post 105 | }) 106 | }) 107 | 108 | 109 | 110 | Cypress.Commands.add("deletePost", (id: number) => { 111 | return cy.deleteResource("posts", id).then((res) =>{ 112 | expect(res.status).eq(200) 113 | }) 114 | }) -------------------------------------------------------------------------------- /projetos/apiTests/cypress/support/models/post.ts: -------------------------------------------------------------------------------- 1 | interface Post { 2 | userId?: number; 3 | id?: number; 4 | title: string; 5 | body: string; 6 | } -------------------------------------------------------------------------------- /projetos/apiTests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "cypress:open": "npx cypress open", 4 | "run:qa": "npx cypress run --config video=false --env endpoint=https://jsonplaceholder.typicode.com --headless", 5 | "generate:report": "jrm ./results/combined-report.xml \"./results/results-*.xml\"", 6 | "run:testsqa": "npm run run:qa && npm run generate:report" 7 | }, 8 | "dependencies": { 9 | "cypress": "12.3.0", 10 | "gerador-validador-cpf": "^5.0.2", 11 | "junit-report-merger": "^3.0.1", 12 | "mocha": "^10.2.0", 13 | "tsconfig-paths": "^4.1.0", 14 | "typescript": "^4.9.4" 15 | }, 16 | "devDependencies": { 17 | "@faker-js/faker": "^7.6.0" 18 | } 19 | } -------------------------------------------------------------------------------- /projetos/apiTests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["es5", "dom"], 5 | "types": ["cypress", "node"], 6 | }, 7 | "include": ["**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/README.md: -------------------------------------------------------------------------------- 1 | ## Lidando com Múltiplos Ambientes com Cypress 2 | 3 | Para rodar o mesmo projeto em ambientes diferentes, você pode configurar uma baseUrl e depois apontar o ambiente desejado ao rodar os scripts via linha de comando. 4 | 5 | ### Configuração do Ambiente 6 | 7 | 1. **Configuração Dinâmica com `baseUrl` via CLI**: Modifique o `cypress.config.js` para aceitar o `baseUrl` passado pela CLI e qualquer outra configuração específica do ambiente. 8 | 9 | ```javascript 10 | const { defineConfig } = require('cypress'); 11 | 12 | module.exports = defineConfig({ 13 | e2e: { 14 | 15 | baseUrl: 'http://staging.example.com', // url padrão, por exemplo: staging 16 | 17 | } 18 | }); 19 | ``` 20 | 21 | ### Executando Testes em Diferentes Ambientes 22 | 23 | Use scripts npm para executar testes em ambientes específicos, configurando o `baseUrl` diretamente na linha de comando. 24 | 25 | - **Desenvolvimento**: `npm run test:dev` 26 | - **Homologação**: `npm run test:staging` 27 | - **Produção**: `npm run test:prod` 28 | 29 | Defina esses scripts no seu `package.json`: 30 | 31 | ```json 32 | "scripts": { 33 | "test:dev": "cypress run --config baseUrl=http://localhost:3000", 34 | "test:staging": "cypress run --config baseUrl=http://staging.example.com", 35 | "test:prod": "cypress run --config baseUrl=http://example.com" 36 | } 37 | ``` 38 | 39 | ### Exemplo de Teste 40 | 41 | Um exemplo de arquivo de teste (`cypress/e2e/configBaseUrl.cy.js`) que utiliza o `baseUrl` configurado: 42 | 43 | ```javascript 44 | describe('Testes Específicos do Ambiente', () => { 45 | it('Visita a aplicação', () => { 46 | cy.visit('/'); 47 | cy.url().should('include', Cypress.config('baseUrl')); 48 | }); 49 | }); 50 | ``` -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require("cypress"); 2 | 3 | module.exports = defineConfig({ 4 | e2e: { 5 | baseUrl: 'https://www.asus.com/content/asus-software/', // url padrão, por exemplo: staging 6 | experimentalRunAllSpecs: true, 7 | setupNodeEvents(on, config) { 8 | // implement node event listeners here 9 | }, 10 | }, 11 | }); -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/cypress/e2e/configBaseUrl.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | Cypress.on('uncaught:exception', () => { 4 | // Retorna false para impedir que o Cypress falhe o teste 5 | return false 6 | }) 7 | 8 | describe('Testes Específicos do Ambiente', () => { 9 | it('Visita a aplicação', () => { 10 | cy.visit('/'); 11 | cy.url().should('include', Cypress.config('baseUrl')); 12 | }); 13 | }) -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add('login', (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/cypress/support/e2e.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/e2e.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') -------------------------------------------------------------------------------- /projetos/multiplosAmbientes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multiplosambientes", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "cypress.config.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "cy:open": "npx cypress open", 9 | "test:dev": "cypress run --config baseUrl=https://www.asus.com/support/", 10 | "test:staging": "cypress run --config baseUrl=https://www.asus.com/", 11 | "test:prod": "cypress run --config baseUrl=https://www.asus.com/content/asus-software/" 12 | }, 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /projetos/uncaughtException/README.md: -------------------------------------------------------------------------------- 1 | ## Lidando com uncaught exception 2 | 3 | ### O Cypress exibe erro de uncaught exception durante a execução dos testes 4 | 5 | Em alguns casos, o Cypress pode encontrar exceções não capturadas (erros de JavaScript) que faz o teste falhar. Para continuar a execução dos testes, você pode usar um comando para ignorar essa exceção. 6 | 7 | #### Como usar `Cypress.on('uncaught:exception')`? 8 | 9 | Adicione o comando abaixo no arquivo de configuração (`cypress/support/e2e.js`) para ignorar todas as exceções não capturadas: 10 | 11 | ```javascript 12 | Cypress.on('uncaught:exception', (err, runnable) => { 13 | // Retorna false para impedir que o Cypress falhe o teste 14 | return false 15 | }) 16 | ``` 17 | ### Quando devo usar esta abordagem? 18 | 19 | Essa abordagem deve ser usada com cuidado. Ignorar exceções pode ocultar problemas reais que precisam ser corrigidos na sua aplicação. Use se você sabe que é um erro conhecido que não afeta os testes que você está executando. 20 | 21 | ### Há alguma alternativa para lidar com exceções específicas? 22 | 23 | Sim, se você quiser lidar com exceções específicas, você pode adicionar lógica dentro da função de callback para filtrar erros dependendo da mensagem ou outros atributos: 24 | 25 | ```javascript 26 | Cypress.on('uncaught:exception', (err, runnable) => { 27 | // Ignora exceções específicas com base na mensagem de erro 28 | if (err.message.includes('Expected error message')) { 29 | return false 30 | } 31 | // Permite que outras exceções interrompam os testes 32 | return true 33 | }) 34 | ``` 35 | ### Exemplo Prático 36 | 37 | O exemplo abaixo ignora um erro específico de uma biblioteca de terceiros, mas permite que outras exceções interrompam os testes: 38 | 39 | ```javascript 40 | Cypress.on('uncaught:exception', (err, runnable) => { 41 | // Ignora erros da biblioteca 'ResizeObserver' 42 | if (err.message.includes('ResizeObserver loop limit exceeded')) { 43 | return false 44 | } 45 | // Permite que outras exceções interrompam os testes 46 | return true 47 | }) 48 | ``` -------------------------------------------------------------------------------- /projetos/uncaughtException/cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require("cypress"); 2 | 3 | module.exports = defineConfig({ 4 | e2e: { 5 | setupNodeEvents(on, config) { 6 | // implement node event listeners here 7 | }, 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /projetos/uncaughtException/cypress/e2e/comUncaughtException.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | Cypress.on('uncaught:exception', () => { 4 | // Retorna false para impedir que o Cypress falhe o teste 5 | return false 6 | }) 7 | 8 | describe('Visitando com sucesso', () => { 9 | it('Deve visitar com sucesso', () => { 10 | cy.visit('https://www.alura.com.br/') 11 | }) 12 | }) -------------------------------------------------------------------------------- /projetos/uncaughtException/cypress/e2e/semUncaughtException.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | describe('Visitando sem sucesso', () => { 4 | it('Deve falhar a visita', () => { 5 | cy.visit('https://www.alura.com.br/') 6 | }) 7 | }) -------------------------------------------------------------------------------- /projetos/uncaughtException/cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /projetos/uncaughtException/cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add('login', (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -------------------------------------------------------------------------------- /projetos/uncaughtException/cypress/support/e2e.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/e2e.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') -------------------------------------------------------------------------------- /projetos/uncaughtException/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uncaughtexception", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "cypress": "^13.11.0" 13 | } 14 | } 15 | --------------------------------------------------------------------------------