<?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: Ben Newton</title>
    <description>The latest articles on DEV Community by Ben Newton (@benenewton).</description>
    <link>https://dev.to/benenewton</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%2F28163%2F9a3e24ed-cd4b-4602-ab79-21718c537434.jpg</url>
      <title>DEV Community: Ben Newton</title>
      <link>https://dev.to/benenewton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benenewton"/>
    <language>en</language>
    <item>
      <title>How Voice Input Transformed My Solo Development Workflow</title>
      <dc:creator>Ben Newton</dc:creator>
      <pubDate>Mon, 04 Aug 2025 03:16:53 +0000</pubDate>
      <link>https://dev.to/benenewton/how-voice-input-transformed-my-solo-development-workflow-371b</link>
      <guid>https://dev.to/benenewton/how-voice-input-transformed-my-solo-development-workflow-371b</guid>
      <description>&lt;p&gt;I've been developing software for almost 3 decades, and I've lost count of how many brilliant ideas vanished between conception and keyboard. You know the feeling – that perfect solution hits you in the shower, during a run, or right as you're falling asleep.&lt;/p&gt;

&lt;p&gt;Last month, I started dogfooding my own tool – VoiceCommit – to create GitHub issues directly from voice. The results surprised me: &lt;strong&gt;I've created 20+ actionable GitHub issues&lt;/strong&gt; from ideas that would have 100% disappeared within minutes.&lt;/p&gt;

&lt;p&gt;Here's the truth: &lt;strong&gt;It's not about saving time. It's about saving ideas.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Ideas That Actually Make It To GitHub
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Old Reality&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have idea while walking → "I'll remember this" → Open laptop 2 hours later → What was that idea again?&lt;/li&gt;
&lt;li&gt;Success rate: Maybe 1 in 10 ideas survived&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The New Reality&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have idea → Pull out phone → 30-second voice note → GitHub issue exists&lt;/li&gt;
&lt;li&gt;Success rate: 10 out of 10 ideas captured&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last Saturday night at 9:57 PM, I had a flash of inspiration about adding social sharing to VoiceCommit. In bed, no laptop nearby. I grabbed my phone and said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I want to add a social piece to VoiceCommit that allows users to share what they said and the PR or Issue that was created. The output should be text for the voice entry and an image of the PR."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By Sunday morning, this detailed GitHub issue was waiting for me. &lt;strong&gt;Without voice input, this idea had a 0% chance of survival.&lt;/strong&gt; I know because I've lost hundreds just like it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Bug Reports With Actual Context (Not "Thing Broken")
&lt;/h2&gt;

&lt;p&gt;We've all been there. You find a bug on mobile, make a mental note, then later create an issue titled "Login redirect issue" with no other context. Future you hates past you.&lt;/p&gt;

&lt;p&gt;Here's what I actually captured at 11:00 PM on a Thursday:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Login page is doing this weird double-redirect thing. User clicks login, goes to auth provider, comes back, then redirects again to dashboard. Feels like we're handling the auth state twice. Need to check the useEffect in AuthProvider component."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The difference isn't time saved – it's context preserved.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Without voice: "Fix login redirect" (useless)&lt;br&gt;&lt;br&gt;
With voice: Full reproduction steps, hypothesis, and where to look&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Feature Ideas With The "Why" Still Fresh
&lt;/h2&gt;

&lt;p&gt;Here's my favorite example. One simple sentence while walking my dog:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I have an idea for my blog. I want to add a feature where a progress bar shows across the top of a post's page and as you scroll, the progress bar advances."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Twenty seconds of speaking preserved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What I wanted (progress bar)&lt;/li&gt;
&lt;li&gt;Where it goes (top of page)
&lt;/li&gt;
&lt;li&gt;How it behaves (advances with scroll)&lt;/li&gt;
&lt;li&gt;The context (blog posts specifically)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The magic&lt;/strong&gt;: I spoke this naturally, including details I wouldn't have remembered to type later. The full context was preserved because I was describing what I was visualizing in that moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Mobile UX Issues Captured Where They Happen
&lt;/h2&gt;

&lt;p&gt;Testing on your phone, notice something broken, and... what? Switch to laptop? Email yourself? &lt;/p&gt;

&lt;p&gt;I caught this at 10:20 PM while browsing on my iPhone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The mobile navigation needs a hamburger menu that slides out from the left. Current tabs are too cramped on iPhone SE. Should use CSS transforms for smooth animation, maybe 300ms duration."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn't faster than typing on a laptop. &lt;strong&gt;But I wasn't at my laptop.&lt;/strong&gt; This idea would have evaporated by morning. Instead, it became a proper GitHub issue with implementation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Meta Development: Building The Tool With The Tool
&lt;/h2&gt;

