<?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: Kevin Jalbert</title>
    <description>The latest articles on DEV Community by Kevin Jalbert (@kevinjalbert).</description>
    <link>https://dev.to/kevinjalbert</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%2F71594%2Fb4ac20ac-2740-4dcc-bc12-b2f9de908f55.jpeg</url>
      <title>DEV Community: Kevin Jalbert</title>
      <link>https://dev.to/kevinjalbert</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevinjalbert"/>
    <language>en</language>
    <item>
      <title>Keep a macOS Application Running using cron</title>
      <dc:creator>Kevin Jalbert</dc:creator>
      <pubDate>Fri, 28 May 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/kevinjalbert/keep-a-macos-application-running-using-cron-232a</link>
      <guid>https://dev.to/kevinjalbert/keep-a-macos-application-running-using-cron-232a</guid>
      <description>&lt;p&gt;I have used &lt;a href="https://www.rescuetime.com/ref/31263"&gt;RescueTime (Referral Link)&lt;/a&gt; for many years at this point. It always disappoints me when I get the email saying that no data was recorded in RescueTime for the last week (see image above article title). For reasons unannounced to me, the macOS menu bar application had stopped running. I use the &lt;a href="https://www.macbartender.com/"&gt;Bartender for macOS&lt;/a&gt; to hide certain menu bar applications (as they offer little visual value) – RescueTime is hidden from my view and I never noticed it wasn’t running.&lt;/p&gt;

&lt;p&gt;I needed a way to ensure that the application was kept running if it crashed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch Application in Background using &lt;code&gt;cron&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;I know of &lt;code&gt;cron&lt;/code&gt; and how it can run scripts periodically – I figured this would be the tool to save me here.&lt;/p&gt;

