<?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: Mike Cataldo</title>
    <description>The latest articles on DEV Community by Mike Cataldo (@mccataldo).</description>
    <link>https://dev.to/mccataldo</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%2F207553%2F4a5c432d-1be3-4989-8440-eeb84aaaa401.jpg</url>
      <title>DEV Community: Mike Cataldo</title>
      <link>https://dev.to/mccataldo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mccataldo"/>
    <language>en</language>
    <item>
      <title>Cypress Tip: Don't Overuse the Visibility Assertion</title>
      <dc:creator>Mike Cataldo</dc:creator>
      <pubDate>Fri, 26 Feb 2021 18:10:18 +0000</pubDate>
      <link>https://dev.to/mccataldo/cypress-tip-don-t-overuse-the-visibility-assertion-3b2e</link>
      <guid>https://dev.to/mccataldo/cypress-tip-don-t-overuse-the-visibility-assertion-3b2e</guid>
      <description>&lt;p&gt;&lt;a href="https://www.cypress.io/"&gt;Cypress&lt;/a&gt; makes &lt;a href="https://docs.cypress.io/guides/references/assertions.html"&gt;assertions&lt;/a&gt; easy with the &lt;a href="https://docs.cypress.io/api/commands/should.html"&gt;&lt;code&gt;should&lt;/code&gt;&lt;/a&gt; command and an intuitive way to leverage the ubiquitous &lt;a href="https://www.chaijs.com/"&gt;Chai&lt;/a&gt; assertion library. &lt;/p&gt;

&lt;p&gt;Let's say, for example, that our application is the &lt;a href="https://github.com/cypress-io/cypress-realworld-app"&gt;Real World App&lt;/a&gt; and we need to assert that upon navigating to Home the avatar at the top left is visible. We could write the test like this:&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="s1"&gt;Home&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;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sign in and navigate to Home&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="c1"&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="s1"&gt;see avatar&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="kd"&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;#avatar&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;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;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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is 🔥 fine, but on multiple occasions, I've seen an overuse of this visibility assertion. For example, when filling out a form field, you might assert visibility between the query and the action like this:&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="s1"&gt;Sign In&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;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navigate to Sign In&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="c1"&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="s1"&gt;sign in&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="kd"&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;#username&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;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;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="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iheartjs&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="kd"&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;#password&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;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;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="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&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="kd"&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#sign-in&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;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;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="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&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;It makes sense why we might do this: to avoid interacting with an element before it's visible. However, this is usually unnecessary and could be considered bad practice. &lt;/p&gt;

