<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: João Pedro Costi</title>
    <description>The latest articles on DEV Community by João Pedro Costi (@joaocosti).</description>
    <link>https://dev.to/joaocosti</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F903486%2Fe5f23927-4eee-4f7f-94a1-9886cca5188e.jpeg</url>
      <title>DEV Community: João Pedro Costi</title>
      <link>https://dev.to/joaocosti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joaocosti"/>
    <language>en</language>
    <item>
      <title>Como formatar e garantir boas práticas em projetos de automação Cypress utilizando a ferramenta Eslint.</title>
      <dc:creator>João Pedro Costi</dc:creator>
      <pubDate>Tue, 23 Aug 2022 21:40:00 +0000</pubDate>
      <link>https://dev.to/joaocosti/eslint-em-projetos-de-cypress-o-que-e-e-quais-suas-vantagens-5765</link>
      <guid>https://dev.to/joaocosti/eslint-em-projetos-de-cypress-o-que-e-e-quais-suas-vantagens-5765</guid>
      <description>&lt;p&gt;No cotidiano da automação de testes ou em projetos que são criados códigos, um dos principais problemas é garantir a qualidade, seja com boas práticas ou um padrão de formatação.&lt;/p&gt;

&lt;p&gt;Uma das maneiras para garantir a qualidade da automação é realizar a revisão de código de outras pessoas (&lt;em&gt;code review&lt;/em&gt;), mas isso acaba sendo um processo custoso por necessitar de uma análise critica e correção de problemas. Para nossa sorte, existe uma ferramente que podemos utilizar que já analisa certos de erros de codificação, formata o código conforme o padrão definido e no caso de automação com Cypress, mostra no código onde existem más práticas de automação de testes. A ferramenta que me refiro é o &lt;a href="https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage" rel="noopener noreferrer"&gt;Eslint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para fins explicativos criei um repositório no &lt;a href="https://github.com/joaocosti/lint-husky-with-cypress/tree/main" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; com os cenários padrões fornecidos pelo Cypress na &lt;em&gt;branch&lt;/em&gt; main. Em seguida instalei o &lt;a href="https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage" rel="noopener noreferrer"&gt;Eslint&lt;/a&gt; na &lt;em&gt;branch&lt;/em&gt; eslint, seguindo os padrões do &lt;em&gt;lint&lt;/em&gt; &lt;a href="https://github.com/airbnb/javascript" rel="noopener noreferrer"&gt;airbnb&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dentro do arquivo &lt;code&gt;package.json&lt;/code&gt; adicionei dois comandos dentro de &lt;code&gt;scripts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"eslint": "eslint cypress/",
"eslint:fix": "eslint cypress/ --fix"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao executar o comando &lt;code&gt;npm run eslint&lt;/code&gt; é apresentado no terminal apenas os erros e avisos de formatação ou de codificação, por exemplo, na imagem abaixo é possível ver um erro no arquivo &lt;code&gt;e2e.js&lt;/code&gt; com a mensagem &lt;em&gt;semi&lt;/em&gt;, no início do erro é possível encontrar qual a linha que está o erro, no caso seria a 17. O erro apresentado diz que está faltando um &lt;code&gt;;&lt;/code&gt; no final do código, no javascript essa regra não é obrigatório, mas como defini para utilizar o &lt;em&gt;lint&lt;/em&gt; Airbnb é obrigatório.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox6maxjsj3a1fksqrhjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox6maxjsj3a1fksqrhjl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O problema do comando a cima é a exaustão de colocar &lt;code&gt;;&lt;/code&gt; em todas as linhas necessárias, ou ter que arrumar o espaçamento de cada linha segundo as regras do &lt;em&gt;lint&lt;/em&gt;, mas a boa notícia é que o outro comando &lt;code&gt;npm run eslint:fix&lt;/code&gt; já corrige a formatação e apresenta somente os erros de codificação. Quando digo erro de codificação seria uma variável que é declarada mas nunca é usada ou uma importação de um arquivo que não existe.&lt;/p&gt;

&lt;p&gt;Na imagem abaixo, executei o comando anteriormente mencionado, em relação à última figura os erros passaram de 818 para 46, isso porque os problemas de formatação foram resolvidos.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f51gils3x802uj7eks1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f51gils3x802uj7eks1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima, o Eslint apresentou um erro em que alerta um problema para o &lt;code&gt;cy.wait&lt;/code&gt;, isso porque eu instalei uma &lt;a href="https://github.com/cypress-io/eslint-plugin-cypress" rel="noopener noreferrer"&gt;extensão que verifica boas práticas relacionadas a códigos de projetos cypress&lt;/a&gt;, por padrão essa extensão possui as seguintes regras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Impedir a atribuição de valores em comandos cy;&lt;/li&gt;
&lt;li&gt;Evitar espera com cy.wait;&lt;/li&gt;
&lt;li&gt;Impedir o uso de async/await em comandos Cypress;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É possível adicionar outras regras, por exemplo, evitar que seja usado &lt;code&gt;{force:true}&lt;/code&gt; nos comandos Cypress, para isso adicionei a regra &lt;code&gt;"cypress/no-force": "error"&lt;/code&gt; na seção &lt;code&gt;rules&lt;/code&gt; dento do arquivo do Eslint, assim uma vez que execute o comando do Eslint, será apresentado erro em todos os comandos que utilizem &lt;code&gt;{force:true}&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88m1k4mhhg3lx1hfkag3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88m1k4mhhg3lx1hfkag3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A partir do Eslint é possível encontrar erros de formatação e codificação de forma eficiente, essa ferramenta não acaba com a necessidade de code review, mas permite que erros sejam encontrados e corrigidos de uma maneira mais eficiente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/joaocosti/lint-husky-with-cypress" rel="noopener noreferrer"&gt;Repositório do no github que apliquei o eslint&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.toGitHub%20-%20cypress-io/eslint-plugin-cypress:%20An%20ESLint%20plugin%20for%20projects%20that%20use%20Cypress"&gt;Lint do cypress&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage" rel="noopener noreferrer"&gt;Eslint&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Laços de repetição com funções recursivas e comandos do Cypress</title>
      <dc:creator>João Pedro Costi</dc:creator>
      <pubDate>Thu, 04 Aug 2022 19:21:00 +0000</pubDate>
      <link>https://dev.to/joaocosti/lacos-de-repeticao-com-funcoes-recursiva-utilizando-cypress-5a21</link>
      <guid>https://dev.to/joaocosti/lacos-de-repeticao-com-funcoes-recursiva-utilizando-cypress-5a21</guid>
      <description>&lt;p&gt;Recentemente me deparei com um problema, onde utilizava &lt;code&gt;cy.wait()&lt;/code&gt; para esperar até que dados de um sistema passassem por alguns micro-serviços e fossem refletidos em outro sistema que era uma API, o problema é que utilizando &lt;code&gt;cy.wait()&lt;/code&gt; os dados poderiam já terem sido refletidos, mas o Cypress ainda iria continuar esperando o tempo pré-definido. &lt;/p&gt;