&lt;p&gt;I quickly put together the following (add this using &lt;code&gt;crontab -e&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/5 * * * * open --hide --background /Applications/RescueTime.app

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

&lt;/div&gt;



&lt;p&gt;Using &lt;a href="https://crontab.guru/#*/5_*_*_*_*"&gt;crontab.guru&lt;/a&gt; we can see that this will run the &lt;code&gt;open&lt;/code&gt; for ResuceTime command every 5 minutes. The &lt;code&gt;--hide&lt;/code&gt; and &lt;code&gt;--background&lt;/code&gt; ensure that the application doesn’t open in an obtrusive manner (i.e., think applications with a GUI).&lt;/p&gt;

&lt;p&gt;This worked for me – it opened RescueTime if it was closed out. I even tested this with other applications and it &lt;em&gt;mostly&lt;/em&gt; worked as expected. The &lt;em&gt;hide and background&lt;/em&gt; flags didn’t work for some applications (e.g., Evernote always appears in the forefront for whatever reason).&lt;/p&gt;

&lt;p&gt;Done deal then right? Wrong. I noticed every now and then a keystroke or two wouldn’t register. When I looked at the time it was always on the minute the &lt;code&gt;cron&lt;/code&gt; would trigger… If I had to take a guess, the &lt;code&gt;open&lt;/code&gt; was causing focus to switch briefly and would interrupt keystrokes on the current application I was in.&lt;/p&gt;

&lt;p&gt;I could decrease the frequency that the command would run or…&lt;/p&gt;

&lt;h2&gt;
  
  
  Only &lt;code&gt;open&lt;/code&gt; if Application isn’t Running
&lt;/h2&gt;

&lt;p&gt;My next approach was to only &lt;em&gt;open&lt;/em&gt; the application if it wasn’t already running. This will prevent the &lt;code&gt;open&lt;/code&gt; from triggering multiple times during the day.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Scroll to see full command (it is one line due to fitting in the crontab)
*/5 * * * * app=Rescuetime; ps aux | grep -v grep | grep -ci $app &amp;gt; /dev/null || open --hide --background /Applications/$app.app

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

&lt;/div&gt;



&lt;p&gt;If we break this down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app=Rescuetime;&lt;/code&gt; sets a variable of what application we’re trying to keep open.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ps aux | grep -v grep | grep -ci $app &amp;gt; /dev/null&lt;/code&gt; lists all running processes, excluding the &lt;code&gt;grep&lt;/code&gt; process, and finally counting the found lines while &lt;code&gt;grep&lt;/code&gt;ing for the application’s name. This ends up being a 0 or 1. The STDOUT output is directed to the void so that it doesn’t create new &lt;code&gt;mail&lt;/code&gt; entries.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;||&lt;/code&gt; will conditionally run the next statement if the previous was falsey (i.e., no application was found running)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;open --hide --background /Applications/$app.app&lt;/code&gt; opens the specified application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now this works as expected! I no longer have to worry about RescueTime not running. I might do this for other menubar applications that I like to have active, but are hidden.&lt;/p&gt;

&lt;p&gt;I haven’t tried this on Linux but I suspect you could do something similar (assuming there is an equivalent to &lt;code&gt;open&lt;/code&gt;).&lt;/p&gt;

</description>
      <category>cron</category>
      <category>macos</category>
      <category>tools</category>
    </item>
    <item>
      <title>AppleScript that Mirrors iPhone to QuickTime</title>
      <dc:creator>Kevin Jalbert</dc:creator>
      <pubDate>Fri, 30 Apr 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/kevinjalbert/applescript-that-mirrors-iphone-to-quicktime-4g9g</link>
      <guid>https://dev.to/kevinjalbert/applescript-that-mirrors-iphone-to-quicktime-4g9g</guid>
      <description>&lt;p&gt;Like many, I’m guilty of playing mobile games on my iPhone. For the games that have controller support, I’ll stream the video on a larger screen. As mentioned in my &lt;a href="https://kevinjalbert.com/how-i-keep-active-at-home/"&gt;previous article&lt;/a&gt;, I’ll sometimes play on my exercise bike. In this situation, I’ll &lt;em&gt;mirror&lt;/em&gt; my iOS device through QuickTime so that I can play on a larger screen with a controller.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Steps
&lt;/h2&gt;

&lt;p&gt;There are a number of steps that I have to complete to mirror my iPhone to QuickTime:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable &lt;a href="https://keepingyouawake.app/"&gt;KeepingYouAwake&lt;/a&gt; (so monitor doesn’t go to sleep with no inputs)&lt;/li&gt;
&lt;li&gt;Open QuickTime&lt;/li&gt;
&lt;li&gt;Make a new &lt;em&gt;Movie Recording&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Select my iPhone for video input&lt;/li&gt;
&lt;li&gt;Select my iPhone for audio input&lt;/li&gt;
&lt;li&gt;Drag the volume slider to 100%.&lt;/li&gt;
&lt;li&gt;Maximize Quicktime window&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Sweet Automation
&lt;/h2&gt;

&lt;p&gt;This GIF demonstrates the automation that covers all seven manual steps. I launch it using &lt;a href="https://www.alfredapp.com/"&gt;Alfred&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7RCqGvRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://kevinjalbert.com/images/2021-04-30-applescript-that-mirrors-iphone-to-quicktime/mirror-ios-alfred.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7RCqGvRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://kevinjalbert.com/images/2021-04-30-applescript-that-mirrors-iphone-to-quicktime/mirror-ios-alfred.gif" alt="Mirror ios alfred"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;I may be biased, but the source code is organized quite well in my opinion. The first eight lines cover all necessary customization needs as they are just function calls. If you need to, you can always dive into the functions themselves. The following is the code hosted on a &lt;a href="https://gist.github.com/kevinjalbert/d7661a6a34c1d66dccf701f64eb09be4"&gt;Public Gist&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Selecting a video input
&lt;/h3&gt;

&lt;p&gt;I had to select my iPhone for the video/audio inputs in QuickTime using AppleScript. A quick search turned up this &lt;a href="https://stackoverflow.com/q/45228743/583592"&gt;Stack Overflow question&lt;/a&gt;. It turns out that you &lt;em&gt;should&lt;/em&gt; be able to do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight applescript"&gt;&lt;code&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"QuickTime Player"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;newMovieRecording&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;movie&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;recording&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;newMovieRecording&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;camera&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;newMovieRecording&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kevin's iPhone"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;microphone&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;newMovieRecording&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kevin's iPhone"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, it doesn’t work as you get hit with &lt;code&gt;Can’t make "Kevin's iPhone" into type video recording device&lt;/code&gt;. This would have made things &lt;em&gt;much easier&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Instead, we have to click the button to open the inputs list and then make the selections via AppleScript. This wasn’t too bad initially, as it was just iterating the list of menu items and clicking the one which matched my device’s name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Same name for audio/video inputs
&lt;/h3&gt;

&lt;p&gt;After I was able to select the video input, the next problem is selecting the audio input. The problem now is that the audio and video input share the same name and are within the same list. I would have to &lt;em&gt;skip&lt;/em&gt; the first one (video input) to select the audio input. This wasn’t too hard but was just another hurdle to get over. Ideally, the list of inputs would have been separated by video/audio, or somehow have a different key to reference them by.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inputs menu was slow to close
&lt;/h3&gt;

&lt;p&gt;I had noticed earlier that when the inputs menu was opened it would stay open for 7-8 seconds before making the menu item selection. I wasn’t too concerned at the time, but after the whole automation was done it took just under 20 seconds to mirror my device.&lt;/p&gt;

&lt;p&gt;It took a lot of digging but I found a &lt;a href="https://apple.stackexchange.com/a/400163/228446"&gt;Stack Overflow answer&lt;/a&gt; that provided the solution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight applescript"&gt;&lt;code&gt;&lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="nv"&gt;openInputMenu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;ignoring &lt;/span&gt;&lt;span class="nb"&gt;application responses&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"System Events"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"QuickTime Player"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nv"&gt;click&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;window&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nb"&gt;delay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ignoring&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nb"&gt;do shell script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"killall 'System Events'"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;openDeviceMenu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function for opening the menu is explicitly telling it to ignore the application responses (i.e., don’t wait for feedback). A manual delay of a second is injected to give time for the menu to open up. It also kills the &lt;code&gt;System Events&lt;/code&gt;, which ends up forcing the script to continue execution to future actions. I’ll be honest, I’m not 100% on the specifics but it worked – the menu opens and the selections are made in just over a second now.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>tools</category>
      <category>alfred</category>
      <category>applescript</category>
    </item>
    <item>
      <title>iTerm2 Mouseless Copy</title>
      <dc:creator>Kevin Jalbert</dc:creator>
      <pubDate>Sun, 06 May 2018 23:53:20 +0000</pubDate>
      <link>https://dev.to/kevinjalbert/iterm2-mouseless-copy-1aeo</link>
      <guid>https://dev.to/kevinjalbert/iterm2-mouseless-copy-1aeo</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image &lt;a href="https://flickr.com/photos/creative_tools/8573767153" rel="noopener noreferrer"&gt;3D printed mouse&lt;/a&gt; by &lt;a href="https://flickr.com/people/creative_tools" rel="noopener noreferrer"&gt;Creative Tools&lt;/a&gt; is licensed under &lt;a href="https://creativecommons.org/licenses/by/2.0/" rel="noopener noreferrer"&gt;CC BY&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Where possible, I try to avoid using the mouse. I heavily use &lt;a href="https://www.vim.org/" rel="noopener noreferrer"&gt;Vim&lt;/a&gt; while editing which allows for keyboard navigation. I have taken such a liking to the Vim keyboard-bindings that I even use &lt;a href="https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=en" rel="noopener noreferrer"&gt;Vimium (a Google Chrome extension)&lt;/a&gt; for keyboard-driven navigation in my browser (for as much as I can). In addition, I use &lt;a href="https://itunes.apple.com/ca/app/bettersnaptool/id417375580" rel="noopener noreferrer"&gt;BetterSnapTool&lt;/a&gt; for MacOS, which allows me to move/resize windows around solely from my keyboard.&lt;/p&gt;

&lt;p&gt;One optimization within my terminal that I have been avoiding is &lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;tmux&lt;/a&gt; – it is unnecessarily complicated for what I need. For the most part, I am able to use &lt;a href="https://www.iterm2.com/" rel="noopener noreferrer"&gt;iTerm2&lt;/a&gt; to open tabs, split panes and navigate around. To be honest, I don’t really need the session keeping functionality that tmux or &lt;a href="http://www.gnu.org/software/screen/" rel="noopener noreferrer"&gt;screen&lt;/a&gt; provided. The big gain I was missing from tmux was the famed &lt;a href="https://minimul.com/increased-developer-productivity-with-tmux-part-8.html" rel="noopener noreferrer"&gt;copy mode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A quick snippet from &lt;a href="https://www.iterm2.com/documentation-highlights.html" rel="noopener noreferrer"&gt;iTerm2’s documentation of highlights&lt;/a&gt; for text selection:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;You can use the mouse.&lt;/li&gt;
&lt;li&gt;You can use the find feature’s “mouseless copy” feature.&lt;/li&gt;
&lt;li&gt;You can use Copy Mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first one we’re not interested in as it’s the &lt;em&gt;standard&lt;/em&gt; way to select and copy text. We will cover others two in the sections that follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find and Copy
&lt;/h2&gt;

&lt;p&gt;So one approach to copying anything within the iTerm2’s session is to use the default &lt;em&gt;search&lt;/em&gt;. It is an interesting approach, to say the least:&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%2Fkevinjalbert.com%2Fimages%2F2018-05-06-iterm2-mouseless-copy%2Fsearch-copy.gif" 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%2Fkevinjalbert.com%2Fimages%2F2018-05-06-iterm2-mouseless-copy%2Fsearch-copy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essentially, you initiate the search with &lt;em&gt;cmd+f&lt;/em&gt; and you can use the &lt;em&gt;enter&lt;/em&gt; and &lt;em&gt;tab&lt;/em&gt; to move your selection around and to control how much of the text you want in your selection. It works in a pinch, but if you mess up the amount of text in your selection, you basically have to restart the process. In addition, I found the &lt;em&gt;shift+tab&lt;/em&gt; command cycled the selected search result, leading to some confusion.&lt;/p&gt;

&lt;p&gt;To be honest, I don’t use this search copying approach very often. I find it difficult to get right, as you cannot really afford any mistakes. The following is a summary of this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Searching for some text using &lt;em&gt;cmd+f&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;enter&lt;/em&gt; to move to the next search result.&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;shift+enter&lt;/em&gt; to move to the previous search result.&lt;/li&gt;
&lt;li&gt;Navigate until you are on the desired location.&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;tab&lt;/em&gt; to expand your search to the next word.&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;shift+tab&lt;/em&gt; to expand your search to the previous word.

&lt;ul&gt;
&lt;li&gt;Although it moves to the previous search result if one exists.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;When your search term is selected, use &lt;em&gt;cmd+c&lt;/em&gt; to copy the selection.&lt;/li&gt;

&lt;li&gt;Use &lt;em&gt;esc&lt;/em&gt; to exit search, and now you have the selection in your clipboard.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Copy Mode
&lt;/h2&gt;

&lt;p&gt;This iTerm2 mode attempts to emulate as much of the tmux copy mode as possible, allowing you to make text selections using the keyboard. It is a &lt;em&gt;mode&lt;/em&gt; very much like Vim’s &lt;em&gt;insert&lt;/em&gt; and &lt;em&gt;normal&lt;/em&gt; modes. It is important to note that the session within the pane will stop updating when you enter copy mode.&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%2Fkevinjalbert.com%2Fimages%2F2018-05-06-iterm2-mouseless-copy%2Fcopy-mode.gif" 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%2Fkevinjalbert.com%2Fimages%2F2018-05-06-iterm2-mouseless-copy%2Fcopy-mode.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I highly recommend reading the &lt;a href="https://www.iterm2.com/documentation-copymode.html" rel="noopener noreferrer"&gt;documentation on iTerm2’s copy mode&lt;/a&gt; as it completely covers the keyboard shortcuts and features. Copy mode, in my opinion, is the superior of the two approaches for mouseless copying. I highly recommend giving it a shot the next time you reach for your mouse. The following is a quick summary of copy mode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter copy mode with &lt;em&gt;cmd+shift+c&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Basic Vim keybinding, many keystrokes can active different actions.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;v&lt;/em&gt; to select by character.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;shift+v&lt;/em&gt; to select by line.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;ctrl+v&lt;/em&gt; for rectangular selection.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;ctrl+space&lt;/em&gt; to stop selecting.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;y&lt;/em&gt; to yank/copy the selection (also exits copy mode).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;q&lt;/em&gt; to exit copy mode.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Can chain off of iTerm2’s search feature.&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>tips</category>
      <category>terminal</category>
      <category>macos</category>
    </item>
    <item>
      <title>Jest Snapshots: Reducing styled-jsx Noise</title>
      <dc:creator>Kevin Jalbert</dc:creator>
      <pubDate>Wed, 11 Apr 2018 23:53:20 +0000</pubDate>
      <link>https://dev.to/kevinjalbert/jest-snapshots-reducing-styled-jsx-noise-gbi</link>
      <guid>https://dev.to/kevinjalbert/jest-snapshots-reducing-styled-jsx-noise-gbi</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image &lt;a href="https://flickr.com/photos/howardignatius/13875481115"&gt;Total Eclipse Light&lt;/a&gt; by &lt;a href="https://flickr.com/people/howardignatius"&gt;howardignatius&lt;/a&gt; is licensed under &lt;a href="https://creativecommons.org/licenses/by-nc-nd/2.0/"&gt;CC BY-NC-ND&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Facebook’s &lt;a href="https://facebook.github.io/jest/"&gt;Jest&lt;/a&gt; is a powerful testing framework for JavaScript. It works &lt;em&gt;out of the box&lt;/em&gt; for React projects and is essentially the de facto testing framework for React. When I began using Jest in combination with React I fell in love with the &lt;a href="https://facebook.github.io/jest/docs/en/snapshot-testing.html#snapshot-testing-with-jest"&gt;snapshot testing&lt;/a&gt; functionality. Having snapshots helps detect structural regressions in the rendered DOM, as per the homepage’s documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Capture snapshots of React trees or other serializable values to simplify testing and to analyze how state changes over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;During my work with React and Jest, I was using &lt;a href="https://github.com/zeit/styled-jsx"&gt;&lt;code&gt;styled-jsx&lt;/code&gt;&lt;/a&gt; as my &lt;a href="https://hackernoon.com/all-you-need-to-know-about-css-in-js-984a72d48ebc"&gt;CSS-in-JS&lt;/a&gt; technology choice. Many times, I saw the following when I made any CSS changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAIL src/App.test.js
● renders without crashing

  expect(value).toMatchSnapshot()

  Received value does not match stored snapshot 1.

  - Snapshot
  1. Received

  @@ -1,28 +1,23 @@
   &amp;lt;div
  - className="jsx-188895008 App"
  + className="jsx-3481390381 App"
   &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because the CSS changed for this scoped component and thus the &lt;code&gt;jsx-########&lt;/code&gt; (unique id) reflects the change.&lt;/p&gt;

&lt;p&gt;To me, these changes in the snapshot diffs are noise and it is harder to see the structural DOM changes. The original &lt;code&gt;className&lt;/code&gt; for the DOM elements are still present, and ideally, I would just want snapshots without any of the &lt;code&gt;styled-jsx&lt;/code&gt; stuff present.&lt;/p&gt;

&lt;p&gt;We will first start with a simplified &lt;code&gt;App&lt;/code&gt; component using &lt;a href="https://github.com/facebook/create-react-app"&gt;create-react-app&lt;/a&gt; as the base. The goal is to illustrate the project setup, what the snapshots look like, how to reduce the noise, and what the snapshots look like afterwards. &lt;code&gt;styled-jsx&lt;/code&gt; provides a way to style your components using &lt;em&gt;inline styles&lt;/em&gt; or &lt;em&gt;external CSS files&lt;/em&gt;, so we will consider both in this article. In addition, we will also consider both the &lt;code&gt;react-test-renderer&lt;/code&gt; and &lt;code&gt;enzyme&lt;/code&gt; Jest snapshot rendering methods.&lt;/p&gt;

&lt;p&gt;Given the above information, the following sections will cover these scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inline styles with &lt;code&gt;react-test-renderer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Inline styles with &lt;code&gt;enzyme&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;External styles with &lt;code&gt;react-test-renderer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;External styles with &lt;code&gt;enzyme&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Inline Styles
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      &amp;lt;div className="App"&amp;gt;
        &amp;lt;p&amp;gt;
          Example Component
        &amp;lt;/p&amp;gt;
        &amp;lt;style jsx&amp;gt;{`
          .App {
            text-align: center;
          }
        `}&amp;lt;/style&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make this all work, you have to add the &lt;code&gt;styled-jsx/babel&lt;/code&gt; to &lt;em&gt;plugins&lt;/em&gt; in the babel configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"babel": {
  "presets": [
    "react-app"
  ],
  "plugins": [
    "styled-jsx/babel"
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Snapshots with react-test-renderer
&lt;/h3&gt;

&lt;p&gt;Within the context of inline styles, we’ll first look at the default approach for testing with Jest snapshots using &lt;a href="https://github.com/facebook/react/tree/master/packages/react-test-renderer"&gt;&lt;code&gt;react-test-renderer&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import ReactDOM from 'react-dom';
import renderer from 'react-test-renderer';

import App from './App';

it('renders without crashing', () =&amp;gt; {
  const tree = renderer.create(&amp;lt;App /&amp;gt;).toJSON();
  expect(tree).toMatchSnapshot();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates the following snapshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports[`renders without crashing 1`] = `
&amp;lt;div
  className="jsx-188096426 App"
&amp;gt;
  &amp;lt;p
    className="jsx-188096426"
  &amp;gt;
    Example Component
  &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we change one aspect of the CSS (i.e., the &lt;code&gt;text-align&lt;/code&gt; value), we get the following snapshot diff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Snapshot
+ Received

 &amp;lt;div
- className="jsx-188096426 App"
+ className="jsx-1500233327 App"
 &amp;gt;
   &amp;lt;p
- className="jsx-188096426"
+ className="jsx-1500233327"
   &amp;gt;
     Example Component
   &amp;lt;/p&amp;gt;
 &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the &lt;code&gt;jsx-########&lt;/code&gt; noise in our diff. One other thing to note here is that the &lt;code&gt;p&lt;/code&gt; element also has the noise even though our CSS doesn’t target it!&lt;/p&gt;

&lt;p&gt;To eliminate this noise, let us remove the &lt;code&gt;styled-jsx/babel&lt;/code&gt; plugin from the test environment (you will want to specify your different environments):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"babel": {
  "presets": [
    "react-app"
  ],
  "env": {
    "production": {
      "plugins": [
        "styled-jsx/babel"
      ]
    },
    "development": {
      "plugins": [
        "styled-jsx/babel"
      ]
    },
    "test": {
      "plugins": [
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a snapshot that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports[`renders without crashing 1`] = `
&amp;lt;div
  className="App"
&amp;gt;
  &amp;lt;p&amp;gt;
    Example Component
  &amp;lt;/p&amp;gt;
  &amp;lt;style
    jsx={true}
  &amp;gt;

              .App {
                text-align: center;
              }

  &amp;lt;/style&amp;gt;
&amp;lt;/div&amp;gt;
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, the &lt;code&gt;jsx-########&lt;/code&gt; values are no longer present, although there is now a &lt;code&gt;style&lt;/code&gt; element which has the actual CSS. In my opinion, this is a good trade – now every element doesn’t have the ever-changing &lt;code&gt;jsx-########&lt;/code&gt;. This alone results in cleaner snapshots from my perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Snapshots with enzyme
&lt;/h3&gt;

&lt;p&gt;The second approach we will look at for inline styles is snapshot testing with &lt;a href="https://github.com/airbnb/enzyme"&gt;&lt;code&gt;enzyme&lt;/code&gt;&lt;/a&gt;. This package gives you the additional functionality to assert and manipulate the component’s output. Unfortunately, the rendered component is wrapped in an &lt;code&gt;enzyme&lt;/code&gt; specific component, which produces unnecessarily complex snapshots. Fortunately, the &lt;a href="https://github.com/adriantoine/enzyme-to-json"&gt;&lt;code&gt;enzyme-to-json&lt;/code&gt;&lt;/a&gt; package provides an approach to convert the wrapped component to the standard format we’re familiar with. It is worth noting that you can further simplify the setup if you read more into the documentation of &lt;code&gt;enzyme&lt;/code&gt; and &lt;code&gt;enzyme-to-json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import ReactDOM from 'react-dom';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';

import App from './App';

Enzyme.configure({ adapter: new Adapter() });

it('renders without crashing', () =&amp;gt; {
  const wrapper = shallow(&amp;lt;App /&amp;gt;);
  expect(toJson(wrapper)).toMatchSnapshot();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates the following snapshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports[`renders without crashing 1`] = `
&amp;lt;div
  className="jsx-188096426 App"
&amp;gt;
  &amp;lt;p
    className="jsx-188096426"
  &amp;gt;
    Example Component
  &amp;lt;/p&amp;gt;
  &amp;lt;JSXStyle
    css=".App.jsx-188096426{text-align:center;}"
    styleId="188096426"
  /&amp;gt;
&amp;lt;/div&amp;gt;
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice here that we have an additional &lt;code&gt;JSXStyle&lt;/code&gt; element that contains the actual CSS styles. This is &lt;em&gt;in addition&lt;/em&gt; to the original noise we have in our snapshot.&lt;/p&gt;

&lt;p&gt;If we change one aspect of the CSS (i.e., the &lt;code&gt;text-align&lt;/code&gt; value), we get the following snapshot readout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Snapshot
+ Received

 &amp;lt;div
- className="jsx-188096426 App"
+ className="jsx-1500233327 App"
 &amp;gt;
   &amp;lt;p
- className="jsx-188096426"
+ className="jsx-1500233327"
   &amp;gt;
     Example Component
   &amp;lt;/p&amp;gt;
   &amp;lt;JSXStyle
- css=".App.jsx-188096426{text-align:center;}"
- styleId="188096426"
+ css=".App.jsx-1500233327{text-align:left;}"
+ styleId="1500233327"
   /&amp;gt;
 &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we apply the same fix as we did for inline styles with &lt;code&gt;react-test-renderer&lt;/code&gt; (removing &lt;code&gt;styled-jsx/babel&lt;/code&gt; plugin from the test environment), we now get the same snapshot output. Thus, there are no more &lt;code&gt;jsx-########&lt;/code&gt; values, however the raw CSS is within the &lt;code&gt;style&lt;/code&gt; tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  External Styles
&lt;/h2&gt;

&lt;p&gt;I personally like to use &lt;a href="https://github.com/zeit/styled-jsx#external-css-and-styles-outside-of-the-component"&gt;external CSS files&lt;/a&gt; that I import into the components. The following shows our converted &lt;code&gt;App&lt;/code&gt; component to use an imported CSS file instead of an inline style:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Component } from 'react';
import css from './App.css';

class App extends Component {
  render() {
    return (
      &amp;lt;div className="App"&amp;gt;
        &amp;lt;p&amp;gt;
          Example Component
        &amp;lt;/p&amp;gt;
        &amp;lt;style jsx&amp;gt;{css}&amp;lt;/style&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}

export default App;

import css from 'styled-jsx/css';

export default css`
  .App {
    text-align: center;
  }
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Snapshots with react-test-renderer
&lt;/h3&gt;

&lt;p&gt;Using external CSS files has no impact on &lt;em&gt;how&lt;/em&gt; we test the component. Thus, we can use the same test from the inline styles section. Since that is the case, let us take the same approach to eliminate the noise in the diff by removing the &lt;code&gt;styled-jsx/babel&lt;/code&gt; plugin from the test environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAIL src/App.test.js
● Test suite failed to run

  styled-jsx/css: if you are getting this error it means that your `css` tagged template literals were not transpiled.

    at Object.&amp;lt;anonymous&amp;gt;.module.exports [as default] (node_modules/styled-jsx/css.js:2:9)
    at Object.&amp;lt;anonymous&amp;gt; (src/App.css.js:3:14)
    at Object.&amp;lt;anonymous&amp;gt; (src/App.js:2:12)
    at Object.&amp;lt;anonymous&amp;gt; (src/App.test.js:5:12)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can recover from this error, if we use a &lt;a href="https://facebook.github.io/jest/docs/en/manual-mocks.html"&gt;Jest manual mocks&lt;/a&gt; to mock out the &lt;code&gt;css&lt;/code&gt; tagged template literal. We can accomplish this by creating the following mock under &lt;code&gt;__mocks__ /styled-jsx/css.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function css() {
  return '';
}

module.exports = css;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our snapshot looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports[`renders without crashing 1`] = `
&amp;lt;div
  className="App"
&amp;gt;
  &amp;lt;p&amp;gt;
    Example Component
  &amp;lt;/p&amp;gt;
  &amp;lt;style
    jsx={true}
  /&amp;gt;
&amp;lt;/div&amp;gt;
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that the &lt;code&gt;jsx-########&lt;/code&gt; values are no longer present, and in addition, the &lt;code&gt;style&lt;/code&gt; tag does not have the raw CSS. This is an improvement over the inline style approaches, as the snapshot doesn’t change with any CSS changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Snapshots with enzyme
&lt;/h3&gt;

&lt;p&gt;We can use the same test we had when testing the inline styles using &lt;code&gt;react-test-renderer&lt;/code&gt;. Going from what we know now, we can remove the &lt;code&gt;styled-jsx/babel&lt;/code&gt; plugin from the test environment and mock the &lt;code&gt;css&lt;/code&gt; tagged template literal. These two changes then result in the same snapshot that we received in the external styles using &lt;code&gt;react-test-renderer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a great outcome given that the use of &lt;code&gt;enzyme&lt;/code&gt; is common in the React tests I write, and it offers the &lt;em&gt;cleanest&lt;/em&gt; snapshots.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you are using &lt;code&gt;styled-jsx&lt;/code&gt; with Jest snapshots:

&lt;ul&gt;
&lt;li&gt;You will see &lt;code&gt;className&lt;/code&gt; changes for the &lt;code&gt;jsx-########&lt;/code&gt; values any time the CSS changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If you are using inline styles:

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Remove&lt;/em&gt; the &lt;code&gt;styled-jsx/babel&lt;/code&gt; plugin from your test environment&lt;/li&gt;
&lt;li&gt;See clean snapshots when using &lt;code&gt;react-test-renderer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;See clean snapshots (except for raw CSS under &lt;code&gt;style&lt;/code&gt; tag) when using &lt;code&gt;enzyme&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If you are using external styles:

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Remove&lt;/em&gt; the &lt;code&gt;styled-jsx/babel&lt;/code&gt; plugin from your test environment&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Mock&lt;/em&gt; the &lt;code&gt;css&lt;/code&gt; tagged template literal for &lt;code&gt;styled-jsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;See clean snapshots when using &lt;code&gt;react-test-renderer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;See clean snapshots when using &lt;code&gt;enzyme&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;There might be a better way to handle this, but as of the time this article was written I have yet to see a clean approach. One thing I noticed was a &lt;a href="https://github.com/zeit/styled-jsx/issues/117#issuecomment-342115323"&gt;GitHub comment&lt;/a&gt; that alluded to a better method that would follow a similar strategy to &lt;a href="https://github.com/styled-components/jest-styled-components"&gt;jest-styled-components&lt;/a&gt; but for &lt;code&gt;styled-jsx&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>testing</category>
      <category>tips</category>
    </item>
    <item>
      <title>Rails ActiveStorage Configuration for Minio</title>
      <dc:creator>Kevin Jalbert</dc:creator>
      <pubDate>Mon, 26 Feb 2018 23:53:20 +0000</pubDate>
      <link>https://dev.to/kevinjalbert/rails-activestorage-configuration-for-minio-4n</link>
      <guid>https://dev.to/kevinjalbert/rails-activestorage-configuration-for-minio-4n</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image &lt;a href="https://flickr.com/photos/agent_ladybug/661200957"&gt;birdy boxcar&lt;/a&gt; by &lt;a href="https://flickr.com/people/agent_ladybug"&gt;b.ug&lt;/a&gt; is licensed under &lt;a href="https://creativecommons.org/licenses/by-nc/2.0/"&gt;CC BY-NC&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You are looking at Rails 5.2 and its shiny new &lt;a href="https://github.com/rails/rails/tree/master/activestorage"&gt;ActiveStorage&lt;/a&gt; – a built-in abstraction/mechanism to handle file storage. You decide to give it a try and remove a dependency you normally use (i.e., &lt;a href="https://github.com/carrierwaveuploader/carrierwave"&gt;CarrierWave&lt;/a&gt; or &lt;a href="https://github.com/thoughtbot/paperclip"&gt;Paperclip&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For some reason, you decide to use &lt;a href="https://minio.io/"&gt;Minio&lt;/a&gt; – an Amazon S3 compatible open source project.&lt;/p&gt;

&lt;p&gt;Looking through the ActiveStorage &lt;a href="http://edgeguides.rubyonrails.org/active_storage_overview.html"&gt;documentation&lt;/a&gt; and &lt;a href="https://github.com/rails/rails/tree/master/activestorage"&gt;repository’s readme&lt;/a&gt;, you figure out how to get everything working locally using ActiveStorage’s &lt;code&gt;local&lt;/code&gt; service.&lt;/p&gt;

&lt;p&gt;Now it is time to try running everything, but with Minio as your file storage. Looking at your &lt;code&gt;config/storage.yml&lt;/code&gt; you’ll see the template for Amazon’s S3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amazon:
   service: S3
   access_key_id: &amp;lt;%= Rails.application.credentials.dig(:aws, :access_key_id) %&amp;gt;
   secret_access_key: &amp;lt;%= Rails.application.credentials.dig(:aws, :secret_access_key) %&amp;gt;
   region: us-east-1
   bucket: your_own_bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configuration Options
&lt;/h1&gt;

&lt;p&gt;Now it’s time to figure out how to use the S3 service in conjunction with your Minio server…&lt;/p&gt;

&lt;h2&gt;
  
  
  Region
&lt;/h2&gt;

&lt;p&gt;Your Minio server doesn’t really support regions like Amazon’s S3. Just keep it as &lt;code&gt;us-east-1&lt;/code&gt; or your closest S3 region (although it really could be any string). From what I’ve seen, this is just used at the Amazon S3-level, and for your hosted Minio server it does not matter.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;region&lt;/code&gt; value is simply used to satisfy ActiveStorage and the &lt;code&gt;aws-sdk-s3&lt;/code&gt; gem. If you omit the &lt;code&gt;region&lt;/code&gt; option you get the following exception &lt;code&gt;missing keyword: region (ArgumentError)&lt;/code&gt;. If you use an empty string for &lt;code&gt;region&lt;/code&gt; you will see &lt;code&gt;missing region; use :region option or export region name to ENV['AWS_REGION'] (Aws::Errors::MissingRegionError)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Endpoint
&lt;/h2&gt;

&lt;p&gt;Your Minio server is hosted at some URL (i.e., &lt;a href="https://minio123.com"&gt;https://minio123.com&lt;/a&gt;), so you’ll need to inform ActiveStorage’s S3 service about this &lt;em&gt;endpoint&lt;/em&gt;. Luckily, it is just a matter of adding the URL endpoint to your configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endpoint: "https://minio123.com" # Points to your Minio server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use ports on the endpoint (i.e., “&lt;a href="http://localhost:9000%E2%80%9D"&gt;http://localhost:9000”&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Force Path Style
&lt;/h2&gt;

&lt;p&gt;So you have the endpoint and region all setup from a configuration standpoint. Your Minio server is also up and running, along with a bucket, &lt;code&gt;your_own_bucket&lt;/code&gt;. You try to upload a file and see the following exception:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aws::Errors::NoSuchEndpointError (Encountered a `SocketError` while attempting to connect to:

  https://you_own_bucket.minio123.com/RJioqjrTT4VmFobw5FhXkSby

This is typically the result of an invalid `:region` option or a
poorly formatted `:endpoint` option.

* Avoid configuring the `:endpoint` option directly. Endpoints are constructed
  from the `:region`. The `:endpoint` option is reserved for connecting to
  non-standard test endpoints.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmm… Well that didn’t work out. If we look at the URL (&lt;a href="https://your%5C_own%5C_bucket.minio123.com"&gt;https://your\_own\_bucket.minio123.com&lt;/a&gt;), we can see that it uses a bucket subdomain approach. However, Minio expects the bucket after the domain (i.e., &lt;a href="https://minio123.com/your%5C_own%5C_bucket"&gt;https://minio123.com/your\_own\_bucket&lt;/a&gt;). Again, fortunately there is an configuration option we can add to &lt;em&gt;force this path style&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;force_path_style: true # Needed to be compliant with how Minio serves the bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Complete Configuration
&lt;/h1&gt;

&lt;p&gt;At this point we covered all the configuration &lt;em&gt;gotchas&lt;/em&gt; to set up ActiveStorage with Minio. Namely, the missing and (mostly undocumented) &lt;code&gt;endpoint&lt;/code&gt; and &lt;code&gt;force_path_style&lt;/code&gt; options. The following is a complete configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minio:
   service: S3
   access_key_id: &amp;lt;%= Rails.application.credentials.dig(:minio, :access_key_id) %&amp;gt;
   secret_access_key: &amp;lt;%= Rails.application.credentials.dig(:minio, :secret_access_key) %&amp;gt;
   region: us-east-1
   bucket: your_own_bucket
   endpoint: "https://minio123.com"
   force_path_style: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It isn’t a bad idea to have the configuration named &lt;code&gt;minio&lt;/code&gt;, just so it is clear that it’s a Minio file storage instead of the typical Amazon S3.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>webdev</category>
      <category>tips</category>
      <category>s3</category>
    </item>
    <item>
      <title>Start Now: Architecture Decision Records</title>
      <dc:creator>Kevin Jalbert</dc:creator>
      <pubDate>Wed, 03 Jan 2018 23:53:20 +0000</pubDate>
      <link>https://dev.to/kevinjalbert/start-now-architecture-decision-records-580</link>
      <guid>https://dev.to/kevinjalbert/start-now-architecture-decision-records-580</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image &lt;a href="https://flickr.com/photos/mightymightymatze/2150298078"&gt;Filing cabinet&lt;/a&gt; by &lt;a href="https://flickr.com/people/mightymightymatze"&gt;mightymightymatze&lt;/a&gt; is licensed under &lt;a href="https://creativecommons.org/licenses/by-nc/2.0/"&gt;CC BY-NC&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While working on any project, you’ll eventually need to make decisions regarding the task at hand. The decision that has to be made can vary in size and impact. Often we are in the context of a team, and these decisions are made in consultation with others. As time progresses, with new and old team members moving on and off the project, we’ll start to question some of those decisions that were made in the past.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why was it done that way?&lt;/p&gt;

&lt;p&gt;Did we not consider this alternative?&lt;/p&gt;

&lt;p&gt;What was the context when that decision was made?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Save the team and yourself future headaches and plan accordingly for these types of questions now, by starting Architecture Decision Records (ADRs) for your project.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are ADRs?
&lt;/h1&gt;

&lt;p&gt;I first read about ADRs in the &lt;a href="http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions"&gt;documenting architecture decisions&lt;/a&gt; blog post by &lt;a href="http://thinkrelevance.com/team/members/michael-nygard"&gt;Michael Nygard&lt;/a&gt;. ADRs are a form of documentation that record any &lt;em&gt;architecturally significant&lt;/em&gt; decisions that impact a project. For an impact to be considered &lt;em&gt;architecturally significant&lt;/em&gt; within a software project context, Micheal stated:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;… those that affect the structure, non-functional characteristics, dependencies, interfaces, or construction techniques.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Michael’s blog post was focused on ADRs within the context of an agile software project, but I believe it can be applied across different domains. The affected values for what a decision might impact would have to be altered to suit the appropriate domain. For example, altering the customer support workflow could constitute a decision record as it significantly changes a business process.&lt;/p&gt;

&lt;p&gt;I had recently read that &lt;a href="https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records"&gt;lightweight architecture decision records&lt;/a&gt; had made it into the &lt;em&gt;adopt&lt;/em&gt; ring of &lt;a href="https://www.thoughtworks.com/radar"&gt;Thoughtworks Technology Radar&lt;/a&gt; in the November 2017 edition. They note that the lightweight aspect of ADRs is to just have text/markdown files alongside software projects in their repositories.&lt;/p&gt;

&lt;p&gt;Here is an example ADR (pretty meta as it is about starting ADRs):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 1. Record architecture decisions

Date: 2018-01-03

## Status

Accepted

## Context

We need to record the architectural decisions made on this project.

## Decision

We will use Architecture Decision Records, as described by Michael Nygard in this article: http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions

## Consequences

See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's _adr-tools_ at https://github.com/npryce/adr-tools.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don’t want to go into technical details of ADRs, as this blog post is to bring awareness to them, as well as tools/techniques around them. There is plenty of supplementary material in this blog post via links to other articles.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started with ADRs
&lt;/h1&gt;

&lt;p&gt;The biggest thing when adopting ADRs in your project is being consistent with them. As with any added process, it’s easy to simply overlook the new parts if they aren’t at the forefront of your mind. Within our software projects, we actually incorporate ADR consideration in our &lt;a href="https://help.github.com/articles/creating-a-pull-request-template-for-your-repository/"&gt;GitHub pull request template&lt;/a&gt;. It’s a good idea to make sure all team members are all in agreement with using ADRs, as well as when to make one. You don’t want a decision to be made that is not documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplify ADRs with &lt;code&gt;adr-tools&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In addition to including a note about ADRs in our pull request template, there is more tooling to help out. In the spirit of being lightweight records, markdown files are the preferred way to write ADRs. The &lt;a href="https://github.com/npryce/adr-tools"&gt;&lt;code&gt;adr-tools&lt;/code&gt; command line tool&lt;/a&gt; is a great way to simplify the creation of ADRs. If you are on MacOS, back in May 2017, I got &lt;a href="https://github.com/Homebrew/homebrew-core/pull/13081"&gt;adr-tools accepted into homebrew&lt;/a&gt;, so now you can just &lt;code&gt;brew install adr-tools&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are a lot of configurations and features that exist within &lt;code&gt;adr-tools&lt;/code&gt;. I’m going to go over some of the essentials, with examples. I highly recommend taking a deeper look into the tool itself to get the most out of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialize Repository
&lt;/h3&gt;

&lt;p&gt;With a new repository, you get started with &lt;code&gt;adr init&lt;/code&gt;, which creates the following &lt;code&gt;doc/adr/0001-record-architecture-decisions.md&lt;/code&gt; file for you. The contents of this ADR is actually the sample one presented above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create New ADRs
&lt;/h3&gt;

&lt;p&gt;When you want to add a new ADR, you can execute &lt;code&gt;adr new "Split up component XXXX into two modules"&lt;/code&gt; which opens up a basic ADR template to fill in. It creates the next incremented ADR – &lt;code&gt;doc/adr/0002-split-up-component-xxxx-into-two-modules.md&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintain Table of Contents
&lt;/h3&gt;

&lt;p&gt;Most software projects have a &lt;code&gt;README.md&lt;/code&gt; file. When working with ADRs, I include a hyperlink to &lt;code&gt;/doc/adr/README.md&lt;/code&gt;. This file can be generated using &lt;code&gt;adr generate toc &amp;gt; ./docs/adr/README.md&lt;/code&gt;, and ends up creating a nice table of contents of the current ADRs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Architecture Decision Records

* [1. Record architecture decisions](0001-record-architecture-decisions.md)
* [2. Split up component XXXX into two modules](0002-split-up-component-xxxx-into-two-modules.md)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Superseding Existing ADRs
&lt;/h3&gt;

&lt;p&gt;Eventually, you will have a decision which is somehow &lt;em&gt;linked&lt;/em&gt; to another ADR. A great example of this is a new ADR which supersedes an older decision. First let us make a new ADR &lt;code&gt;adr new -s 2 "Combine modules back into one component"&lt;/code&gt;, which ends up superseding our earlier decision. This will actually modify the ADR’s &lt;em&gt;status&lt;/em&gt; section by adding the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# In 0002-split-up-component-xxxx-into-two-modules.md
Superseded by [3. Combine modules back into one component](0003-combine-modules-back-into-one-component.md)

# In 0003-combine-modules-back-into-one-component.md
Superseds [2. Split up component XXXX into two modules](0002-split-up-component-xxxx-into-two-modules.md)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is useful to see how ADRs relate to each other. In our example, we’re indicating one ADR that supersedes another. It is possible to use &lt;code&gt;adr link&lt;/code&gt; to specifically tailor the link to use different wording, so you can be specific in how ADRs are associated. Ultimately, linking provides additional context surrounding linked decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualizing ADRs
&lt;/h3&gt;

&lt;p&gt;With the ability to &lt;em&gt;link&lt;/em&gt; ADRs together, it now becomes possible to trace the story of a specific ADR. By following links you can understand the &lt;em&gt;bigger picture&lt;/em&gt; of how the architecture evolved over time. It can be hard to navigate one file at a time, so fortunately for us, &lt;code&gt;adr-tools&lt;/code&gt; has us covered by being able to produce a visualization of the ADRs.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;adr generate graph | dot -Tjpg &amp;gt; graph.jpg&lt;/code&gt; we can generate the following image (using our example ADRs so far):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_JwDY1mN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kevinjalbert.com/images/2018-01-03-start-now-architecture-decision-records/graph.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_JwDY1mN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kevinjalbert.com/images/2018-01-03-start-now-architecture-decision-records/graph.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is quite apparent to see the ADR links in this diagram. I personally have not seen how well this scales, although it still is a good technique to be aware of.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;adr generate graph&lt;/code&gt; by itself will return a &lt;a href="https://graphviz.gitlab.io/"&gt;graphviz&lt;/a&gt; output. It would be interesting to attach this to the &lt;code&gt;/doc/adr/README.md&lt;/code&gt; using the &lt;a href="https://github.com/TLmaK0/gravizo"&gt;gravizo&lt;/a&gt; service. This way, the ADR visualization is always within reach and can be apart of the normal process when adding new ADRs. I have not personally done this approach, but it looks interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Searching ADRs
&lt;/h2&gt;

&lt;p&gt;As we’re just dealing with markdown files, it becomes trivial to search through the ADRs. The file names are the titles, so even at a glance, it becomes easy to narrow down what you are looking for. You can even use &lt;code&gt;adr list&lt;/code&gt; to just list all the ADRs. In combination with other command line tools (i.e., grep) you can filter the list. I personally like using the &lt;a href="https://github.com/junegunn/fzf"&gt;&lt;code&gt;fzf&lt;/code&gt; command line tool&lt;/a&gt; to filter the list and open it in vim: &lt;code&gt;adr list | fzf | xargs vim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to dig deeper you can search the contents of the files for what you are looking for. For example, &lt;code&gt;grep -l 'tool' ./doc/adr/*.md | fzf | xargs vim&lt;/code&gt; would look for any file with &lt;em&gt;tool&lt;/em&gt; in it, and present the &lt;code&gt;fzf&lt;/code&gt; interface for further filtering.&lt;/p&gt;

&lt;p&gt;In the end, you can be creative on how you search through ADRs – there is a lot of flexibility built into it. I usually use the &lt;a href="https://github.com/aykamko/tag"&gt;&lt;code&gt;tag&lt;/code&gt; command line tool&lt;/a&gt; for searching within files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing ADRs
&lt;/h2&gt;

&lt;p&gt;At this point, you might be thinking &lt;em&gt;“ADRs sound great, but it doesn’t quite satisfy all my needs”&lt;/em&gt;. The concept of ADRs is very general and flexible in nature so that if you have specific needs or requirements, you can customize it. In our case, we’ve been using &lt;code&gt;adr-tools&lt;/code&gt; and it has a base template. You can change it, or use a different template. For example, it might be useful to look through &lt;a href="https://github.com/joelparkerhenderson/architecture_decision_record"&gt;other templates&lt;/a&gt; to find one that fits your needs.&lt;/p&gt;

&lt;p&gt;This post has been talking about using markdown files, but your ADRs could be held in any other medium (i.e., JIRA, Google Docs, etc…). I would argue to use what works best for your team. In most cases, within a software project, the markdown approach is nice as it’s very lightweight and everything is contained in the source directory.&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;ADRs are a great way keep records of architectural decisions&lt;/li&gt;
&lt;li&gt;ADRs provide context surrounding architectural decisions&lt;/li&gt;
&lt;li&gt;ADRs can be lightweight as markdown files that live within your project’s repository&lt;/li&gt;
&lt;li&gt;ADRs are searchable and customizable&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The best time to start ADRs is at the start of a project; the second best time is right now&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>architecture</category>
      <category>tips</category>
      <category>collaboration</category>
      <category>documentation</category>
    </item>
  </channel>
</rss>