&lt;p&gt;First, it's unnecessary because of two implicit behaviors of Cypress: &lt;a href="https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Actionability"&gt;actionability&lt;/a&gt; assertions and command &lt;a href="https://docs.cypress.io/guides/core-concepts/retry-ability.html"&gt;retry-ability&lt;/a&gt;. Cypress will not attempt to perform certain actions on an element unless it's visible. If it isn't visible, Cypress repeatedly retries this assertion until either the assertion passes and the next command is executed or the timeout is reached and it fails.&lt;br&gt;
Now the test can be written this way:&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="s1"&gt;Sign In&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;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navigate to Sign In&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="c1"&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="s1"&gt;sign in&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="kd"&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;#username&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;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iheartjs&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="kd"&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;#password&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;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&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="kd"&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#sign-in&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;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&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;Not only is there less code to manage, but now there's less noise in the &lt;a href="https://docs.cypress.io/guides/core-concepts/test-runner.html#Command-Log"&gt;Command Log&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;To be clear, we're assuming that the example is not a component test; and while we want to ensure that a user is able to sign in by filling in the fields and clicking a button, we have other tests to ensure form components work as intended. In that vein, it could also be considered bad practice to assert visibility even if it were necessary for a working test. &lt;br&gt;
The alternative? Assert visibility using the &lt;a href="https://api.jquery.com/visible-selector/"&gt;&lt;code&gt;:visible&lt;/code&gt;&lt;/a&gt; selector (jQuery's extension to native &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes"&gt;CSS pseudo-classes&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;When you run the iteration below, Cypress will only perform the action on the element until it's visible.&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="s1"&gt;Sign In&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;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navigate to Sign In&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="c1"&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="s1"&gt;sign in&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="kd"&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;#username: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="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iheartjs&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="kd"&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;#password: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="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&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="kd"&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#sign-in: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="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&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;While this isn't necessary in cases like this, in the real world, you might run into a situation where you need to make the assertion solely for the purpose of test resiliency or debuggability.&lt;/p&gt;

&lt;p&gt;In addition to visibility, there are several other &lt;a href="https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Default-Assertions"&gt;default assertions&lt;/a&gt; - like ensuring the element is not disabled - that Cypress makes to determine &lt;a href="https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Actionability"&gt;actionability&lt;/a&gt;. Check out the Cypress docs for more in-depth content.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>cypress</category>
    </item>
    <item>
      <title>Cypress Tip: Get the Cypress Dashboard App
</title>
      <dc:creator>Mike Cataldo</dc:creator>
      <pubDate>Wed, 03 Feb 2021 17:04:36 +0000</pubDate>
      <link>https://dev.to/iheartjs/cypress-tip-get-the-cypress-dashboard-app-16og</link>
      <guid>https://dev.to/iheartjs/cypress-tip-get-the-cypress-dashboard-app-16og</guid>
      <description>&lt;p&gt;If you're familiar with the &lt;a href="https://www.cypress.io/dashboard"&gt;Cypress Dashboard&lt;/a&gt;, you might immediately suspect that I'm clickbaiting you, but stay with me!&lt;/p&gt;

&lt;p&gt;In Chrome, &lt;a href="https://support.google.com/chrome_webstore/answer/3060053?hl=en"&gt;there's a way&lt;/a&gt; to add shortcuts to ordinary sites (like dashboard.cypress.io) as "apps". Firefox calls these "site-specific browsers" but sadly they're &lt;a href="https://9to5google.com/2021/01/27/firefox-discontinues-work-pwa-desktop/"&gt;dropping&lt;/a&gt; SSB and PWA support, while other Chromium-based browsers are making it more of a mainstay. Edge on Windows supports this feature and will &lt;a href="https://9to5google.com/2020/12/23/chrome-windows-web-app-uninstall-integration/"&gt;soon&lt;/a&gt; allow you to manage/uninstall those apps just like native ones. &lt;/p&gt;

&lt;p&gt;Why would we do this? If you're like me, you check on runs frequently throughout the day. You also have a lot of apps and Chrome tabs - like the dashboard - open (because you're uber-productive). Hunting around for the dashboard either takes longer than it should or you have to navigate there every time.&lt;/p&gt;

&lt;p&gt;Do this now (trust me): &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open the Cypress Dashboard in Chrome&lt;/li&gt;
&lt;li&gt; At the top right, click More (⋮) &lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;More Tools&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Click  &lt;strong&gt;Create shortcut&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Input &lt;strong&gt;Cypress Dashboard&lt;/strong&gt; as the name for the shortcut&lt;/li&gt;
&lt;li&gt;Check the &lt;strong&gt;Open as window&lt;/strong&gt; checkbox&lt;/li&gt;
&lt;li&gt;Click  &lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now getting to the Cypress Dashboard is as easy as opening and switching apps!&lt;/p&gt;

