<?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: Yevhen Laichenkov</title>
    <description>The latest articles on DEV Community by Yevhen Laichenkov (@elaichenkov).</description>
    <link>https://dev.to/elaichenkov</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%2F339670%2F3ecae1fc-346d-4aaf-adc7-d2ff84f57827.jpg</url>
      <title>DEV Community: Yevhen Laichenkov</title>
      <link>https://dev.to/elaichenkov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elaichenkov"/>
    <language>en</language>
    <item>
      <title>Cypress: Copy Debug Prompt</title>
      <dc:creator>Yevhen Laichenkov</dc:creator>
      <pubDate>Tue, 03 Jun 2025 02:20:13 +0000</pubDate>
      <link>https://dev.to/elaichenkov/cypress-copy-debug-prompt-4hnb</link>
      <guid>https://dev.to/elaichenkov/cypress-copy-debug-prompt-4hnb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The test failed. Of course it did. And now you're in a staring contest with a stack trace that refuses to make sense.&lt;/p&gt;

&lt;p&gt;So I built a plugin that generates a ready-to-use prompt you can drop into any AI chat (ChatGPT or your favorite LLM). It packs in all the useful context: test steps, environment info, error messages, and stack traces, so the AI actually gets what happened.&lt;/p&gt;

&lt;p&gt;No digging through logs. No re-explaining your setup. Just click "Copy Debug Prompt", paste it into ChatGPT, and get help that makes sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;The plugin hooks into Cypress's failure handling. When a test fails, it captures the error message, test title, relevant stack trace, and even the surrounding context, then wraps it all into a clean, AI-friendly prompt.&lt;/p&gt;

&lt;p&gt;To see the "Copy Debug Prompt" button we have to install the plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; cy-copy-prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then add this line to &lt;code&gt;cypress/support/e2e.js&lt;/code&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="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cy-copy-prompt&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;Now, whenever a test fails, you'll see a "Copy Debug Prompt" button in the Cypress app. One click, and your clipboard is loaded with a prompt that's ready to paste into AI chat.&lt;/p&gt;

&lt;p&gt;Prompt Copied to Clipboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2ewea33k892mg45hdbv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2ewea33k892mg45hdbv9.png" alt="Prompt Copied to Clipboard" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then paste it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fa19q8xxadyn37k4npqgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fa19q8xxadyn37k4npqgi.png" alt="AI chat" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;Inspired by Playwright's "Copy Prompt" feature, this plugin brings the same convenience to Cypress. It's simple, helpful, and &lt;a href="https://github.com/elaichenkov/cy-copy-prompt" rel="noopener noreferrer"&gt;open source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Try it out. If you like it, star it, fork it, or suggest a tweak.&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
      <category>automation</category>
      <category>javascript</category>
    </item>
    <item>
      <title>10 Mistakes to Avoid When Using Cypress</title>
      <dc:creator>Yevhen Laichenkov</dc:creator>
      <pubDate>Fri, 19 Jan 2024 11:41:15 +0000</pubDate>
      <link>https://dev.to/elaichenkov/10-mistakes-to-avoid-when-using-cypress-411o</link>
      <guid>https://dev.to/elaichenkov/10-mistakes-to-avoid-when-using-cypress-411o</guid>
      <description>&lt;p&gt;As a seasoned Cypress user, I've observed recurring patterns of errors among many engineers over the years. So, this article aims to shed light on &lt;strong&gt;10 common but often overlooked pitfalls&lt;/strong&gt; in Cypress usage. &lt;/p&gt;

