<?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>Forem: Evgeny Orekhov</title>
    <description>The latest articles on Forem by Evgeny Orekhov (@evgenyorekhov).</description>
    <link>https://forem.com/evgenyorekhov</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%2F414654%2F5af99b4f-9a72-4a61-ab81-3ec645f0fe5d.jpeg</url>
      <title>Forem: Evgeny Orekhov</title>
      <link>https://forem.com/evgenyorekhov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/evgenyorekhov"/>
    <language>en</language>
    <item>
      <title>More Cypress Best Practices</title>
      <dc:creator>Evgeny Orekhov</dc:creator>
      <pubDate>Sun, 02 Apr 2023 14:24:55 +0000</pubDate>
      <link>https://forem.com/evgenyorekhov/more-cypress-best-practices-266g</link>
      <guid>https://forem.com/evgenyorekhov/more-cypress-best-practices-266g</guid>
      <description>&lt;p&gt;These are some additional Cypress best practices that I haven't seen in any other articles about Cypress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use &lt;a href="https://github.com/cypress-io/eslint-plugin-cypress"&gt;eslint-plugin-cypress&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The best way to avoid anti-patterns is to have a tool that will catch them for you as early as possible.&lt;/p&gt;

&lt;p&gt;Make sure to enable all available rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"plugin:cypress/recommended"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cypress/no-force"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cypress/assertion-before-screenshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cypress/require-data-selectors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cypress/no-pause"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And make sure to read about each rule to improve your understanding of Cypress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use UI assertions to reduce test flakiness
&lt;/h2&gt;

&lt;p&gt;If you find that a certain action sometimes gets performed earlier than it should, then add a UI assertion before it.&lt;/p&gt;

&lt;p&gt;In this example we want to wait for a comment to appear before adding another one, otherwise, we may end up with a flaky race condition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  cy.findByRole("textbox", { name: "Comment" }).type("My first comment");
  cy.findByRole("button", { name: "Post comment" }).click();
&lt;span class="gi"&gt;+ cy.findByText("My first comment").to("be.visible");
&lt;/span&gt;  cy.findByRole("textbox", { name: "Comment" }).type("My second comment");
  cy.findByRole("button", { name: "Post comment" }).click();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use UI assertions to reduce screenshot flakiness
&lt;/h2&gt;

&lt;p&gt;This is what &lt;a href="https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/assertion-before-screenshot.md"&gt;&lt;code&gt;cypress/assertion-before-screenshot&lt;/code&gt;&lt;/a&gt; rule is about. If you take screenshots without assertions then you may get different screenshots depending on timing.&lt;/p&gt;

&lt;p&gt;Unfortunately, the rule works only with the default &lt;code&gt;cy.screenshot()&lt;/code&gt; command, so you need to be diligent if you use a different one, like &lt;code&gt;cy.percySnapshot()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this example, after publishing a new post, we want to wait for it to appear in the UI before taking a screenshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  cy.findByRole("button", { name: "Publish" }).click();
&lt;span class="gi"&gt;+ cy.findByRole("heading", { name: "My new post" }).to("be.visible");
&lt;/span&gt;  cy.percySnapshot("Posts - new post");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use functions to create reusable commands
&lt;/h2&gt;