&lt;p&gt;If you're not familiar with the Dashboard or if you haven't used it in a while, I suggest giving it a try - at least on the free tier. Check out the  &lt;a href="https://docs.cypress.io/faq/questions/dashboard-faq.html"&gt;FAQ&lt;/a&gt; if you have a question. Cypress has been making a ton of improvements on it as of late (and  &lt;a href="https://portal.productboard.com/cypress-io/1-cypress-dashboard/tabs/1-under-consideration"&gt;more&lt;/a&gt; on the way), so it's a worthy investment. I love it!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Cypress Tip: In-Spec Functions</title>
      <dc:creator>Mike Cataldo</dc:creator>
      <pubDate>Wed, 03 Feb 2021 17:00:04 +0000</pubDate>
      <link>https://dev.to/iheartjs/cypress-tip-in-spec-functions-1570</link>
      <guid>https://dev.to/iheartjs/cypress-tip-in-spec-functions-1570</guid>
      <description>&lt;p&gt;Let's imagine you have a bunch of repeatable code in your tests:&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;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;should do this thing&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="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;#thisElement&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$el&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;// some unusual hackery here&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&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="s1"&gt;should do that thing&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="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;#thatElement&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$el&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;// some unusual hackery here&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&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="s1"&gt;should do another thing&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="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;#anotherElement&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$el&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;// some unusual hackery here&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What a mess, right? You might be tempted to immediately break this out into a custom command...&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;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;should do this thing&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="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;#thisElement&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;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but it's not necessarily the best solution for a number of reasons. The alternative? I'm calling it an &lt;strong&gt;in-spec function&lt;/strong&gt;. It's an abstraction in the form of a hoisted function contained in the spec file:&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="s1"&gt;some feature&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="s1"&gt;should do this thing&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="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;#thisElement&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// some unusual hackery here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's why you might want to use an in-spec function: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Like an abstraction into a custom command, this will make your tests much easier to reason about, but if it's only required in a single spec, why bother with a command when you can use plain JavaScript?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's hoisted from the bottom so that it's out of the way, but because it's in the spec, it's easier to access in the event you need to debug, update or refactor it. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you need this function outside the spec, it's likely easier to prototype it as an in-spec function first. Then when it's working the way you want, you can convert it to a command.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Taking Control of Your Cypress Test Runs With Tags</title>
      <dc:creator>Mike Cataldo</dc:creator>
      <pubDate>Fri, 29 May 2020 18:48:41 +0000</pubDate>
      <link>https://dev.to/mccataldo/taking-control-of-your-cypress-test-runs-with-tags-59ao</link>
      <guid>https://dev.to/mccataldo/taking-control-of-your-cypress-test-runs-with-tags-59ao</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.cypress.io/"&gt;Cypress&lt;/a&gt; is a phenomenal end-to-end testing tool. It's certainly not perfect but it's being &lt;a href="https://docs.cypress.io/guides/references/changelog.html"&gt;updated consistently&lt;/a&gt; and it's expandable with &lt;a href="https://docs.cypress.io/plugins/index.html"&gt;plugins&lt;/a&gt;. I recently came upon a problem that required more granular control over my test runs than Cypress provides out of the box. Using our imagination, we'll take a similar journey to what I believe is a sweet solution to a problem you'll likely have. Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Imagine you have a great set of Cypress tests for your calculator app, perfectly organized by feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cypress
└───integration
│   └───add
│   │   │   add.spec.js
│   └───subtract
│   │   │   subtract.spec.js
│   └───multiply
│   │   │   multiply.spec.js
│   └───divide
│   │   │   divide.spec.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within each of these spec files are several tests:&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="c1"&gt;// add.spec.js&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="s1"&gt;add two numbers&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="p"&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="s1"&gt;add three fractions&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="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="c1"&gt;// subtract.spec.js&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="s1"&gt;subtract a negative number from a positive number&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="p"&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="s1"&gt;subtract two whole numbers&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="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 get the idea.&lt;/p&gt;

&lt;p&gt;The time it takes to test your calculator app end-to-end with Cypress is a lot longer than your unit tests take so you run them nightly. In an effort to catch bugs sooner, you and your team have determined that a certain set of tests need to be executed as part of your &lt;a href="https://martinfowler.com/articles/continuousIntegration.html"&gt;continuous integration&lt;/a&gt; pipeline. What's the best way to implement this?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;You figure out your best course of action through an iterative process:&lt;/p&gt;

&lt;h3&gt;
  
  
  Good Solution - Separating Tests
&lt;/h3&gt;

&lt;p&gt;First, you create &lt;code&gt;important-tests.spec.js&lt;/code&gt; and move all the relevant tests into that file. You considered copying the tests but didn't want the hassle of keeping them in sync.&lt;br&gt;
Then you run Cypress like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx cypress run &lt;span class="nt"&gt;--spec&lt;/span&gt; &lt;span class="s1"&gt;'path/to/important-tests.spec.js'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy enough, but you soon find out that maintenance is tricky because you now have double the number of files for each feature you need to maintain tests for. While this solution works, the additional complexity and cognitive load are too significant to scale effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better Solution - Tagging Tests
&lt;/h3&gt;