&lt;p&gt;Whether you're new to this powerful testing tool or have been using it for some time, you're likely to discover some &lt;strong&gt;insightful tips and tricks&lt;/strong&gt; that haven't been widely discussed before. Get ready to elevate your Cypress skills with some valuable lessons!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Using &lt;code&gt;.then()&lt;/code&gt; instead of &lt;code&gt;.should()&lt;/code&gt; for &lt;strong&gt;multiple assertions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.then()&lt;/code&gt; method in Cypress is pivotal for accessing and manipulating the yielded subject within a callback function. This method is particularly useful when you need to perform specific &lt;strong&gt;actions&lt;/strong&gt; or &lt;strong&gt;transform values&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, a common misconception is equating &lt;code&gt;.then()&lt;/code&gt; with &lt;code&gt;.should()&lt;/code&gt;. These methods function differently. The &lt;code&gt;.should()&lt;/code&gt; method is designed to automatically &lt;strong&gt;wait&lt;/strong&gt; and &lt;strong&gt;retry&lt;/strong&gt; until all conditions within the callback function are met. Typically, &lt;code&gt;.should()&lt;/code&gt; passes on the same subject it received from the preceding command. Crucially, any value returned from within a &lt;code&gt;.should()&lt;/code&gt; callback is not utilized, a key difference to remember when writing your Cypress tests.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Ensure idempotency in &lt;code&gt;.should()&lt;/code&gt; callbacks&lt;/p&gt;

&lt;p&gt;It's crucial to design callback functions within &lt;code&gt;.should()&lt;/code&gt; to be &lt;strong&gt;resilient&lt;/strong&gt; and &lt;strong&gt;side-effect-free&lt;/strong&gt;, capable of enduring multiple executions. This is because Cypress employs a retry mechanism for these functions. In case of an assertion failure, Cypress will &lt;strong&gt;repeatedly attempt the assertions&lt;/strong&gt; until a timeout occurs. To adapt to this behavior, your code must be &lt;strong&gt;idempotent&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep in mind that &lt;code&gt;.and()&lt;/code&gt; is an alias for &lt;code&gt;.should()&lt;/code&gt;. Hence, it &lt;strong&gt;waits&lt;/strong&gt; and &lt;strong&gt;retries&lt;/strong&gt; as well.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;❌&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.header&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;$header&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$header&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="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$div&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;className&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="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/heading-/&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;✅&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.header&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="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;$header&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$header&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="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$div&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;className&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="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/heading-/&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;
  
  
  2. Explicitly clearing &lt;code&gt;cookies&lt;/code&gt;, &lt;code&gt;local&lt;/code&gt;, and &lt;code&gt;session&lt;/code&gt; storage &lt;strong&gt;before each test&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Cypress is designed to maintain test integrity by automatically wiping all cookies, local storage, and session storage before each test. This feature is essential for ensuring that no residual state is carried over between tests when &lt;strong&gt;test isolation is enabled&lt;/strong&gt;. Typically, you won't need to manually clear these storages unless you're addressing a specific requirement within a single test, or if test isolation is turned off. Specifically, Cypress takes care of clearing the following before each test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cookies across all domains&lt;/li&gt;
&lt;li&gt;local storage across all domains&lt;/li&gt;
&lt;li&gt;session storage across all domains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding this automatic process is crucial for writing &lt;strong&gt;effective&lt;/strong&gt; and &lt;strong&gt;isolated&lt;/strong&gt; tests in Cypress.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;❌&lt;/span&gt;
&lt;span class="nf"&gt;before&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;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearAllCookies&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="nf"&gt;clearAllLocalStorage&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="nf"&gt;clearAllSessionStorage&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;✅&lt;/span&gt;
&lt;span class="nf"&gt;before&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="c1"&gt;// perform actions you need&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  3. Passing the &lt;code&gt;--headless&lt;/code&gt; flag
&lt;/h2&gt;

&lt;p&gt;Starting from version &lt;strong&gt;8.0&lt;/strong&gt;, Cypress has streamlined its operation by defaulting to &lt;strong&gt;headless&lt;/strong&gt; test execution. This enhancement means that the &lt;code&gt;--headless&lt;/code&gt; flag is no longer necessary when you use the &lt;code&gt;cypress run&lt;/code&gt; command. This update simplifies the testing process, making it more efficient and user-friendly. However, it's worth noting that some users still add this flag, perhaps out of habit or for explicit confirmation, even though &lt;strong&gt;it's no longer required&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