&lt;p&gt;The ultimate dogfooding – I've created 12 VoiceCommit features using VoiceCommit itself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Make VoiceCommit a PWA so I can add it to home screen"&lt;/li&gt;
&lt;li&gt;"Add pictures to voice commands and have AI analyze them"&lt;/li&gt;
&lt;li&gt;"Create a blog post about using VoiceCommit to build VoiceCommit"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these was captured in the moment of inspiration, not reconstructed later from memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Talk About "Time Saved"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I'm not saving time. I'm saving ideas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional time comparison:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing a GitHub issue: 5 minutes&lt;/li&gt;
&lt;li&gt;Voice recording + AI processing: 1 minute
&lt;/li&gt;
&lt;li&gt;"Time saved": 4 minutes ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real comparison:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ideas that make it to GitHub without voice: 10%&lt;/li&gt;
&lt;li&gt;Ideas that make it to GitHub with voice: 90%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ideas saved&lt;/strong&gt;: 80% ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Data: 14 Days of Voice-First Development
&lt;/h2&gt;

&lt;p&gt;From my actual VoiceCommit database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;20+ voice submissions&lt;/strong&gt; → 20+ GitHub issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capture locations&lt;/strong&gt;: In bed, walking the dog, shopping, out to dinner (don't tell my wife)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capture times&lt;/strong&gt;: 40% after 9 PM, 30% before 9 AM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average time from idea to issue&lt;/strong&gt;: 47 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The key insight&lt;/strong&gt;: 0% of these would exist without voice input. Not because I'm lazy, but because ideas are ephemeral.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started With Voice Capture
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Accept the reality&lt;/strong&gt;: You will forget that idea in 5 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make it frictionless&lt;/strong&gt;: Phone shortcut, PWA, whatever works&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speak naturally&lt;/strong&gt;: Include context, don't self-edit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust the AI&lt;/strong&gt;: It's better at formatting than your memory is at remembering&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try This For One Week
&lt;/h2&gt;

&lt;p&gt;Don't think about time saved. Think about ideas saved. Every time you have a development thought away from your keyboard, capture it with voice. &lt;/p&gt;

&lt;p&gt;After one week, count how many ideas made it to GitHub that normally would have vanished.&lt;/p&gt;

&lt;p&gt;That's the real metric.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;How many development ideas do you lose each week? Have you found other ways to capture fleeting thoughts? Share your experience in the comments!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; Want to try VoiceCommit? Free tier includes 25 voice submissions/month: &lt;a href="https://voicecommit.com" rel="noopener noreferrer"&gt;voicecommit.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>productdevelopment</category>
      <category>programming</category>
    </item>
    <item>
      <title>My Take on the NPM Calling Card</title>
      <dc:creator>Ben Newton</dc:creator>
      <pubDate>Thu, 03 Jan 2019 03:46:14 +0000</pubDate>
      <link>https://dev.to/benenewton/my-take-on-the-npm-calling-card-3d74</link>
      <guid>https://dev.to/benenewton/my-take-on-the-npm-calling-card-3d74</guid>
      <description>&lt;p&gt;Originally posted at &lt;a href="https://benenewton.com/npm-calling-card/" rel="noopener noreferrer"&gt;https://benenewton.com/npm-calling-card/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've recently noticed a trend among some javascript developers in which they are publishing a simple &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; package that they use to share their contact information. I have seen this in the past but I'm not sure who's I saw first, I believe it may have been &lt;a href="https://github.com/elijahmanor/elijahmanor" rel="noopener noreferrer"&gt;Elijah Manor&lt;/a&gt;. After reading about it again on &lt;a href="https://dev.to/wuz/setting-up-a-npx-username-card-1pip"&gt;this dev.to post&lt;/a&gt; by &lt;a href="https://dev.to/wuz"&gt;Conlin Durbin&lt;/a&gt;, &lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/wuz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F28677%2F832cee31-d4b7-492e-9854-b74192026b8c.jpg" alt="wuz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/wuz/setting-up-a-npx-username-card-1pip" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Setting up a `npx username` card!&lt;/h2&gt;
      &lt;h3&gt;Conlin Durbin ・ Dec 26 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I decided to create my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make Your Own
&lt;/h2&gt;

&lt;p&gt;You can view my Repo on GitHub here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/bennewton999" rel="noopener noreferrer"&gt;
        bennewton999
      &lt;/a&gt; / &lt;a href="https://github.com/bennewton999/bennewton" rel="noopener noreferrer"&gt;
        bennewton
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      NPM Contact Card
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;NPM Contact Card&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b950578bf4f78424045ced92990090593b9fa5eec1a48a13c683ecd19fa64953/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f62656e6e6577746f6e2e7376673f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/b950578bf4f78424045ced92990090593b9fa5eec1a48a13c683ecd19fa64953/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f62656e6e6577746f6e2e7376673f7374796c653d666c61742d737175617265" alt="version"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My take on the NPX me contact card.&lt;/p&gt;
&lt;p&gt;To run - &lt;code&gt;npx bennewton&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To make your own, fork this Repo and update the myData.js, add ascii art to asciiArt.js or leave file empty. When updated, publish to npm as your own new package.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/bennewton999/bennewton" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;To make it your own, you can fork it and do as little as update the info in &lt;code&gt;myData.js&lt;/code&gt; and &lt;code&gt;package.json&lt;/code&gt; then publish as a new NPM module. Or you can go further and customize the text output with chalk, add your own data, etc. I used tagged template literals, so modifying the output is a breeze. You can just add a modifier like &lt;code&gt;{red ${name}}&lt;/code&gt; to an output function to change the color and/or font variant.&lt;/p&gt;

&lt;p&gt;I also added some ascii art for old times' sake (and because why not??). I originally used &lt;a href="https://www.npmjs.com/package/image-to-ascii" rel="noopener noreferrer"&gt;image-to-ascii&lt;/a&gt; to generate the ascii art from a .png on my website, however an external dependency of &lt;a href="http://www.graphicsmagick.org/" rel="noopener noreferrer"&gt;GraphicsMagick&lt;/a&gt; was required for it to work properly. So I removed it and copied the output to a file. I was unable to keep the color, which stinks. I would like to know how to keep the color referenced in the file, I'm not sure what format and how to output that, so if anybody has any ideas, let me know.&lt;/p&gt;

&lt;h2&gt;
  
  
  See It In Action
&lt;/h2&gt;

&lt;p&gt;To see it all in action, run the following from your command prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx bennewton
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a quick, temporary install, the downloaded npm module will display the following in your terminal leaving nothing behind on your drive.&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%2Fbenenewton.com%2Fstatic%2Fbennewton-output-f9dd415603c71b22621cd960af8dfa80-22704.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%2Fbenenewton.com%2Fstatic%2Fbennewton-output-f9dd415603c71b22621cd960af8dfa80-22704.png" alt="npx bennewton output" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The npx command downloads and runs a NPM module on your machine without installing it permanently. This is perfect for this type of text output module.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's It For?
&lt;/h2&gt;

&lt;p&gt;Of course, this serves very little purpose, it's just for fun. After reading the artice, it reminded me of Apple II games from the 80s. These games were "cracked" and would have the "pirate's" name on the &lt;a href="https://www.google.com/search?biw=1280&amp;amp;bih=767&amp;amp;tbm=isch&amp;amp;sa=1&amp;amp;ei=mLYrXOKbOK2Oggfu3qv4DA&amp;amp;q=apple+ii+cracked+games&amp;amp;oq=apple+ii+cracked+games&amp;amp;gs_l=img.3.0.35i39.5003.7495..7596...0.0..1.280.1585.6j3j3......1....1..gws-wiz-img.......0j0i30j0i8i30j0i24.cf9t7-cy9q0#imgrc=ZedDzc7KuxtS-M:" rel="noopener noreferrer"&gt;splash screen&lt;/a&gt; along with some BBS phone numbers where you could download other games. Those were the days...&lt;/p&gt;

&lt;p&gt;So my thought was why don't we use these as calling cards as signatures for our own modules. We are downloading hundreds if not thousands of modules as developers, most of the time knowing nothing about the author and paying little to no homage to them. A simple post-install script calling the author's own NPM calling card could be the answer to get them the recognition they deserve. I think it would be cool and at least make waiting for NPM installs more entertaining. Just a thought, what do you think?&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>commandline</category>
    </item>
    <item>
      <title>How To Handle Pesky Modals In Your Puppeteer Tests</title>
      <dc:creator>Ben Newton</dc:creator>
      <pubDate>Fri, 03 Aug 2018 03:32:34 +0000</pubDate>
      <link>https://dev.to/benenewton/how-to-handle-pesky-modals-in-your-puppeteer-tests-2igm</link>
      <guid>https://dev.to/benenewton/how-to-handle-pesky-modals-in-your-puppeteer-tests-2igm</guid>
      <description>&lt;p&gt;If you've worked on any large e-commerce sites, you've probably run into an iPerception Modal. Every major brand seems to have this survey and it will inevitably pop up right as you are trying to do something important. The good news for most users is you won't ever see it again if you close it. But, for developers, you'll see this modal over and over if you're running visual regression tests or integration tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the iPerception Modal?
&lt;/h3&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%2Fbenenewton.com%2Fstatic%2FiperceptionModal-d9261e8e5975ec235c9c9fe174154c16-b7e98.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%2Fbenenewton.com%2Fstatic%2FiperceptionModal-d9261e8e5975ec235c9c9fe174154c16-b7e98.png" title="iPerception Modal" alt="iPerception Modal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem with the Modal
&lt;/h3&gt;

&lt;p&gt;In my partucular case, I was running integration tests on an ecommerce funnel of a site I'm currently working on. The flow starts at the home page and then clicks through a series of steps to the confirmation page. As I wrote the tests, I would run the test after each additional step to make sure they were passing. While working on step 3, I suddenly began to get test failures on step 2 which had been passing previously.&lt;/p&gt;

&lt;p&gt;I set headless to true in the Puppeteer config and watched the tests in the browser. I quickly realized the iPerception modal had began popping up in step 2, blocking my test from clicking the proper CTA to continue the flow, hence the failing test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find and Handle the Modal in Puppeteer
&lt;/h3&gt;

&lt;p&gt;I had to check for the modal on each page and close it if I wanted the test to pass and continue to the next step. I was hoping there was simple way for me to set up the modal not to show, after all, this is on my local environment. But in this case, it is a large code base with many agencies working on it and I don't have access to the code that is triggering the modal. So I had to find a way to test for the modal and close it before trying to click the CTA to the next step of the funnel.&lt;/p&gt;

&lt;p&gt;I tried to identify the modal by an ID or a class, but they use neither. My guess is this is to avoid ad blockers. I figured out the only selector in the modal I really need to target was the 'NO' CTA. I just had to check for this CTA on the page and if it exists, click it to close the modal. I found since it was an image, I could just use the src attribute as a selector. So now, before each screenshot and click of a CTA, Puppeteer checks for the 'NO' CTA, if it exists, it clicks it and continues with the test. I added this as a helper library as I would have to call it multiple times in multiple tests.&lt;/p&gt;

&lt;p&gt;Below is the module I added to my test. I ended up having to call it on every page. The modal is not set for just the home page. In my case, it came up in every page over the course of writing the 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;// Checks for survey modal and clicks "NO" if it is on page during testing.&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkForSurvey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SELECTOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;img[src="https://ips-invite.iperceptions.com/images/templates/Layer/theme1/no_1.png"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SELECTOR&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&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="nx"&gt;SELECTOR&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;checkForSurvey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example of how I used the module above in my tests. I now use this in all my Puppeteer tests for this particular site. Without it, my tests would fail randomly all the time.&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="nx"&gt;puppeteer&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;puppeteer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;toMatchImageSnapshot&lt;/span&gt; &lt;span class="p"&gt;}&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;jest-image-snapshot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;config&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;./config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;checkForSurvey&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;./checkForSurvey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;toMatchImageSnapshot&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;beforeAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;args&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;--no-sandbox&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;--enable-features=NetworkService&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;--ignore-certificate-errors&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;--disable-web-security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;headless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showBrowser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// slowMo: 80,&lt;/span&gt;
    &lt;span class="na"&gt;ignoreHTTPSErrors&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;devtools&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="nx"&gt;showDevtools&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;afterAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&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;Visual Regression Test Home Page&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="nf"&gt;test&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 page screenshot should match&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setViewport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&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="nx"&gt;homePageUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Check for iPerseption Survey Modal and close if it exists.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;checkForSurvey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;screenshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;screenshot&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;screenshot&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toMatchImageSnapshot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Page 2 Page should match screenshot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.linkToPage2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForNavigation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Check for iPerseption Survey Modal and close if it exists.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;checkForSurvey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;screenshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;screenshot&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;screenshot&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toMatchImageSnapshot&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 helper became a necessity for every test I have written so far. If you have something similar that may take over the pages you are trying to write Puppeteer tests for, I hope this helps you. Let me know in the comments if you use this to remove an iPerception modal on your tests. And let me know if you have a different way of handling this.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