&lt;p&gt;In most cases, performing a single meaningful action will involve executing multiple commands and assertions. If you find yourself repeating the same commands over and over, create a function that abstracts them away.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;goToPosts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByAltText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Menu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mouseover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;textbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Post name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;textbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Post content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Publish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;textbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Post comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;deletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Open &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;postName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; menu`&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Delete &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;postName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Yes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will make your tests concise and clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can create a new post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My new post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;goToPosts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My post content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;addComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My first comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;addComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My second comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My second comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;screenshot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;deletePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Make production code more accessible
&lt;/h2&gt;

&lt;p&gt;If you find that it's impossible or hard to use an accessible &lt;a href="https://testing-library.com/docs/cypress-testing-library/intro/"&gt;Testing Library&lt;/a&gt; query, go ahead and change the production code to make it more accessible. It will make your users happier, and your tests less dependent on implementation details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- &amp;lt;div onClick={handleClick}&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+ &amp;lt;button type="button" onClick={handleClick}&amp;gt;
&lt;/span&gt;    Create post
&lt;span class="gd"&gt;- &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+ &amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use &lt;code&gt;cy.within()&lt;/code&gt; instead of &lt;code&gt;cy.findAllBy*()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If a page contains multiple elements with the same role and name (like multiple forms with "Save" button), instead of using &lt;code&gt;cy.findAllBy*().first()&lt;/code&gt; or &lt;code&gt;cy.findAllBy*().eq(&amp;lt;index&amp;gt;)&lt;/code&gt;, try to use &lt;code&gt;cy.within()&lt;/code&gt;. It will make your tests less dependent on implementation details. But better yet, try to avoid those situations in the first place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- cy.findAllByRole("button", { name: "Save" }).eq(1).click();
&lt;/span&gt;&lt;span class="gi"&gt;+ cy.findByRole("form", { name: "User settings" }).within(() =&amp;gt; {
+   cy.findByRole("button", { name: "Save" }).click();
+ });
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use &lt;a href="https://github.com/filiphric/cypress-plugin-steps"&gt;cypress-plugin-steps&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;If you find yourself using code comments a lot in your Cypress tests, consider using &lt;code&gt;cy.step()&lt;/code&gt; from cypress-plugin-steps instead. It will show the messages in the test log, and if your test fails, your scenario will be added to the error message, and it will be easier to pinpoint the failed command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- // Go to posts
&lt;/span&gt;&lt;span class="gi"&gt;+ cy.step("Go to posts");
&lt;/span&gt;  cy.findByAltText("Menu").trigger("mouseover");
  cy.findByRole("link", { name: "Posts" }).click();

- // Delete post
&lt;span class="gi"&gt;+ cy.step("Delete post");
&lt;/span&gt;  cy.findByRole("button", { name: 'Open "My new post" menu' }).click();
  cy.findByRole("button", { name: 'Delete "My new post"' }).click();
  cy.findByRole("button", { name: "Yes" }).click();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you liked this article, you should check out&lt;br&gt;
&lt;a href="https://dev.to/evgenyorekhov/cypress-best-practices-that-are-actually-bad-2m3m"&gt;&lt;strong&gt;Cypress Best Practices that are actually bad&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cypress</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Cypress Best Practices that are actually bad</title>
      <dc:creator>Evgeny Orekhov</dc:creator>
      <pubDate>Sat, 01 Apr 2023 10:24:17 +0000</pubDate>
      <link>https://forem.com/evgenyorekhov/cypress-best-practices-that-are-actually-bad-2m3m</link>
      <guid>https://forem.com/evgenyorekhov/cypress-best-practices-that-are-actually-bad-2m3m</guid>
      <description>&lt;p&gt;These are some of the &lt;a href="https://docs.cypress.io/guides/references/best-practices"&gt;best practices from the official Cypress documentation&lt;/a&gt; which are actually anti-patterns.&lt;/p&gt;

&lt;p&gt;I'll explain why and give you better alternatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://docs.cypress.io/guides/references/best-practices#Selecting-Elements"&gt;Use &lt;code&gt;data-*&lt;/code&gt; attributes&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why it's bad
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;data-*&lt;/code&gt; attributes clutter your production code and make your tests be dependent on implementation details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better alternative: &lt;a href="https://testing-library.com/docs/cypress-testing-library/intro/"&gt;Cypress Testing Library&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It doesn't require you to add extra stuff to your markup, makes your tests more abstract, and helps you improve accessibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pro tips
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Use ESLint to forbid &lt;code&gt;cy.get()&lt;/code&gt; entirely
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"no-restricted-properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"property"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use Testing Library query."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Follow &lt;a href="https://testing-library.com/docs/queries/about/#priority"&gt;Testing Library priority guide&lt;/a&gt; when writing queries
&lt;/h4&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://docs.cypress.io/guides/references/best-practices#Unnecessary-Waiting"&gt;Use route aliases&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why it's bad
&lt;/h3&gt;

&lt;p&gt;It still makes your tests flaky, and it makes them be dependent on implementation details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better alternative: UI assertions
&lt;/h3&gt;

&lt;p&gt;Wait for something to appear in the UI, not for network requests to finish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;publish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Publish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@publish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Publish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My new post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pro tip
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Use ESLint to forbid &lt;code&gt;cy.wait()&lt;/code&gt; entirely
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"no-restricted-properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"property"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wait"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use UI assertion."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you liked this article, you should check out&lt;br&gt;
&lt;a href="https://dev.to/evgenyorekhov/more-cypress-best-practices-266g"&gt;&lt;strong&gt;More Cypress Best Practices&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cypress</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Prefer npm scripts to global commands</title>
      <dc:creator>Evgeny Orekhov</dc:creator>
      <pubDate>Sat, 12 Jun 2021 13:18:13 +0000</pubDate>
      <link>https://forem.com/evgenyorekhov/prefer-npm-scripts-to-global-commands-8g3</link>
      <guid>https://forem.com/evgenyorekhov/prefer-npm-scripts-to-global-commands-8g3</guid>
      <description>&lt;p&gt;Define npm scripts in your &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ember serve"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ember exam --load-balance --parallel=4"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm-run-all --parallel --aggregate-output lint:**"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;and use those scripts, don't use global commands.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bad: &lt;code&gt;ember test&lt;/code&gt; (yes, it's bad even if you see it in &lt;a href="https://guides.emberjs.com/release/testing/#toc_how-to-run-tests"&gt;the official docs&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Good: &lt;code&gt;npm test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are several benefits to using npm scripts instead of global commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No chance of local vs global package version mismatch that can lead to inexplicable errors&lt;/li&gt;
&lt;li&gt;No chance of using the wrong command and/or options (for example, the default command for running tests in Ember projects is &lt;code&gt;ember test&lt;/code&gt;, but a project might use &lt;code&gt;ember exam&lt;/code&gt; and/or additional options like &lt;code&gt;--load-balance --parallel=4&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;No need to remember specific commands for each type of project, because &lt;code&gt;npm start&lt;/code&gt; and &lt;code&gt;npm test&lt;/code&gt; are &lt;strong&gt;standard&lt;/strong&gt; commands used by virtually every JavaScript project, be it an Ember project, a React project, or an Express project&lt;/li&gt;
&lt;li&gt;No need to install global packages, keep track of their versions, and update them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you really need to run a one-off command, use npx, it will protect you from local vs global package version mismatch (because it uses local package if it detects one):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;npx prettier --write .
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>node</category>
      <category>npm</category>
    </item>
    <item>
      <title>Use 👍 more often</title>
      <dc:creator>Evgeny Orekhov</dc:creator>
      <pubDate>Wed, 26 Aug 2020 17:25:54 +0000</pubDate>
      <link>https://forem.com/evgenyorekhov/use-more-often-36le</link>
      <guid>https://forem.com/evgenyorekhov/use-more-often-36le</guid>
      <description>&lt;p&gt;Agree with a GitHub comment? Spare a second of your time and give that comment a 👍. It can make the author of the content feel good and encourage them to contribute more.&lt;/p&gt;

&lt;p&gt;Want that issue to be resolved sooner? Give it a 👍. It's often used by maintainers for prioritizing issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some advice:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;favor 👍 over ❤️/🎉/🚀 for GitHub issues, it will make prioritizing issues easier to do for maintainers (GitHub UI allows you to sort issues only by a particular reaction)&lt;/li&gt;
&lt;li&gt;use 👎 less often (or don't use it at all), it can make the contributor feel bad and even discourage them from contributing&lt;/li&gt;
&lt;li&gt;never write a comment that just says "+1" or "👍", use the 👍 &lt;strong&gt;reaction&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use 👍 more often.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>eslint-config-hardcore – 17 plugins, 500 rules, and counting</title>
      <dc:creator>Evgeny Orekhov</dc:creator>
      <pubDate>Mon, 22 Jun 2020 17:37:47 +0000</pubDate>
      <link>https://forem.com/evgenyorekhov/eslint-config-hardcore-17-plugins-500-rules-and-counting-1k78</link>
      <guid>https://forem.com/evgenyorekhov/eslint-config-hardcore-17-plugins-500-rules-and-counting-1k78</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/EvgenyOrekhov/eslint-config-hardcore"&gt;eslint-config-hardcore&lt;/a&gt; is a framework-agnostic "batteries included" config that aims to enable as many plugins and rules as possible to make your code extremely consistent and robust. It uses Prettier code style and autoformats your code with eslint-plugin-prettier.&lt;/p&gt;

&lt;p&gt;There are dozens of great ESLint plugins out there. Did you know that there is a plugin that can optimize your regexes for you? Or did you know that ESLint can validate &lt;code&gt;*.json&lt;/code&gt; files? This config allows you to gain the power of all those awesome plugins with a single &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Fun (and useful) fact: you can use typescript-eslint for linting your JavaScript code. That's right, you can take advantage of typescript-eslint's type-aware rules, like &lt;code&gt;@typescript-eslint/naming-convention&lt;/code&gt; and &lt;code&gt;@typescript-eslint/prefer-optional-chain&lt;/code&gt;, without the need to switch to writing TypeScript. Use the &lt;code&gt;hardcore/ts-for-js&lt;/code&gt; config for that.&lt;/p&gt;

&lt;p&gt;Also, did you know that when you enable an ESLint rule with &lt;code&gt;"rule-name": "error"&lt;/code&gt;, you don't get all the benefits the rule can provide? Many rules have advanced options that are disabled by default. For example, the &lt;code&gt;no-unneeded-ternary&lt;/code&gt; rule has the &lt;code&gt;defaultAssignment&lt;/code&gt; option that can enforce using &lt;code&gt;foo = bar || default&lt;/code&gt; instead of &lt;code&gt;foo = bar ? bar : default&lt;/code&gt;. And the &lt;code&gt;no-param-reassign&lt;/code&gt; rule allows you to modify parameter properties by default, which is considered a bad practice. This config uses those stricter options whenever it makes sense.&lt;/p&gt;

&lt;p&gt;Back in 2016, when I started compiling this config, it was helping me begin my JavaScript journey. I was using it on small projects, and it was helping me avoid many JavaScript pitfalls. Over the years it grew and proved itself as an extremely useful tool for all kinds of projects, both backend and frontend. Now, I can't imagine what I would do without it and how much more painful our code reviews would be. And I really want to avoid any kind of nitpicking in pull requests. Let ESLint catch (and most of the time autofix!) all problems early.&lt;/p&gt;

&lt;p&gt;The funniest thing: 500 rules are still not enough. We still spend time in code reviews catching issues and inconsistencies, especially when there are new developers on the team. So, expect to see more and more plugins and rules in the config in the future.&lt;/p&gt;

&lt;p&gt;Let me know what you think. Try it out. Suggest more plugins.&lt;/p&gt;

&lt;p&gt;Hacker News thread: &lt;a href="https://news.ycombinator.com/item?id=23602860"&gt;https://news.ycombinator.com/item?id=23602860&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codequality</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