❌
cypress run &lt;span class="nt"&gt;--browser&lt;/span&gt; chrome &lt;span class="nt"&gt;--headless&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

✅
cypress run &lt;span class="nt"&gt;--browser&lt;/span&gt; chrome


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  4. Ignoring &lt;strong&gt;experimental&lt;/strong&gt; features
&lt;/h2&gt;

&lt;p&gt;If you're unfamiliar with experimental features in Cypress, it's essential to start with the &lt;a href="https://docs.cypress.io/guides/references/experiments" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;. Staying updated with new releases and reading release notes can give you an edge by acquainting you with the latest experimental features. I highly recommend exploring these &lt;strong&gt;notable&lt;/strong&gt; features, but remember to always refer back to the documentation for the most current information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;experimentalMemoryManagement&lt;/code&gt; - enhances memory management for &lt;strong&gt;Chromium-based browsers&lt;/strong&gt;, potentially improving performance and stability.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;experimentalCspAllowList&lt;/code&gt; - allows you to specify which &lt;em&gt;Content-Security-Policy&lt;/em&gt; directives are allowed during test runs, &lt;strong&gt;offering more control&lt;/strong&gt; over security settings.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;retries.experimentalStrategy&lt;/code&gt; - by enabling this, you can implement a tailored strategy for test retries based on &lt;em&gt;flake tolerance&lt;/em&gt;. Options include &lt;em&gt;detect-flake-but-always-fail&lt;/em&gt; or &lt;em&gt;detect-flake-and-pass-on-threshold&lt;/em&gt;, providing flexibility in &lt;strong&gt;handling test flakiness&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;retries.experimentalOptions&lt;/code&gt; - lets you set specific options for your chosen retries strategy, such as &lt;em&gt;maxRetries&lt;/em&gt;, &lt;em&gt;passesRequired&lt;/em&gt;, and &lt;em&gt;stopIfAnyPassed&lt;/em&gt;, allowing for &lt;strong&gt;more nuanced control&lt;/strong&gt; over test retries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use these experimental features, you need to configure them in your &lt;code&gt;cypress.config.js&lt;/code&gt; file. For instance, to enable a particular feature, you would add the relevant configuration entries like this: &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cypress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;experimentalMemoryManagement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;experimentalCspAllowList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;experimentalStrategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;detect-flake-and-pass-on-threshold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;experimentalOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;maxRetries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;passesRequired&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;openMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;runMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;blockquote&gt;
&lt;p&gt;⚠️ Remember, experimental features might &lt;strong&gt;change&lt;/strong&gt; or ultimately be &lt;strong&gt;removed&lt;/strong&gt; without making it into the core product. So use them with &lt;strong&gt;caution&lt;/strong&gt; and stay informed about their status and updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Asserting DOM elements with &lt;code&gt;.should('exist')&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A quick GitHub search for the &lt;code&gt;.should('exist')&lt;/code&gt; assertion reveals its presence in &lt;strong&gt;over 49,000 files&lt;/strong&gt;. While some of these instances are legitimately used for non-DOM element assertions, a significant number are applied to DOM commands, where their necessity is &lt;strong&gt;debatable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&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%2Fwdeog7zs5zq7i76bgl2s.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%2Fwdeog7zs5zq7i76bgl2s.png" alt="github search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's important to note that Cypress inherently &lt;strong&gt;waits&lt;/strong&gt; for DOM commands to become present in the DOM. This automatic waiting mechanism means that explicitly writing &lt;code&gt;.should('exist')&lt;/code&gt; for DOM element verification is &lt;strong&gt;often redundant&lt;/strong&gt;. By understanding this built-in feature of Cypress, you can streamline your tests by omitting unnecessary assertions, leading to &lt;strong&gt;cleaner&lt;/strong&gt; and more &lt;strong&gt;efficient&lt;/strong&gt; tests.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;❌&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;✅&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  6. Not setting up ESLint
&lt;/h2&gt;