&lt;p&gt;You discover a great plugin &lt;a href="https://github.com/bahmutov/cypress-select-tests"&gt;&lt;code&gt;cypress-select-tests&lt;/code&gt;&lt;/a&gt; developed by Cypress' own &lt;a href="https://glebbahmutov.com/"&gt;Gleb Bahmutov&lt;/a&gt;, that provides a way to select or &lt;code&gt;grep&lt;/code&gt; the specific tests you want to run. &lt;/p&gt;

&lt;h4&gt;
  
  
  Setup
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Install:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; cypress-select-tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update your &lt;code&gt;plugins/index.js&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&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="nx"&gt;selectTestsWithGrep&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cypress-select-tests/grep&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&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="o"&gt;=&amp;gt;&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;file:preprocessor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;selectTestsWithGrep&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now running tests like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx cypress run &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'fraction'&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will execute only tests that contain &lt;code&gt;fraction&lt;/code&gt; in the title. Sweet!&lt;/p&gt;

&lt;h4&gt;
  
  
  Tagging
&lt;/h4&gt;

&lt;p&gt;The tests that need to run in CI are titled,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;add three fractions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subtract two whole numbers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;divide by zero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subtract fractions&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You ask yourself,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What search term will result in only these tests running?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and find that there aren't any, so you toy around with the idea of adding one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ci divide by zero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;important: divide by zero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;divide by zero, important&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;divide by zero, #important&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Settling on the last format makes sense to you because it's not ambiguous, it's out of the way and, and most importantly, it's &lt;em&gt;distinguishable&lt;/em&gt; from the other text, which reduces the risk that it'll be casually edited or a test that happens to have the term &lt;code&gt;important&lt;/code&gt; in it won't be included in the run unintentionally. Phew!&lt;/p&gt;

&lt;h3&gt;
  
  
  Finally
&lt;/h3&gt;

&lt;p&gt;Finally, running Cypress like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx cypress run &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#important"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;results in a run - containing really important tests - that can be added to your pipeline so you can find critical bugs sooner without adding significant complexity to your workflow.&lt;/p&gt;

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

&lt;p&gt;Many thanks to &lt;a href="https://glebbahmutov.com/blog"&gt;Gleb Bahmutov&lt;/a&gt; for his work on &lt;code&gt;cypress-select-tests&lt;/code&gt;. I hope this was helpful to you! &lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
    </item>
    <item>
      <title>Cypress 4.6.0 is Out...And Brings a Surprise New Feature!</title>
      <dc:creator>Mike Cataldo</dc:creator>
      <pubDate>Fri, 22 May 2020 17:21:38 +0000</pubDate>
      <link>https://dev.to/mccataldo/cypress-4-6-0-is-out-and-brings-a-surprise-new-feature-48ll</link>
      <guid>https://dev.to/mccataldo/cypress-4-6-0-is-out-and-brings-a-surprise-new-feature-48ll</guid>
      <description>&lt;p&gt;The &lt;a href="https://www.cypress.io/about"&gt;Cypress team&lt;/a&gt; is still hard at work (per usual), bringing us regular releases. The latest iteration of Cypress (4.6.0) is out, and with it comes a surprising feature. It's something that I always wanted but didn't think was even possible, so I never asked for it or tried to build it out myself.&lt;/p&gt;

&lt;p&gt;I'll give it to you straight from their &lt;a href="https://docs.cypress.io/guides/references/changelog.html#4-6-0"&gt;Changelog&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://docs.cypress.io/guides/guides/debugging.html#Errors"&gt;Errors&lt;/a&gt; in the Test Runner now display a code frame to preview where the failure occurred with the relevant file, line number, and column number highlighted. Clicking on the file link will open the file in your preferred file opener and highlight the line and column in editors that support it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So imagine for a moment the test runner shows a test failed at the &lt;code&gt;cy.get()&lt;/code&gt; command, perhaps because you got the selector wrong. It happens to the best of us. Below the usual stack trace and message, &lt;code&gt;Timed out retrying: Expected to find element: #login, but never found it.&lt;/code&gt;, is a &lt;a href="https://github.com/babel/babel/tree/master/packages/babel-code-frame"&gt;code frame&lt;/a&gt; which shows the line in your spec containing the failing command and a couple of lines of surrounding code for context. That's cute. At this point you'd have to go back to your editor and find the file and line where the failure occurred so you can start fixing it. But - at the top of the code frame is the relative path to the spec file (that you created in VSCode). And - here's the best part - clicking on that file opens it in VSCode with the offending line highlighted and your cursor in the precise spot where you need to make the correction. Pretty sweet, right? &lt;/p&gt;