&lt;p&gt;Buscando então uma solução, pensei em criar uma forma onde o código iria ficar consultando a requisição da Api, durante um certo tempo ou até que o dado fosse refletido. &lt;/p&gt;

&lt;p&gt;Inicialmente pensei em utilizar laços de repetição tradicionais (do, while, do while), assim colocaria uma condição onde o loop iria parar caso o número de interações chegasse ao limite ou os dados fossem refletidos na Api. Mas com Cypress isso não é possível, pelo fato desses laços de repetição serem síncronos, mas o comando (&lt;code&gt;cy.request&lt;/code&gt;) do Cypress ser assíncrono.&lt;/p&gt;

&lt;p&gt;Desta maneira, a outra forma que encontrei foi  utilizar funções recursivas, que são funções que chamam a si mesmo até uma certa condição ser satisfeita, uma vez satisfeita a chamada das funções é encerrada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de função recursiva com código do Cypress&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Inicialmente criei uma função que recebe como parâmetro um contador, que será o número de tentativas de consulta na API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function recursiva(contador = 60) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, inseri as informações para realizar a requisição no comando &lt;code&gt;cy.request&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy
        .request({
            method: 'GET',
            url: 'https://UrlDeExemplo.com.br',
            log: false,
            failOnStatusCode: false
        })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deixei a flag &lt;code&gt;log&lt;/code&gt; desativada para não mostrar todas as requisições no console do Cypress, e também desativei a flag &lt;code&gt;failOnStatusCode&lt;/code&gt; para o Cypress não dar erro de execução caso a requisição falhe.&lt;/p&gt;

&lt;p&gt;Assim, uma vez o &lt;code&gt;cy.request&lt;/code&gt; executado, eu obtenho a resposta da requisição utilizando o comando &lt;code&gt;.then()&lt;/code&gt; e salvando o valor na variável &lt;code&gt;resposta&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Dentro &lt;code&gt;.then()&lt;/code&gt; é onde coloco as condições para encerrar a chamada de função:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;No primeiro &lt;code&gt;if&lt;/code&gt; verifico se o status da resposta foi 200, isso significa que o dado foi refletido na API, assim posso encerrar a chamada das funções; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na segunda, caso o contador chegue a 0,  significa que o número total de requisições que defini foi executado e as respostas das requisições continuaram não dando 200, assim considero que os dados não foram refletidos e posso acabar também a execução das funções;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;E por último, é caso a requisição não deu 200 e o número de requisições não foram finalizadas, assim decremento um na variável &lt;code&gt;contador&lt;/code&gt; e chamo a função novamente passando o novo valor do contador.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.then((resposta) =&amp;gt; {
            if (resposta.status === 200) return;
            else if (contador === 0) {
                cy.log('Os dados não foram refletidos');
                return;
            } else {
                const DECREMENTA_CONTADOR = contador - 1; 
                recursiva(DECREMENTA_CONTADOR);
            }
        });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Juntando as partes do código,  ele fica da seguinte maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function recursiva(contador = 60) {
    cy
        .request({
            method: 'GET',
            url: 'https://UrlDeExemplo.com.br',
            log: false,
            failOnStatusCode: false
        })
        .then((resposta) =&amp;gt; {
            if (resposta.status === 200) return;
            else if (contador === 0) {
                cy.log('Os dados não foram refletidos');
                return;
            } else {
                const DECREMENTA_CONTADOR = contador - 1; 
                recursiva(DECREMENTA_CONTADOR);
            }
        });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código acima pode ser adaptado de acordo com sua necessidade, o que mais é importante é a condição para parar a execução da função.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Utilizando funções recursivas é possível realizar laços de repetição com comandos do Cypress. O principal fato de ter optado por essa escolha foi evitar o uso de &lt;code&gt;cy.wait()&lt;/code&gt; e assim diminuir o tempo de execução, mas ainda continuar garantido que se o dado não foi refletido para a API não foi por questão de espera de tempo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Créditos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Créditos para o Rodrigo Matola que deu idéia de utilizar funções recursivas para resolver o problema.&lt;/p&gt;

&lt;p&gt;Linkdin do Rodrigo: &lt;a href="https://www.linkedin.com/in/rodrigomatola/"&gt;https://www.linkedin.com/in/rodrigomatola/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meu Linkdin:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/jo%C3%A3o-pedro-costi-78a874a2/"&gt;https://www.linkedin.com/in/jo%C3%A3o-pedro-costi-78a874a2/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