&lt;p&gt;From my experience, incorporating ESLint in all Cypress projects is not just a best practice, &lt;strong&gt;it's essential&lt;/strong&gt;. However, it's crucial to go beyond just the official &lt;a href="https://github.com/cypress-io/eslint-plugin-cypress/pulls" rel="noopener noreferrer"&gt;Cypress ESLint Plugin&lt;/a&gt;. I strongly recommend integrating additional plugins like &lt;a href="https://www.npmjs.com/package/eslint-plugin-chai-friendly" rel="noopener noreferrer"&gt;chai-friendly&lt;/a&gt; and &lt;a href="https://github.com/lo1tuma/eslint-plugin-mocha" rel="noopener noreferrer"&gt;mocha&lt;/a&gt; plugins to enhance your project's &lt;strong&gt;code quality&lt;/strong&gt; and &lt;strong&gt;maintainability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Starting with the recommended configurations is a wise choice for most projects. But don’t stop there. &lt;strong&gt;Dive into the documentation&lt;/strong&gt; and understand the full potential of these rules. Customize them to suit the specific needs of your project for optimal results. To give you a head start, here's the ESLint configuration file that I've &lt;strong&gt;successfully implemented&lt;/strong&gt; across various projects:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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;"root"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&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:mocha/recommended"&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:chai-friendly/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;"plugins"&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;"cypress"&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-assigning-return-values"&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-unnecessary-waiting"&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-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/no-async-tests"&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="nl"&gt;"cypress/unsafe-to-chain-command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"off"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mocha/no-mocha-arrows"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"off"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mocha/no-exclusive-tests"&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;"mocha/prefer-arrow-callback"&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="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;"env"&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/globals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;blockquote&gt;
&lt;p&gt;💡 It's kind of odd that the official Cypress docs don't make a big deal about setting up ESLint. It's super important for keeping your &lt;strong&gt;code clean&lt;/strong&gt; and making coding a smoother ride. In my &lt;a href="https://hackernoon.com/the-most-popular-cypress-packages-in-2023" rel="noopener noreferrer"&gt;last article&lt;/a&gt;, I pointed out that ESLint is the top dog in the Cypress world when it comes to downloads from NPM. That just shows how much people rely on it to keep their code in check. So, yeah, setting up ESLint in your Cypress projects? Definitely a good move.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7. Overusing &lt;code&gt;{ force: true }&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Yes, I know that the &lt;code&gt;{ force: true }&lt;/code&gt; is super handy when you just want to &lt;strong&gt;skip actionability checks&lt;/strong&gt; and get things done. But, hear me out – it's really worth it to act like a &lt;strong&gt;real user&lt;/strong&gt;. Doing the actual steps a user would take to interact with your application is key. Plus, when you force things, you might &lt;strong&gt;miss some real bugs&lt;/strong&gt;, because Cypress will breeze past a bunch of functional checks. That's exactly why I've got the &lt;code&gt;cypress/no-force&lt;/code&gt; rule set up in my ESLint config.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;❌&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;force&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;✅&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  8. Using &lt;code&gt;.then()&lt;/code&gt; to access fixture data and stub response
&lt;/h2&gt;