&lt;p&gt;Here it is in action:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qLHO413y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://docs.cypress.io/img/guides/file-opener-ide-go-to-line.3cc1a2e4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qLHO413y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://docs.cypress.io/img/guides/file-opener-ide-go-to-line.3cc1a2e4.gif" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://github.com/cypress-io/cypress/issues/3762"&gt;issue&lt;/a&gt; was created over a year ago, so completion of this is a testament to the diligence of the Cypress team in delivering an amazing, ever-evolving product. &lt;/p&gt;

&lt;p&gt;In addition to regular updates, Cypress also comes with outstanding documentation if you want instructions to set up the &lt;a href="https://docs.cypress.io/guides/tooling/IDE-integration.html#File-Opener-Preference"&gt;File Opener Preference&lt;/a&gt; or how Cypress &lt;a href="https://docs.cypress.io/guides/guides/debugging.html#Errors"&gt;Errors&lt;/a&gt; work in general. &lt;/p&gt;

&lt;p&gt;Enjoy this new feature and be sure to &lt;a href="https://twitter.com/Cypress_io"&gt;share your feedback with the Cypress team&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Static Analysis: What Is It and Why Is It Important?</title>
      <dc:creator>Mike Cataldo</dc:creator>
      <pubDate>Wed, 20 May 2020 21:27:02 +0000</pubDate>
      <link>https://dev.to/mccataldo/static-analysis-254d</link>
      <guid>https://dev.to/mccataldo/static-analysis-254d</guid>
      <description>&lt;p&gt;You're likely familiar with the concept of a code review: scrutinizing code by visual inspection, without the assistance of automated tools. You know manual processes are prone to human error and you'd jump at the opportunity to automate some of that process if you could, right? Enter static analysis:&lt;/p&gt;

&lt;p&gt;In short, static analysis can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provide an understanding of the code structure&lt;/li&gt;
&lt;li&gt;help to ensure that the code adheres to a set of standards&lt;/li&gt;
&lt;li&gt;and reveal errors that don't manifest themselves until disaster strikes

&lt;ul&gt;
&lt;li&gt;which could be weeks, months or years post-release&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Static Analysis &amp;amp; Tooling
&lt;/h2&gt;

&lt;p&gt;Automated tools can assist developers in carrying out different types of static analysis, loosely defined as &lt;strong&gt;linting&lt;/strong&gt;, &lt;strong&gt;formatting&lt;/strong&gt; and &lt;strong&gt;type-checking&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linting - ESLint
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  High-level Overview
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;ESLint statically analyzes your code to quickly find problems

&lt;ul&gt;
&lt;li&gt;it's built into most editors like VSCode&lt;/li&gt;
&lt;li&gt;it can be run as part of a continuous integration pipeline&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Some problems are &lt;strong&gt;fixed automatically&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;fixes are &lt;em&gt;syntax-aware&lt;/em&gt; 

&lt;ul&gt;
&lt;li&gt;you won't experience errors introduced by traditional find-and-replace algorithms&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;And it's customizable to work exactly the way you need it for your project

&lt;ul&gt;
&lt;li&gt;you can write your own rules that work alongside ESLint's built-in rules&lt;/li&gt;
&lt;li&gt;there are plenty of valuable plugins (rulesets written by others) to save you time &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Given this single line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var foo = bar;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ESLint would output the following messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1:5 - 'foo' is assigned a value but never used. (no-unused-vars)
1:11 - 'bar' is not defined. (no-undef)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That output is a product of the recommended configuration which enforces rules &lt;a href="https://eslint.org/docs/rules/no-unused-vars"&gt;no-unused-vars&lt;/a&gt; and &lt;a href="https://eslint.org/docs/rules/no-undef"&gt;no-undef&lt;/a&gt; (along with &lt;a href="https://eslint.org/docs/rules/"&gt;many others&lt;/a&gt;) that can be reconfigured to show a warning instead of an error or even be turned off completely.&lt;/p&gt;

