<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Steve Cavender</title>
        <link>https://cavender.foo</link>
        <description>Digital Garden of Steve Cavender</description>
        <lastBuildDate>Tue, 29 Sep 2026 18:14:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Steve Cavender</title>
            <url>https://cavender.foo/favicon.svg</url>
            <link>https://cavender.foo</link>
        </image>
        <copyright>copyright 2026 Stephen Cavender all rights reserved</copyright>
        <atom:link href="https://cavender.foo/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[React Native Environment Setup]]></title>
            <link>https://cavender.foo/articles/react-native-env</link>
            <guid>https://cavender.foo/articles/react-native-env</guid>
            <pubDate>Mon, 24 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[A primer on setting up an environment for react native projects]]></description>
            <content:encoded><![CDATA[<p>I enjoy building apps in react native. Yet, configuring my system to run them is a pain. In this article I’ll outline how I’ve tried to make it less painful.</p>
<h2 id="node">Node</h2>
<p>React native uses node to interface with the native JS runtime on Android and iOS. The runtime allows for hooks into native code which is how we can build high performing native apps.
I use NVM to manage my node installs. It lets me manage many versions for various projects.</p>
<h2 id="watchman">Watchman</h2>
<p>React native uses watchman to watch changes, compile, and refresh the app on your device. I install this from brew; no management required.</p>
<h2 id="ruby">Ruby</h2>
<p>React native needs ruby to use CocoaPods (a ruby gem) for handling iOS dependencies. I started out using rvm but have since switched to rbenv. Both libraries allow managing ruby version. I found rbenv much easier to set up than rvm.</p>
<h2 id="xcode">Xcode</h2>
<p>React native needs Xcode for iOS development tooling including the iOS simulator. For a while I installed this via the Mac App Store but downloads took forever and sometimes got stuck. I have switched to using Xcodes to manage having many versions of Xcode installed. Downloads don’t take as long and have not gotten stuck thus far.</p>
<h2 id="jdk">JDK</h2>
<p>React native needs a JDK for Android development. I use jenv to manage jdk versions and prefer openJDKs. I grab openJDKs from brew and add them into jenv.</p>
<h2 id="android-studio">Android Studio</h2>
<p>React native needs Android Studio for Android development tooling. During install include Android SDK, Android SDK Platform, and Android Virtual Device. The latest Android SDK installs by default. Check that it’s compatible with the version of react native you’re using. You can use the SDK Manager within Android Studio to install the correct version. In order for react native to build apps with native code some environment variables need set up.</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>export ANDROID_HOME=$HOME/Library/Android/sdk</span></span>
<span class="line"><span>export PATH=$PATH:$ANDROID_HOME/emulator</span></span>
<span class="line"><span>export PATH=$PATH:$ANDROID_HOME/platform-tools</span></span></code></pre>
<h2 id="create-an-app">Create An App</h2>
<p>At this point the system is set up to run react native applications. There are several options for spinning up a new react native app. I have used the CLI to create apps with and without expo. I have also used a 3rd party CLI called Ignite from InfiniteRed. My next project will use a template from TheCodingMachine called React Native Boilerplate.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native SVG Example]]></title>
            <link>https://cavender.foo/articles/react-native-svg</link>
            <guid>https://cavender.foo/articles/react-native-svg</guid>
            <pubDate>Sat, 10 Apr 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Working with SVGs in React Native]]></description>
            <content:encoded><![CDATA[<p>In this article we’ll be creating a react native application and updating it to show SVGs.</p>
<p>To begin we’ll need a React Native application to add SVGs to. Either create a new one with the <code>npx react-native init PROJECTNAME</code> command or use existing app but you’ll have to check version compatibility. Our next step is to fire up the app. I run <code>npm run start</code> which just calls <code>react-native start</code>. Now metro is running in this terminal and we need to open a new terminal. In the new terminal let’s fire up the app in either iOS or Android. I started with Android so I ran <code>npm run android</code> which just runs <code>react-native run-android</code>. Now we have an Android emulator running our app! Here’s a screenshot of where we’re at on Android:</p>
<p><img src="https://cavender.foo/_astro/init.DDxjcYmn_1XLHiC.webp" alt="Initial Screen" loading="lazy" decoding="async" width="200" height="422"></p>
<h2 id="drawing-svgs">Drawing SVGs</h2>
<p>React Native doesn’t support SVG out of the box. So we’ll have to install a package to handle SVGs for us. I chose <a href="https://github.com/react-native-svg/react-native-svg">svg-react-native</a>. Here’s where we need to pay attention to the versions we’re on. There are various steps to getting this package to work in the app depending on the versions it has. Be sure to read through the Readme and the <a href="https://github.com/react-native-svg/react-native-svg#notice">table of versions</a>. Since I’m on a brand new app I ran <code>npm i react-native-svg</code> to install the latest. Now with the package installed we can import it and start drawing SVGs in our app! I added a separate component to contain my SVG: <code>/components/svg.js</code>. Here’s my component code:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> React </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#F97583"> type</span><span style="color:#E1E4E8"> { Node } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> Svg, { Circle, Rect, Path } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react-native-svg&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> { View } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react-native&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> SvgComp</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ()</span><span style="color:#F97583">:</span><span style="color:#B392F0"> Node</span><span style="color:#F97583"> =&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#B392F0">View</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#F97583">      &lt;</span><span style="color:#E1E4E8">Svg height</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;100&quot;</span><span style="color:#E1E4E8"> width</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;100&quot;</span><span style="color:#F97583">&gt;</span></span>
<span class="line"><span style="color:#F97583">        &lt;</span><span style="color:#E1E4E8">Rect x</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;0&quot;</span><span style="color:#E1E4E8"> y</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;0&quot;</span><span style="color:#E1E4E8"> width</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;100&quot;</span><span style="color:#E1E4E8"> height</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;100&quot;</span><span style="color:#E1E4E8"> fill</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;black&quot;</span><span style="color:#F97583"> /&gt;</span></span>
<span class="line"><span style="color:#F97583">        &lt;</span><span style="color:#E1E4E8">Circle cx</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;50&quot;</span><span style="color:#E1E4E8"> cy</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;50&quot;</span><span style="color:#E1E4E8"> r</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;30&quot;</span><span style="color:#E1E4E8"> fill</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;yellow&quot;</span><span style="color:#F97583"> /&gt;</span></span>
<span class="line"><span style="color:#F97583">        &lt;</span><span style="color:#E1E4E8">Circle cx</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;40&quot;</span><span style="color:#E1E4E8"> cy</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;40&quot;</span><span style="color:#E1E4E8"> r</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;4&quot;</span><span style="color:#E1E4E8"> fill</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;black&quot;</span><span style="color:#F97583"> /&gt;</span></span>
<span class="line"><span style="color:#F97583">        &lt;</span><span style="color:#E1E4E8">Circle cx</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;60&quot;</span><span style="color:#E1E4E8"> cy</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;40&quot;</span><span style="color:#E1E4E8"> r</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;4&quot;</span><span style="color:#E1E4E8"> fill</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;black&quot;</span><span style="color:#F97583"> /&gt;</span></span>
<span class="line"><span style="color:#F97583">        &lt;</span><span style="color:#E1E4E8">Path d</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;M 40 60 A 10 10 0 0 0 60 60&quot;</span><span style="color:#E1E4E8"> stroke</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;black&quot;</span><span style="color:#F97583"> /&gt;</span></span>
<span class="line"><span style="color:#F97583">      &lt;/</span><span style="color:#E1E4E8">Svg</span><span style="color:#F97583">&gt;</span></span>
<span class="line"><span style="color:#F97583">    &lt;/</span><span style="color:#E1E4E8">View</span><span style="color:#F97583">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> SvgComp;</span></span></code></pre>
<p>And here’s a screenshot of how it renders in the Android emulator:</p>
<p><img src="https://cavender.foo/_astro/drawing.CsHRRBZ9_i2ASW.webp" alt="SVG Drawing" loading="lazy" decoding="async" width="200" height="422"></p>
<hr/>
<p><strong>NOTE</strong></p>
<p>I had to restart metro and re-run the android command to get SVGs working.</p>
<hr/>
<p>Check out the <a href="https://github.com/react-native-svg/react-native-svg#supported-elements">supported elements</a> to see what else we can do with SVGs now.</p>
<h2 id="using-svg-files">Using SVG Files</h2>
<p>Maybe we have some SVG files we want to include rather than drawing them. For this case we’ll need another package. <a href="https://github.com/kristerkari">Kristerkari</a> has us covered with <a href="https://github.com/kristerkari/react-native-svg-transformer">react-native-svg-transformer</a>. Install the package with <code>npm i --save-dev react-native-svg-transformer</code>. Next we’ll update our metro config to handle transforming SVGs. Here’s what my metro.config.js looks like now:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="js"><code><span class="line"><span style="color:#F97583">const</span><span style="color:#E1E4E8"> { </span><span style="color:#79B8FF">getDefaultConfig</span><span style="color:#E1E4E8"> } </span><span style="color:#F97583">=</span><span style="color:#B392F0"> require</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;metro-config&quot;</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#79B8FF">module</span><span style="color:#E1E4E8">.</span><span style="color:#79B8FF">exports</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> (</span><span style="color:#F97583">async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#FFAB70">    resolver</span><span style="color:#E1E4E8">: { </span><span style="color:#79B8FF">sourceExts</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">assetExts</span><span style="color:#E1E4E8"> },</span></span>
<span class="line"><span style="color:#E1E4E8">  } </span><span style="color:#F97583">=</span><span style="color:#F97583"> await</span><span style="color:#B392F0"> getDefaultConfig</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8">    transformer: {</span></span>
<span class="line"><span style="color:#B392F0">      getTransformOptions</span><span style="color:#E1E4E8">: </span><span style="color:#F97583">async</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> ({</span></span>
<span class="line"><span style="color:#E1E4E8">        transform: {</span></span>
<span class="line"><span style="color:#E1E4E8">          experimentalImportSupport: </span><span style="color:#79B8FF">false</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">          inlineRequires: </span><span style="color:#79B8FF">true</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        },</span></span>
<span class="line"><span style="color:#E1E4E8">      }),</span></span>
<span class="line"><span style="color:#E1E4E8">      babelTransformerPath: require.</span><span style="color:#B392F0">resolve</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">&quot;react-native-svg-transformer&quot;</span><span style="color:#E1E4E8">),</span></span>
<span class="line"><span style="color:#E1E4E8">    },</span></span>
<span class="line"><span style="color:#E1E4E8">    resolver: {</span></span>
<span class="line"><span style="color:#E1E4E8">      assetExts: assetExts.</span><span style="color:#B392F0">filter</span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70">ext</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> ext </span><span style="color:#F97583">!==</span><span style="color:#9ECBFF"> &quot;svg&quot;</span><span style="color:#E1E4E8">),</span></span>
<span class="line"><span style="color:#E1E4E8">      sourceExts: [</span><span style="color:#F97583">...</span><span style="color:#E1E4E8">sourceExts, </span><span style="color:#9ECBFF">&quot;svg&quot;</span><span style="color:#E1E4E8">],</span></span>
<span class="line"><span style="color:#E1E4E8">    },</span></span>
<span class="line"><span style="color:#E1E4E8">  };</span></span>
<span class="line"><span style="color:#E1E4E8">})();</span></span></code></pre>
<p>I needed some SVG files so I grabbed these:</p>
<ul>
<li>A colorized one: <a href="https://raw.githubusercontent.com/kristerkari/react-native-svg-example/master/logos/firefox.svg">firefox.svg</a> from Kristerkari’s <a href="https://github.com/kristerkari/react-native-svg-example">example repo</a></li>
<li>And a customizable one: <a href="https://feathericons.com/?query=coffee">coffee.svg</a> from Feather</li>
</ul>
<p>And another new component for SVG files: <code>./components/svg-files.js</code>. Here’s the component code:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> React </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#F97583"> type</span><span style="color:#E1E4E8"> { Node } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> { View } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react-native&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> Coffee </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;../assets/icons/coffee.svg&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> Firefox </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;../assets/icons/firefox.svg&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> SvgFilesComp</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ()</span><span style="color:#F97583">:</span><span style="color:#B392F0"> Node</span><span style="color:#F97583"> =&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#B392F0">View</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#F97583">      &lt;</span><span style="color:#E1E4E8">Firefox </span><span style="color:#F97583">/&gt;</span></span>
<span class="line"><span style="color:#F97583">      &lt;</span><span style="color:#E1E4E8">Coffee </span><span style="color:#F97583">/&gt;</span></span>
<span class="line"><span style="color:#F97583">    &lt;/</span><span style="color:#E1E4E8">View</span><span style="color:#F97583">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> SvgFilesComp;</span></span></code></pre>
<p>And here’s a screenshot of how it renders in the Android emulator:</p>
<p><img src="https://cavender.foo/_astro/file-1.D0MYCfqL_1sG22O.webp" alt="SVG File Initial Screen" loading="lazy" decoding="async" width="200" height="422"></p>
<hr/>
<p><strong>NOTE</strong></p>
<p>I had to restart metro and re-run the android command to get SVGs working.</p>
<hr/>
<p>Notice that our coffee SVG isn’t visible but taking space. That’s because its designed to be customizable. We need to pass in some arguments if we want it to render in color. Which arguments and whether it’s customizable at all depends on the SVG.</p>
<p>For instance, both SVGs I chose have widths and heights set for them. If we don’t include those properties then their defaults are used. If we pass in a width to the firefox SVG check out what happens:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="js"><code><span class="line"><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Firefox</span><span style="color:#B392F0"> width</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">50</span><span style="color:#E1E4E8">} /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Coffee</span><span style="color:#E1E4E8"> /&gt;</span></span></code></pre>
<p><img src="https://cavender.foo/_astro/file-2.D5StRnH-_Z2m781H.webp" alt="SVG File Firefox Width" loading="lazy" decoding="async" width="200" height="422"></p>
<p>The image is the correct size but the overall SVG is still taking up a lot more room than it needs. We have to pass in both sizes to fix this. While we’re at it, let’s give some color to our coffee icon by passing in a fill color.</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="js"><code><span class="line"><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Firefox</span><span style="color:#B392F0"> width</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">50</span><span style="color:#E1E4E8">} </span><span style="color:#B392F0">height</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">50</span><span style="color:#E1E4E8">} /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Coffee</span><span style="color:#B392F0"> fill</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#9ECBFF">&#39;blue&#39;</span><span style="color:#E1E4E8">} /&gt;</span></span></code></pre>
<p><img src="https://cavender.foo/_astro/file-3.DzCb0X2v_yPaFg.webp" alt="SVG File Firefox Size Coffee Fill" loading="lazy" decoding="async" width="200" height="422"></p>
<p>Now our firefox looks good but our coffee icon does not. This particular icon isn’t meant to have a fill. Rather, we should pass in a stroke to get the desired look.</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="js"><code><span class="line"><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Firefox</span><span style="color:#B392F0"> width</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">50</span><span style="color:#E1E4E8">} </span><span style="color:#B392F0">height</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">50</span><span style="color:#E1E4E8">} /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">&lt;</span><span style="color:#79B8FF">Coffee</span><span style="color:#B392F0"> stroke</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#9ECBFF">&#39;#333&#39;</span><span style="color:#E1E4E8">} /&gt;</span></span></code></pre>
<p><img src="https://cavender.foo/_astro/file-4.BLekrSvM_ZyQ6lp.webp" alt="SVG File Final" loading="lazy" decoding="async" width="200" height="422"></p>
<h2 id="using-an-svg-font">Using an SVG Font</h2>
<p>Now let’s pull in an SVG font with a bunch of icons we can use. I chose a set of open source icons called <a href="https://feathericons.com/">Feather</a>. Install Feather with <code>npm i feather-icons</code> and grab an SVG file. I created another separate component to try out Feather icons in my app: <code>/components/feather.js</code>. Here’s my component code:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8;overflow-x:auto" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> React </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#F97583"> type</span><span style="color:#E1E4E8"> { Node } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> { View } </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;react-native&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> ArrowUpCircle </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> &quot;feather-icons/dist/icons/arrow-up-circle.svg&quot;</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> FeatherComp</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ()</span><span style="color:#F97583">:</span><span style="color:#B392F0"> Node</span><span style="color:#F97583"> =&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#B392F0">View</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#F97583">      &lt;</span><span style="color:#E1E4E8">ArrowUpCircle stroke</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;red&quot;</span><span style="color:#E1E4E8"> fill</span><span style="color:#F97583">=</span><span style="color:#9ECBFF">&quot;#fff&quot;</span><span style="color:#E1E4E8"> width</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">32</span><span style="color:#E1E4E8">} height</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">32</span><span style="color:#E1E4E8">} </span><span style="color:#F97583">/&gt;</span></span>
<span class="line"><span style="color:#F97583">    &lt;/</span><span style="color:#E1E4E8">View</span><span style="color:#F97583">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> default</span><span style="color:#E1E4E8"> FeatherComp;</span></span></code></pre>
<p>And here’s a screenshot of how it renders in the Android emulator:</p>
<p><img src="https://cavender.foo/_astro/feather-1.-c1xNaKo_1fxb15.webp" alt="Feather Icon" loading="lazy" decoding="async" width="200" height="422"></p>
<p>This is great because now we have access to all of the Feather icons as React components. But what if we had an SVG file we wanted to use?</p>
<p>Now those are some good looking SVGs in a React Native app!</p>
<h2 id="conclusion">Conclusion</h2>
<p>In this article we covered how to include SVGs inside a React Native application using three different methods:</p>
<ol>
<li>Drawing them</li>
<li>Importing an SVG font</li>
<li>Loading from .svg files</li>
</ol>
<p>Thanks for reading!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MacOS OpenJDK Maintenance]]></title>
            <link>https://cavender.foo/articles/macos-openjdk-maintenance</link>
            <guid>https://cavender.foo/articles/macos-openjdk-maintenance</guid>
            <pubDate>Sun, 21 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Maintaining multiple OpenJDK versions on MacOS]]></description>
            <content:encoded><![CDATA[<p>In this article we’ll be looking at OpenJDK, an open-source implementation of the Java platform SE. To read more check out <a href="https://openjdk.java.net/">official site</a>.</p>
<h2 id="why-have-multiple-versions">Why have multiple versions?</h2>
<p>Why not? Not all apps are able to keep up with Java versions and those that do might need some time when a new version comes out. For example: I’m working with React Native building mobile apps for both iOS and Android. To build the Android app it uses Gradle 6.5 which doesn’t support the latest version of Java (16) yet.</p>
<h2 id="installing">Installing</h2>
<p>I have OpenJDK installed through AdoptOpenJDK using brew. I like to keep all my apps and libs as up-to-date as possible so I run <code>brew upgrade</code> a lot. One of those times it upgraded AdoptOpenJDK to 16. Lucky for me they also publish older versions on brew but there’s an extra step.</p>
<p>My initial thought was to run <code>brew install adoptopenjdk@15</code> but it didn’t work. The versioned casks are contained in their Tap which I found out by checking out their <a href="https://formulae.brew.sh/cask/adoptopenjdk#default">brew page</a> and subsequently their <a href="https://github.com/AdoptOpenJDK/homebrew-openjdk">open-source tap code</a>.</p>
<p>So the fix was to get into the tap (<code>brew tap adoptopenjdk/openjdk</code>) and run the command above again.</p>
<h2 id="switching-between-versions">Switching between versions</h2>
<p>Now I have two versions of OpenJDK available to my system: 16 and 15. To switch between them I found a little function to pop into my .zshrc file:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#B392F0">jdk</span><span style="color:#E1E4E8">() {</span></span>
<span class="line"><span style="color:#F97583">  export</span><span style="color:#E1E4E8"> JAVA_VERSION</span><span style="color:#F97583">=</span><span style="color:#FFAB70">$1</span></span>
<span class="line"><span style="color:#B392F0">  java</span><span style="color:#79B8FF"> -version</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre>
<p>Now to switch between JDK versions I run <code>jdk 15</code> or any version I have installed.</p>
<p>Thanks for reading!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dev Setup]]></title>
            <link>https://cavender.foo/articles/dev-setup</link>
            <guid>https://cavender.foo/articles/dev-setup</guid>
            <pubDate>Mon, 16 Nov 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[A quick rundown of my personal development setup]]></description>
            <content:encoded><![CDATA[<p>I try to keep my setup pretty minimal but the following is my list of must-haves. All are easily <a href="https://startpage.com">searchable</a> so I have not included links except to my settings hosted as GitHub Gists.</p>
<ul>
<li>Physical
<ul>
<li>MacBook Air (Light but powerful)</li>
<li>Logitech MX Master 2S</li>
<li>Bose QC 25</li>
<li>Fidget Spinner</li>
<li>Moleskine grid notebook</li>
<li>Lamy Safari Fountain Pen</li>
<li>Blackwing Pencil</li>
</ul>
</li>
<li>Digital
<ul>
<li>Zsh (as well as Oh-my-zsh and zsh-completions)
<ul>
<li><a href="https://gist.github.com/StephenCavender/91a3243a8b26d14f3ae6d0b747d2bba3">.zshrc</a></li>
</ul>
</li>
<li>Brew</li>
<li>NVM</li>
<li>RVM</li>
<li>VSCodium (No MS branding/telemetry)
<ul>
<li>Extensions:
<ul>
<li>Bookmarks</li>
<li>Bracket Pair Colorizer 2</li>
<li>ES7 React/Recux/GraphQL/React-native Snippets</li>
<li>ESLint</li>
<li>GitLens</li>
<li>JavaScript (ES6) code snippets</li>
<li>Live Server</li>
<li>Material Icon Theme</li>
<li>Night Owl</li>
<li>REST Client</li>
<li>SVG</li>
<li>TODO Highlight</li>
<li>YAML</li>
</ul>
</li>
<li><a href="https://gist.github.com/StephenCavender/f821dd072238ba388d86da38903e8fc8">Settings</a></li>
</ul>
</li>
<li>Firefox (main driver)</li>
<li>Hyper</li>
<li>LICEcap</li>
<li>OBS</li>
<li>Chromium (for testing apps)</li>
<li>Chrome (for testing apps)</li>
<li>Vanilla</li>
<li>Time Out</li>
<li>OpenJDK</li>
<li>Nginx</li>
<li>SVGO</li>
</ul>
</li>
</ul>
<p>Thanks for reading!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dual-booting Linux Mint]]></title>
            <link>https://cavender.foo/articles/linux-dual-boot</link>
            <guid>https://cavender.foo/articles/linux-dual-boot</guid>
            <pubDate>Fri, 08 Nov 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[How and why I installed Linux Mint and chose to dual-boot between it and Windows]]></description>
            <content:encoded><![CDATA[<p>I’ve always heard that Linux is the way to go but I never tried it. I had Windows and it worked fine for me. I took some training at work that required Linux so I started using it inside a virtual machine. I got comfortable with it and decided it would be fun to try at home.</p>
<h2 id="why-mint">Why Mint</h2>
<p>Based on this <a href="https://dev.to/pluralsight/which-distribution-of-linux-should-i-use-51g7">Dev.to</a> article it sounded like where a Linux newbie like myself should start. I tried a couple versions inside VirtualBox before committing. I used <a href="https://www.osboxes.org/">OSBoxes</a> to quickly get them up and running.</p>
<h2 id="why-dual-boot">Why Dual-Boot</h2>
<p>I chose to dual-boot because I didn’t want to risk losing Windows if I messed up the Mint install. Also because the Mint install made it really easy.</p>
<h2 id="how-i-did-it">How I did it</h2>
<h3 id="disclaimer">Disclaimer!</h3>
<p>I’ll recount the steps I took and the references I used but can’t guarantee any of it for anyone else.
Also it’s a good idea to follow along with <a href="https://www.linuxmint.com/documentation.php">Mint’s install docs</a>.</p>
<h3 id="1-back-up-data">1. Back Up Data</h3>
<p>I backed up my data because there’s always a chance it could get wiped from existence.</p>
<h3 id="2-download-linux-mint">2. Download Linux Mint</h3>
<p>I grabbed the 64bit Cinnamon version from <a href="https://linuxmint.com/download.php">here</a>.</p>
<h3 id="3-create-a-bootable-usb">3. Create a Bootable USB</h3>
<p>I used <a href="https://www.balena.io/etcher/">Etcher</a> to flash the image onto my USB drive but any flashing software should do the trick.
<img alt="Etcher UI" loading="lazy" decoding="async" width="995" height="565" src="https://cavender.foo/_astro/etcher.BoUCK95C_1LL3dQ.webp" srcset=""></p>
<h3 id="4-create-disk-space">4. Create Disk Space</h3>
<p>My first attempt didn’t take because I didn’t have any room. I ended up freeing up some space from my Windows partitions.
<img alt="Disk Management Window" loading="lazy" decoding="async" width="942" height="746" src="https://cavender.foo/_astro/disk.CNItBbI1_1yxVXu.webp" srcset=""></p>
<h3 id="5-update-boot-configuration">5. Update Boot Configuration</h3>
<p>I had to disable secure boot and change the boot order in the BIOS.</p>
<h3 id="6-install-mint">6. Install Mint</h3>
<p>I followed the on-screen instructions at this point. Here are the important bits:</p>
<ul>
<li>Dual booting with Windows</li>
<li>Create partitions
<ul>
<li>Root (I used 20Gb)</li>
<li>Swap (I used 8Gb)</li>
<li>Home (I used the rest of my free space)
A few more on-screen instructions and I was ready to go!</li>
</ul>
</li>
</ul>
<h3 id="7-use-mint">7. Use Mint</h3>
<p>Mint is installed and ready to go. I’m on a Razer Blade Stealth and everything works out of the box except for closing the lid. I’m sure there are other things that don’t quite work that I haven’t encountered yet. When I close the lid Mint is supposed to suspend but when I open the lid back up I have to hard shutdown before my laptop will wake up and respond.
Other than that I’m very happy with Mint and hope that this article helps you!</p>
<p>Thanks for reading!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JavaScript Selenium Mocha QuickStart Guide]]></title>
            <link>https://cavender.foo/articles/js-selenium-mocha-quickstart</link>
            <guid>https://cavender.foo/articles/js-selenium-mocha-quickstart</guid>
            <pubDate>Wed, 20 Jul 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[A quick how-to on setting up a solution using Mocha and Selenium!]]></description>
            <content:encoded><![CDATA[<p>In this article we’ll be using Mocha and Selenium to write tests for web applications. This will be a starter project we can build on for various projects and in future articles.</p>
<h3 id="requirements">Requirements</h3>
<p>Here are the requirements before we get started:</p>
<ul>
<li><a href="https://nodejs.org">NodeJS</a> (A JavaScript runtime)</li>
<li><a href="https://www.selenium.dev/downloads/">Selenium JavaScript language bindings</a> (But we’ll use NPM to grab these)</li>
<li><a href="http://mochajs.org/">MochaJS</a> (Mocha is a JS test framework)</li>
<li><a href="http://chaijs.com/">ChaiJS</a> (Chai is an assertion library)</li>
<li>Any browsers installed that you want to test <a href="https://www.selenium.dev/downloads/#platforms-supported-by-selenium">Supported Platforms</a></li>
</ul>
<h3 id="selenium-prep">Selenium Prep</h3>
<p>If you haven’t read through my quick <a href="https://cavender.foo/articles/selenium-overview-setup">Overview of Selenium</a> you should do that now. Selenium will need a few things configured before it’ll do its magic!</p>
<h3 id="nodejs-tutorial">NodeJs Tutorial</h3>
<p>If you’re unfamiliar with NodeJS I recommend this tutorial to get you started: <a href="https://blog.risingstack.com/node-hero-tutorial-getting-started-with-node-js/">NodeHero</a>. It’s packed with helpful information. It’s a good resource to keep open in a tab while working through this post.</p>
<h3 id="create-project">Create Project</h3>
<p>To kick things off we’ll need a new project. Using a command prompt or Explorer we need to create a new folder for our project. Once we have our folder we can use the command prompt to begin installing the packages we’ll need.</p>
<h3 id="initializing-project">Initializing Project</h3>
<p>NodeJS comes with its own package manager: NPM. It is also used to initialize a project. Run the following command and fill in each section: <code>npm init</code>.
This will create the <strong>package.json</strong> file. This file tracks dependencies and project information.</p>
<h3 id="installing-packages">Installing Packages</h3>
<p>NPM is also responsible for installing packages. The command for installing a package is <code>npm install &lt;package&gt;</code>. We need to install Selenium, Mocha and Chai.</p>
<ul>
<li><code>npm install selenium-webdriver --save</code></li>
<li><code>npm install mocha --save</code></li>
<li><code>npm install chai --save</code></li>
</ul>
<p>These will install in the <strong>node_modules</strong> folder and get tracked in our <strong>package.json</strong> file.</p>
<p>We can now write our first test and use our installed packages! Here’s what the package.json file should look like at this point:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="json"><code><span class="line"><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#79B8FF">  "name"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"selenium-js-mocha"</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">  "version"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"1.0.0"</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">  "description"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"A project to go along with blog posts explaining how to get started with</span></span>
<span class="line"><span style="color:#9ECBFF">  functional testing using Selenium, JavaScript and Mocha. "</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">  "main"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"test1.js"</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">  "dependencies"</span><span style="color:#E1E4E8">: {</span></span>
<span class="line"><span style="color:#79B8FF">    "chai"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"^3.5.0"</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">    "mocha"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"^2.5.3"</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">    "selenium-webdriver"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"^2.53.2"</span></span>
<span class="line"><span style="color:#E1E4E8">  },</span></span>
<span class="line"><span style="color:#79B8FF">  "devDependencies"</span><span style="color:#E1E4E8">: {},</span></span>
<span class="line"><span style="color:#79B8FF">  "scripts"</span><span style="color:#E1E4E8">: {</span></span>
<span class="line"><span style="color:#79B8FF">    "test"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"mocha test1.js"</span></span>
<span class="line"><span style="color:#E1E4E8">  },</span></span>
<span class="line"><span style="color:#79B8FF">  "author"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"Stephen Cavender"</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#79B8FF">  "license"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"ISC"</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre>
<h3 id="write-test">Write Test</h3>
<p>We’ll write our test against <a href="http://the-internet.herokuapp.com/">The Internet</a><sup><a href="#user-content-fn-theinternet" id="user-content-fnref-theinternet" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.</p>
<p>Let’s create a new JS file in our project folder: I’ll create test1.js.</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="javascript"><code><span class="line"><span style="color:#6A737D">// Load dependecies</span></span>
<span class="line"><span style="color:#F97583">var</span><span style="color:#E1E4E8"> assert </span><span style="color:#F97583">=</span><span style="color:#B392F0"> require</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"chai"</span><span style="color:#E1E4E8">).assert,</span></span>
<span class="line"><span style="color:#E1E4E8">  test </span><span style="color:#F97583">=</span><span style="color:#B392F0"> require</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"selenium-webdriver/testing"</span><span style="color:#E1E4E8">),</span></span>
<span class="line"><span style="color:#E1E4E8">  webdriver </span><span style="color:#F97583">=</span><span style="color:#B392F0"> require</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"selenium-webdriver"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// Our test</span></span>
<span class="line"><span style="color:#E1E4E8">test.</span><span style="color:#B392F0">describe</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Test"</span><span style="color:#E1E4E8">, </span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> () {</span></span>
<span class="line"><span style="color:#E1E4E8">  test.</span><span style="color:#B392F0">it</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'Title should be "The Internet"'</span><span style="color:#E1E4E8">, </span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> () {</span></span>
<span class="line"><span style="color:#6A737D">    // Set timeout to 10 seconds</span></span>
<span class="line"><span style="color:#79B8FF">    this</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">timeout</span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">10000</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">    // Get driver</span></span>
<span class="line"><span style="color:#6A737D">    // var driver = new webdriver.Builder().</span></span>
<span class="line"><span style="color:#6A737D">    // withCapabilities(webdriver.Capabilities.firefox()).</span></span>
<span class="line"><span style="color:#6A737D">    // build();</span></span>
<span class="line"><span style="color:#6A737D">    // var driver = new webdriver.Builder().</span></span>
<span class="line"><span style="color:#6A737D">    // withCapabilities(webdriver.Capabilities.edge()).</span></span>
<span class="line"><span style="color:#6A737D">    // build();</span></span>
<span class="line"><span style="color:#6A737D">    // var driver = new webdriver.Builder().</span></span>
<span class="line"><span style="color:#6A737D">    // withCapabilities(webdriver.Capabilities.ie()).</span></span>
<span class="line"><span style="color:#6A737D">    // build();</span></span>
<span class="line"><span style="color:#F97583">    var</span><span style="color:#E1E4E8"> driver </span><span style="color:#F97583">=</span><span style="color:#F97583"> new</span><span style="color:#E1E4E8"> webdriver.</span><span style="color:#B392F0">Builder</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8">      .</span><span style="color:#B392F0">withCapabilities</span><span style="color:#E1E4E8">(webdriver.Capabilities.</span><span style="color:#B392F0">chrome</span><span style="color:#E1E4E8">())</span></span>
<span class="line"><span style="color:#E1E4E8">      .</span><span style="color:#B392F0">build</span><span style="color:#E1E4E8">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">    // Go to URL</span></span>
<span class="line"><span style="color:#E1E4E8">    driver.</span><span style="color:#B392F0">get</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"http://the-internet.herokuapp.com"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">    // Find title and assert</span></span>
<span class="line"><span style="color:#E1E4E8">    driver.</span><span style="color:#B392F0">executeScript</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"return document.title"</span><span style="color:#E1E4E8">).</span><span style="color:#B392F0">then</span><span style="color:#E1E4E8">(</span><span style="color:#F97583">function</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70">return_value</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#E1E4E8">      assert.</span><span style="color:#B392F0">equal</span><span style="color:#E1E4E8">(return_value, </span><span style="color:#9ECBFF">"The Internet"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">    });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">    // Quit webdriver</span></span>
<span class="line"><span style="color:#E1E4E8">    driver.</span><span style="color:#B392F0">quit</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"><span style="color:#E1E4E8">});</span></span></code></pre>
<ol>
<li>Load dependencies</li>
<li>Create test</li>
<li>Set timeout (test runs too fast and fails without increasing the timeout)</li>
<li>Get a web driver</li>
<li>Set the URL property (tells the driver to go to that URL)</li>
<li>Assert on the title of the driver</li>
<li>Dispose of the driver</li>
</ol>
<h3 id="run-test">Run Test</h3>
<p>Now that we have a functional test we can run it. Save the test file and let’s grab our command prompt. To run tests we call the mocha command and our test file.</p>
<p><code>mocha test1.js</code></p>
<p>Run that in the command prompt and we should see our test run and the command prompt will tell us the result of the test. If the <strong>package.json</strong> is set up with a test script we can also run our test by calling the npm test script.</p>
<p><code>npm test</code></p>
<p>Now our test results will show in the terminal!</p>
<p>This is a basic, and brittle, example of how Selenium works. We’ll cover a much better testing approach in a later post to avoid such things! This is not an example of best practices by any means. This is to get you a working example of Selenium. Stay tuned for more posts on how to use Selenium and best practices for automating tests!</p>
<p>Thanks for reading!</p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-theinternet">
<p>Credit to Dave Haeffner. <a href="#user-content-fnref-theinternet" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Selenium Overview & Setup]]></title>
            <link>https://cavender.foo/articles/selenium-overview-setup</link>
            <guid>https://cavender.foo/articles/selenium-overview-setup</guid>
            <pubDate>Sat, 25 Jun 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[A quick overview of Selenium and guide on getting it ready for glory!]]></description>
            <content:encoded><![CDATA[<p>In this article we’ll explore what Selenium is and how to prep our environment to use it.</p>
<blockquote>
<p>Selenium is an umbrella project for a range of tools and libraries that enable and support the automation of web browsers. - From <a href="https://www.selenium.dev/documentation/">Selenium HQ</a></p>
</blockquote>
<p>Selenium enables us to:</p>
<ol>
<li>Open browsers</li>
<li>Navigate web pages</li>
<li>Find web elements</li>
<li>Manipulate web elements</li>
<li>Run JavaScript</li>
</ol>
<h3 id="language-bindings">Language Bindings</h3>
<p>First we’ll need to get the language bindings we want. The bindings will need to be downloaded and referenced in our project. Some IDE’s have package managers that will do this for us. We’ll talk more about how that’s done in separate articles. For now just know that we’ll need some language bindings to get Selenium to work.</p>
<h3 id="webdrivers">Webdrivers</h3>
<p>Selenium’s power comes from <a href="https://www.selenium.dev/documentation/webdriver/">webdrivers</a>; called such because they “drive the web.” In the articles to come we’ll be using Chrome, Firefox, Edge and IE; we’ll need drivers for each.</p>
<h4 id="chrome">Chrome</h4>
<p><a href="https://developer.chrome.com/docs/chromedriver/downloads/">ChromeDriver</a> is a separate executable loaded by Selenium when Chrome is the desired browser. Download the latest driver and place it in an easily-accessible location. I keep mine in <code>C:/webdrivers/</code>. Download and install the latest <a href="https://www.google.com/intl/en/chrome/browser/desktop/index.html">Chrome</a>.</p>
<h4 id="firefox">Firefox</h4>
<p>The <a href="https://github.com/SeleniumHQ/selenium/wiki/FirefoxDriver">FirefoxDriver</a> comes built-in with the Selenium language bindings. Download and install the latest <a href="https://www.mozilla.org/en-US/firefox/all/">Firefox</a>.
Mozilla is working on a new driver for their browser called <a href="https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette">MarionetteDriver</a>. However, it has not been released as of this writing. Feel free to download the latest driver and put it in the same location as the ChromeDriver.</p>
<h4 id="edge">Edge</h4>
<p>The <a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?form=MA13LH&amp;cs=1385545810">Microsoft WebDriver</a> is a separate executable loaded up by Selenium when Edge is requested as a browser. Download the latest driver and keep it in the same location as the other driver(s). Make sure you have the latest updates for Edge.</p>
<h4 id="ie">IE</h4>
<p>The <a href="https://www.selenium.dev/downloads/">IEDriverServer</a> is maintained and distributed by the Selenium group. Download the latest driver and put it in the same location as the other driver(s). Make sure you have the latest updates for IE.</p>
<h3 id="adding-to-path">Adding to PATH</h3>
<p>Now that we have all the drivers we’ll want to use we need to add an entry to our PATH environment variable. If you’ve never done anything with environment variables I would recommend reading this <a href="http://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/">guide</a>. Follow the instructions and add the folder containing your webdrivers.</p>
<p>Now Selenium will be ready to go! Check out one of my other articles for the environment you want to use with Selenium:</p>
<ul>
<li><a href="https://cavender.foo/articles/dotnet-selenium-mstest-quickstart">C#, Selenium &amp; MSTest</a></li>
<li><a href="https://cavender.foo/articles/js-selenium-mocha-quickstart">JavaScript, Selenium &amp; Mocha</a></li>
</ul>
<p>Thanks for reading!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[C# Selenium MSTest QuickStart Guide]]></title>
            <link>https://cavender.foo/articles/dotnet-selenium-mstest-quickstart</link>
            <guid>https://cavender.foo/articles/dotnet-selenium-mstest-quickstart</guid>
            <pubDate>Sat, 18 Jun 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[A quick how-to on setting up a solution using MSTest and Selenium!]]></description>
            <content:encoded><![CDATA[<p>In this article we’ll be using MSTest and Selenium to write tests for web applications. This will be a starter project we can build on for various projects and in future articles.</p>
<h3 id="requirements">Requirements</h3>
<p>Here are the requirements before we get started:</p>
<ul>
<li><a href="https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx">Visual Studio</a> (A Microsoft Integrated Development Environment or IDE)</li>
<li><a href="http://docs.nuget.org/consume/installing-nuget">Nuget</a> (A package manager for Visual Studio)</li>
<li><a href="https://www.selenium.dev/downloads/">Selenium C# language bindings</a> (But we’ll use NuGet to grab these)</li>
<li>Any browsers installed that you want to test <a href="https://www.selenium.dev/downloads/#platforms-supported-by-selenium">Supported Platforms</a></li>
</ul>
<h3 id="selenium-prep">Selenium Prep</h3>
<p>If you haven’t read through my quick <a href="https://cavender.foo/2016/06/25/selenium-overview-setup">Overview of Selenium</a> you should do that now. Selenium will need a few things configured before it’ll do its magic!</p>
<h3 id="create-project">Create Project</h3>
<p>To kick things off we’ll need a new project.</p>
<p><strong>File &gt; New &gt; Project</strong></p>
<p>Select the Unit Test Project template (<strong>Templates &gt; Visual C# &gt; Test</strong>), give it a name and configure some options. Press Ok to create the project. Visual Studio will create the project and open up your first UnitTest class.</p>
<h3 id="importinstall-selenium">Import/Install Selenium</h3>
<p>Now we’ll need to grab the Selenium DLLs and give our project access to them.</p>
<p><strong>Tools &gt; NuGet Package Manager &gt; Manage NuGet Packages for Solution</strong></p>
<p>Select Browse, search for ‘Selenium’ and install both Selenium.WebDriver and Selenium.Support for your new project.</p>
<h3 id="write-test">Write Test</h3>
<p>Now the fun begins; we can write the first Selenium test!
We’ll write our test against <a href="http://the-internet.herokuapp.com/">The Internet</a><sup><a href="#user-content-fn-theinternet" id="user-content-fnref-theinternet" data-footnote-ref aria-describedby="footnote-label">1</a></sup>.</p>
<p>Here’s some code to put inside the <strong>TestMethod1()</strong></p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto;" tabindex="0" data-language="c#"><code><span class="line"><span style="color:#6A737D">//var driver = new OpenQA.Selenium.Firefox.FirefoxDriver</span></span>
<span class="line"><span style="color:#6A737D">//var driver = new OpenQA.Selenium.Edge.EdgeDriver</span></span>
<span class="line"><span style="color:#6A737D">//var driver = new OpenQA.Selenium.IE.InternetExplorerDriver</span></span>
<span class="line"><span style="color:#F97583">var</span><span style="color:#B392F0"> driver</span><span style="color:#F97583"> =</span><span style="color:#F97583"> new</span><span style="color:#B392F0"> OpenQA</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">Selenium</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">Chrome</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">ChromeDriver</span></span>
<span class="line"><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#E1E4E8">Url </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> "http://the-internet.herokuapp.com/"</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"><span style="color:#E1E4E8">Assert.</span><span style="color:#B392F0">IsTrue</span><span style="color:#E1E4E8">(driver.Title </span><span style="color:#F97583">==</span><span style="color:#9ECBFF"> "The Internet"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">driver.</span><span style="color:#B392F0">Dispose</span><span style="color:#E1E4E8">();</span></span></code></pre>
<ol>
<li>Get a web driver</li>
<li>Set the URL property (tells the driver to go to that URL)</li>
<li>Assert on the title of the driver</li>
<li>Dispose of the driver</li>
</ol>
<h3 id="run-test">Run Test</h3>
<p>Now that we have a functional test we can run it. First, if the Test Explorer isn’t displayed we need to add it.</p>
<p><strong>Test &gt; Windows &gt; Test Explorer</strong></p>
<p>Our test isn’t showing up yet. We need to build the solution for it to recognize that we’ve written a test it can run. Right click on the solution in the Solution Explorer and Build or Rebuild the solution. If the build is successful we should see our test show up in the Test Explorer. Now we can right click on our test and tell it to run. If all went according to plan we should see a Chrome window pop up, navigate to Google’s home page and then close.</p>
<p>This is a basic, and brittle, example of how Selenium works. If our assertion returns false the test will report a failure but the browser window will still be alive. This test is brittle in that it can’t run any code after the Assert if the Assert returns false. We’ll cover a much better testing approach in a later post to avoid such things! This is not an example of best practices by any means. This is to get you a working example of Selenium. Stay tuned for more posts on how to use Selenium and best practices for automating tests!</p>
<p>Thanks for reading!</p>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-theinternet">
<p>Credit to Dave Haeffner. <a href="#user-content-fnref-theinternet" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content:encoded>
        </item>
    </channel>
</rss>