&lt;p&gt;I've noticed folks using &lt;code&gt;.then()&lt;/code&gt; for all sorts of stuff, but a lot of times, it's just &lt;strong&gt;not needed&lt;/strong&gt;. It's like using a fancy tool when a simple one will do the job. Sure, &lt;code&gt;.then()&lt;/code&gt; can be useful for many things, but when it comes to accessing fixture data or stubbing responses, sometimes keeping it straightforward is the way to go. Let's &lt;strong&gt;not overcomplicate things&lt;/strong&gt;. Less code is better, right?&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;❌&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;json&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;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;json&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;✅&lt;/span&gt;
&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/**&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;fixture&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&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;h2&gt;
  
  
  9. Avoiding &lt;code&gt;blockHosts&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;There's this super straightforward config option in Cypress – &lt;code&gt;blockHosts&lt;/code&gt;. I've noticed it's &lt;strong&gt;often ignored&lt;/strong&gt;, but it's actually pretty handy. All you gotta do is add the hosts you want to block to an array in your &lt;code&gt;cypress.config.js&lt;/code&gt; file. Here's how it goes:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cypress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;blockHosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.google-analytics.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.codesandbox.io&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.loom.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.youtube.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.github.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.googletagmanager.com&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="p"&gt;})&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you're not sure which host to block, the &lt;a href="https://nodejs.org/api/url.html#url_url_strings_and_url_objects" rel="noopener noreferrer"&gt;URL strings and URL objects&lt;/a&gt;  guide is a great place to start. It'll help you &lt;strong&gt;nail down the exact host&lt;/strong&gt; you're after.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Cypress blocks a request to a host you've listed, it automatically whips back a &lt;code&gt;503&lt;/code&gt; status code. Plus, it slaps on &lt;code&gt;a x-cypress-matched-blocked-host&lt;/code&gt; header, so you can easily tell which rule got hit. Neat, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&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%2Fjo2n9cpwzeu4u2r79g54.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%2Fjo2n9cpwzeu4u2r79g54.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Using the &lt;strong&gt;wrong&lt;/strong&gt; Docker image
&lt;/h2&gt;

&lt;p&gt;So, I've been noticing that a lot of projects use the &lt;code&gt;cypress/included&lt;/code&gt; docker image, which comes packed with a bunch of browsers and Cypress pre-installed. But here's the twist – they're &lt;strong&gt;not even testing against all those browsers&lt;/strong&gt;, and they don't really need Cypress installed &lt;strong&gt;globally&lt;/strong&gt;. Let's break down which image you actually need for your tests.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;image&lt;/th&gt;
&lt;th&gt;system deps&lt;/th&gt;
&lt;th&gt;cypress&lt;/th&gt;
&lt;th&gt;browsers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;cypress/factory&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❗️ (if specified)&lt;/td&gt;
&lt;td&gt;❗️ (if specified)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cypress/base&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cypress/browsers&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cypress/included&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most of the time, you just need the image with Node, system dependencies, and the &lt;strong&gt;browser you're testing with&lt;/strong&gt;. No need to pull all the browsers. Like, if you're only testing in Chrome, &lt;code&gt;cypress/browsers&lt;/code&gt; is your go-to. Want to build a custom image? &lt;code&gt;cypress/factory&lt;/code&gt; is great for picking the exact versions you want. If you've got browsers installed already or want to add them yourself, &lt;code&gt;cypress/base&lt;/code&gt; is all about those system dependencies. And if you're into the whole all-inclusive vibe, &lt;code&gt;cypress/included&lt;/code&gt; has got you covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cypress is a great and powerful framework for testing, but it's the little things that count. Remember the insights on &lt;code&gt;.then()&lt;/code&gt; vs &lt;code&gt;.should()&lt;/code&gt;, using the &lt;strong&gt;right Docker image&lt;/strong&gt;, and &lt;strong&gt;setting up ESLint&lt;/strong&gt;. Avoid common traps like overusing &lt;code&gt;{ force: true }&lt;/code&gt; and &lt;strong&gt;unnecessary assertions&lt;/strong&gt;. This article aimed to give you the lowdown on these key details to sharpen your Cypress skills.&lt;/p&gt;

&lt;p&gt;Hope you found some helpful nuggets here. Happy testing with Cypress!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow me on &lt;a href="https://github.com/elaichenkov" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://twitter.com/elaichenkov" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>javascript</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Manage Your Cypress Logs Like a Pro</title>
      <dc:creator>Yevhen Laichenkov</dc:creator>
      <pubDate>Thu, 21 Dec 2023 21:55:54 +0000</pubDate>
      <link>https://dev.to/elaichenkov/manage-your-cypress-logs-like-a-pro-23dc</link>
      <guid>https://dev.to/elaichenkov/manage-your-cypress-logs-like-a-pro-23dc</guid>
      <description>&lt;p&gt;&lt;strong&gt;Cypress&lt;/strong&gt; has emerged as a fast, easy-to-use, and reliable testing framework, greatly simplifying the process of end-to-end testing for web applications. However, despite its numerous benefits, it's not without its limitations, especially when it comes to logging.&lt;/p&gt;

&lt;p&gt;So, &lt;strong&gt;one notable limitation&lt;/strong&gt; is the behavior of the &lt;code&gt;cy.log()&lt;/code&gt; command. In its default state, &lt;code&gt;cy.log()&lt;/code&gt; only prints log messages in the Cypress Runner UI. Meanwhile, if you need to print in the terminal then this requires extra work and also may become a problem by adding extra complexity to your codebase.&lt;/p&gt;

&lt;p&gt;Hence, if you want to print a message in the terminal then you have to create an additional function and add it to a task's object in the configuration file and only after that you can invoke the added task in your tests and see the message in the command line. This might sound crazy to some people, but &lt;strong&gt;that is how it works now&lt;/strong&gt;. So, it would be quite a challenge for new users.&lt;/p&gt;

&lt;p&gt;Therefore, I've decided to develop the &lt;a href="https://github.com/elaichenkov/cypress-log" rel="noopener noreferrer"&gt;cypress-log&lt;/a&gt; plugin that will &lt;strong&gt;handle under the hood all logic&lt;/strong&gt; where to print the message. So, you don't need to think about what to invoke &lt;code&gt;cy.log()&lt;/code&gt; or &lt;code&gt;cy.task('log')&lt;/code&gt;. Just simply use the same native command &lt;code&gt;cy.log()&lt;/code&gt; with the &lt;a href="https://github.com/elaichenkov/cypress-log" rel="noopener noreferrer"&gt;cypress-log&lt;/a&gt; plugin that will &lt;strong&gt;override the default behavior&lt;/strong&gt; and it will print a log message in the environment where it was running. &lt;/p&gt;

&lt;p&gt;To install the &lt;a href="https://github.com/elaichenkov/cypress-log" rel="noopener noreferrer"&gt;cypress-log&lt;/a&gt; library you need to run the following command in your terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; cypress-log


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After that, you need to integrate the plugin into your Cypress project. In your &lt;code&gt;cypress/support/e2e.js&lt;/code&gt; file, add the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cypress-log&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;Last but not least, you will need to add the &lt;code&gt;log&lt;/code&gt; task to your &lt;code&gt;cypress.config.js&lt;/code&gt; configuration file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// import the 'log' function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cypress-log/log.task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;e2e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setupNodeEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// add the 'log' function to the object&lt;/span&gt;
      &lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;task&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;log&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;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then you can use the &lt;code&gt;cy.log()&lt;/code&gt; method as you have used it before. For instance, by running the following test:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prints to the console&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;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, World!&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nested&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prop&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;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;another message&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;three&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;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will see the following in the &lt;strong&gt;interactive mode&lt;/strong&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%2Fxklvqxlnr56c7xwxer93.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%2Fxklvqxlnr56c7xwxer93.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But if you run the test in the &lt;strong&gt;non-interactive mode&lt;/strong&gt; then you will see the following in your terminal:&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%2Fiffjzb6sudrh794cygzo.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%2Fiffjzb6sudrh794cygzo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow me on &lt;a href="https://github.com/elaichenkov" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://twitter.com/elaichenkov" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