&lt;p&gt;Beyond initial setup and configuration, linting your entire codebase is easy:&lt;br&gt;
&lt;code&gt;$ npx eslint .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To lint React &lt;code&gt;jsx&lt;/code&gt; files:&lt;br&gt;
&lt;code&gt;$ npx eslint --ext .jsx .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ESLint can be used to enforce standards around formatting with very fine control - down to the character. Even the whitespace around your code can be scrutinized! Other more opinionated formatting tools are designed to avoid this sort of &lt;a href="https://en.wikipedia.org/wiki/Law_of_triviality"&gt;bike-shedding&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Code Formatting - Prettier
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://prettier.io/"&gt;Prettier&lt;/a&gt; reformats your code in a way that's more readable and consistent. While being a stickler for code style can seem unfruitful, there are some hidden code-quality gems to be found. Here's an example:&lt;/p&gt;
&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const a = false
const b = false
const c = true
const d = a &amp;amp;&amp;amp; b || c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you don’t remember the order of operations of &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; - or you don’t trust that all developers on the team do - in order to get the value of d, then a bug could get introduced when this get refactored.&lt;/p&gt;

&lt;p&gt;Formatting the code with Prettier results in this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const a = false
const b = false
const c = true
const d = (a &amp;amp;&amp;amp; b) || c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extra parentheses are helpful even if you do know the order of operations. If by chance you realize that wasn’t your intention, you can add the parentheses yourself and Prettier will leave it that way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const a = false
const b = false
const c = true
const d = a &amp;amp;&amp;amp; (b || c)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code formatting can make the intent of your code more obvious, reducing cognitive load on the developer reviewing or refactoring the code.&lt;/p&gt;

&lt;p&gt;By design, Prettier configuration is limited. This delegation is at the cost of finer control over formatting which can be achieved by using ESLint instead to format your code. &lt;/p&gt;

&lt;h3&gt;
  
  
  Type-checking - TypeScript
&lt;/h3&gt;

&lt;p&gt;Trying to invoke an object that’s not a function results (unsurprisingly) in an error like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;x is not a function&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However this happens at &lt;em&gt;execution&lt;/em&gt; time. &lt;/p&gt;

&lt;p&gt;A static type checker allows you to specify what data type a variable is to ensure - at &lt;em&gt;compile&lt;/em&gt; time - that it’s being used properly by adding syntax to JavaScript to follow that variable through the code.&lt;/p&gt;

&lt;p&gt;You might be saying to yourself, &lt;em&gt;but JavaScript is not a compiled language!&lt;/em&gt; - and you'd be right! But &lt;a href="https://www.typescriptlang.org"&gt;TypeScript&lt;/a&gt;'s compiler can be used to type-check your code - whether it's TypeScript or JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;This code contains a bug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getFullName(customer) {
  const {
    name: {first, middle, last},
  } = customer
  return [first, middle, last].filter(Boolean).join(' ')
}
getFullName({first: 'John', middle: 'A', last: 'Smith'})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding type-checking helps us find the bug automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Customer = {
  name: {
    first: string,
    middle: string,
    last: string,
  },
}
function getFullName(user: Customer): string {
  const {
    name: {first, middle, last},
  } = customer
  return [first, middle, last].filter(Boolean).join(' ')
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the output:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
Argument of type '{ first: string; middle: string; last: string; }' is not assignable to parameter of type 'Customer'.2  Object literal may only specify known properties, and 'first' does not exist in type 'Customer'.(0123)&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Type-checking can be adopted incrementally: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;with Babel

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://babeljs.io/docs/en/babel-preset-typescript"&gt;babel-preset-typescript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;with a &lt;a href="https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc"&gt;supported subset&lt;/a&gt; of &lt;a href="https://jsdoc.app/about-getting-started.html"&gt;JSDoc&lt;/a&gt; annotations

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html"&gt;Type Checking JavaScript Files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Static analysis should be an arrow in every JavaScript developer's quiver. In addition to manual and automated testing, it will give you more confidence that you're shipping quality code. &lt;/p&gt;

</description>
      <category>linting</category>
      <category>eslint</category>
      <category>typescript</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
