<?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: Andy Li</title>
    <description>The latest articles on DEV Community by Andy Li (@andyli).</description>
    <link>https://dev.to/andyli</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%2F47087%2F429589e0-f72d-4b36-b896-09766fdb2b62.jpeg</url>
      <title>DEV Community: Andy Li</title>
      <link>https://dev.to/andyli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andyli"/>
    <language>en</language>
    <item>
      <title>Nice tests to run in CI before deploying any website</title>
      <dc:creator>Andy Li</dc:creator>
      <pubDate>Sat, 14 Sep 2019 23:50:25 +0000</pubDate>
      <link>https://dev.to/andyli/nice-tests-to-run-in-ci-before-deploying-any-website-14o2</link>
      <guid>https://dev.to/andyli/nice-tests-to-run-in-ci-before-deploying-any-website-14o2</guid>
      <description>&lt;p&gt;Since I'm the only dev behind my startup, &lt;a href="https://giffon.io"&gt;Giffon 🎁&lt;/a&gt;, I've to take care of all the technical things from development to deployment. Though I've been following best practices and be careful about edge cases, still I don't trust the code I wrote very much.&lt;/p&gt;

&lt;p&gt;I added a number of tests in CI to check my website before deployment, and they have caught my mistakes many times. The cool thing is, many of those tests are generic enough to be applicable to any website, so you should consider using them too!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Markup validation
&lt;/h2&gt;

&lt;p&gt;The first easy low-hanging fruit is HTML (and CSS/SVG) validation. Most HTML templates do not enforce valid HTML, so it's quite easy to output documents with mismatched tags, which can be a pain to spot! Giffon uses &lt;a href="https://reactjs.org/docs/react-dom-server.html"&gt;ReactDOMServer&lt;/a&gt;, which prevents tag mismatches, but the validation still caught me many times about putting block-level elements (e.g. &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;) in &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;, and also missing &lt;code&gt;alt&lt;/code&gt; attribute in &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Giffon's CI uses the &lt;a href="https://github.com/svenkreiss/html5validator"&gt;html5validator&lt;/a&gt; command line tool against a development server. It's basically calling the commands as follow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;html5validator &lt;span class="nt"&gt;--html&lt;/span&gt; http://localhost:3000/every/page
html5validator &lt;span class="nt"&gt;--css&lt;/span&gt; www/css/&lt;span class="k"&gt;*&lt;/span&gt;.css
html5validator &lt;span class="nt"&gt;--svg&lt;/span&gt; &lt;span class="nt"&gt;--errors-only&lt;/span&gt; www/images/&lt;span class="k"&gt;*&lt;/span&gt;.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Detecting browser console error messages
&lt;/h2&gt;

&lt;p&gt;The second generic error detection is to check the browser console. It reports JS run-time errors as well as broken image references and some invalid HTTP respond headers too.&lt;/p&gt;

&lt;p&gt;Giffon's way to do it is to use &lt;a href="https://www.seleniumhq.org/projects/webdriver/"&gt;Selenium web driver&lt;/a&gt;, navigates to each page and calls &lt;code&gt;driver.get_log("browser")&lt;/code&gt;, asserts that there is no log.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Detecting horizontal scrollbars
&lt;/h2&gt;

&lt;p&gt;Most websites don't use horizontal scrollbars. It's annoying (especially on mobile) when one appears due to layout bugs.&lt;/p&gt;

&lt;p&gt;Again, Giffon's CI makes use of Selenium. The CI navigates to each page and detects the present of horizontal scrollbars by asserting the following code returns zero:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute_script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"document.scrollingElement.scrollLeft = 1;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s"&gt;"return document.scrollingElement.scrollLeft;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Spellchecking
&lt;/h2&gt;

&lt;p&gt;Who doesn't make typos? It may not be critical, but having typos in your website does give a bad impression to visitors.&lt;/p&gt;

&lt;p&gt;Giffon's CI uses &lt;a href="https://www.npmjs.com/package/spellchecker"&gt;spellchecker npm library&lt;/a&gt;. Giffon has its UI text strings isolated when I implement multi-language support, so it's easy for me to iterate over all the strings and call &lt;code&gt;SpellChecker.checkSpelling(str)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you don't have your strings isolated, you may save the html output as a file and use the good old &lt;a href="http://aspell.net/"&gt;aspell&lt;/a&gt; cli to list all misspelled words as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;path/to/my.html | aspell &lt;span class="nt"&gt;--mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;html list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Any others?
&lt;/h1&gt;

&lt;p&gt;Do you run similar tests in you CI pipelines? Let me know if you have any good ones to share!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Do you set up Patreon or other services to accept donation? 💰</title>
      <dc:creator>Andy Li</dc:creator>
      <pubDate>Tue, 09 Jul 2019 21:43:51 +0000</pubDate>
      <link>https://dev.to/andyli/do-you-set-up-patreon-or-other-services-to-accept-donation-2m6e</link>
      <guid>https://dev.to/andyli/do-you-set-up-patreon-or-other-services-to-accept-donation-2m6e</guid>
      <description>&lt;p&gt;On one hand, it sounds great to receive donation for working on projects, and people can dream of having enough donation to quit their day jobs. On the other hand, even the people maintaining pretty popular projects do not receive much money. For example, the &lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt; maintainer is currently receiving $2,580 per month via &lt;a href="https://www.patreon.com/henryzhu"&gt;Patreon&lt;/a&gt;, but I'm pretty sure one can easily make more money in a full time tech job.&lt;/p&gt;

&lt;p&gt;Do you think Patreon or similar services (GitHub Sponsor) is helpful to you? Would receiving money contribution motivate you working on projects?&lt;/p&gt;

&lt;p&gt;P.S. Feel free to put your donation links in the discussion ;)&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>motivation</category>
    </item>
    <item>
      <title>What's the connection between Debian and Toy Story?</title>
      <dc:creator>Andy Li</dc:creator>
      <pubDate>Sun, 07 Jul 2019 00:24:17 +0000</pubDate>
      <link>https://dev.to/andyli/what-s-the-connection-between-debian-and-toy-story-1dmg</link>
      <guid>https://dev.to/andyli/what-s-the-connection-between-debian-and-toy-story-1dmg</guid>
      <description>&lt;p&gt;&lt;a href="https://www.debian.org/" rel="noopener noreferrer"&gt;Debian&lt;/a&gt; is a popular Linux distribution. &lt;a href="https://ubuntu.com/" rel="noopener noreferrer"&gt;Ubuntu&lt;/a&gt;, which is the first choice of many Linux new-comers, is based on Debian.&lt;/p&gt;

&lt;p&gt;Debian 10, which was just &lt;a href="https://www.debian.org/News/2019/20190706" rel="noopener noreferrer"&gt;released&lt;/a&gt; today, is code-named Buster. Debian 9 is Stretch, Debian 8 is Jessie, and the earlier ones Wheezy, Squeeze, Lenny... which are all Pixar's Toy Story characters!&lt;/p&gt;

&lt;h2&gt;
  
  
  But why Toy Story code names?
&lt;/h2&gt;

&lt;p&gt;It turns out, at the time Debian made its first release with a code name, Debian 1.1 Buzz (yes, Buzz Lightyear), the project leader at the time (Bruce Perens) was working at Pixar.&lt;/p&gt;

&lt;p&gt;You may find the other Debian code names in &lt;a href="https://www.debian.org/doc/manuals/project-history/ch-releases.en.html" rel="noopener noreferrer"&gt;A Brief History of Debian&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gph.is/21I4qOp" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx1a32lv4rey36q86wg9.gif" alt="Buster and Woody"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look closer to the &lt;a href="https://wiki.debian.org/DebianArt/Themes/futurePrototype" rel="noopener noreferrer"&gt;Debian 10 wallpaper&lt;/a&gt;, which is the cover image of this post, you will notice there is a hidden shape of Buster, Andy's pet dog.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>debian</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I stay focused when working at home: live streaming myself</title>
      <dc:creator>Andy Li</dc:creator>
      <pubDate>Thu, 04 Jul 2019 22:36:38 +0000</pubDate>
      <link>https://dev.to/andyli/how-i-stay-focused-when-working-at-home-live-streaming-myself-2dhi</link>
      <guid>https://dev.to/andyli/how-i-stay-focused-when-working-at-home-live-streaming-myself-2dhi</guid>
      <description>&lt;p&gt;I was a typical procrastinator - not in the mood of working 90% of the time, many excuses for doing unimportant tasks, easy to distract.&lt;/p&gt;

&lt;p&gt;When I quit from my previous full-time job to work on my startup, &lt;a href="https://giffon.io"&gt;Giffon.io&lt;/a&gt;, I was quite worried that I would just spend all time playing League of Legends and burn my saving until I have to find another office job.&lt;/p&gt;

&lt;p&gt;I tried to make deadlines for myself. Not fake ones, but I made a "real" deadline by submitting a talk to introduce Giffon in &lt;a href="https://summit.haxe.org/us/2019/"&gt;Haxe Summit&lt;/a&gt;. It worked, but mostly only for the 2 weeks before the talk. I was even building major features the day before I got on the stage. After I came back from the summit, the productivity burst didn't last.&lt;/p&gt;

&lt;p&gt;I came across a Hacker News &lt;a href="https://news.ycombinator.com/item?id=20001383"&gt;discussion&lt;/a&gt; about live streaming programming (while I was procrastinating, of course). It sounded interesting to me since I kind of like showcasing stuff and meeting people, basically the same reasons I like speaking at conferences.&lt;/p&gt;

&lt;p&gt;Once I've decided to give it a try, I dug out my Kinect for Windows and set it up as my camera (just because I don't have a webcam for my PC), tweeted about it such that I will have a few viewers, and started doing it on the next day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gph.is/g/4Lx1M7p"&gt;&lt;img src="https://i.giphy.com/media/cKJc1ohEZQCl51l3yV/giphy.gif" alt="GIF image banners for the Giffon wish pages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first stream was me implementing GIF image banners for the Giffon wish pages. There were about 5 viewers, in which 2 of them were my friends from the Haxe team. I couldn't tell how interesting my stream was to my viewers (probably not much), but at least I myself felt pretty good. I got stuck at one point and my friend discussed the problem with me in the chat. I haven't tried pair programming but I guess it would be a similar experience. At the end of my first stream, I had almost finished the feature in just a bit over 2 hours. It was about the maximum coding efficiency I can get.&lt;/p&gt;

&lt;p&gt;Not only I was productive during the stream, I was also productive afterwards since I've already kickstarted my work and the inertia allowed me to polish the feature and do some refactoring off-stream.&lt;/p&gt;

&lt;p&gt;Since then, I've been streaming every weekdays. From time to time, different strangers come by and chat with me for a bit, sometimes about programming languages, sometimes about career planing, sometimes about the background music I was listening. The amount of chatting is just right for me to have fun and I keep pretty productive through out. Sometimes the same viewer comes by again in the next stream and it's pretty motivating for me to continue.&lt;/p&gt;

&lt;p&gt;So, yeah, so far live streaming is the most successful weapon to fight procrastination for me. I do encourage you to try it out if you haven't yet. Leave me a comment if you have a Twitch stream and I will try to &lt;a href="https://help.twitch.tv/s/article/how-to-use-raids"&gt;raid&lt;/a&gt; you if our timing is right :)&lt;/p&gt;

&lt;p&gt;My Twitch channel is &lt;a href="https://www.twitch.tv/andyonthewings"&gt;andyonthewings&lt;/a&gt;, streaming development of Giffon as well as &lt;a href="https://haxe.org"&gt;Haxe&lt;/a&gt; and some Linux packaging etc.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>hacks</category>
      <category>livecoding</category>
      <category>twitch</category>
    </item>
    <item>
      <title>Create 5 real PRs in an hour and win a Hacktoberfest T-shirt</title>
      <dc:creator>Andy Li</dc:creator>
      <pubDate>Fri, 26 Oct 2018 03:44:01 +0000</pubDate>
      <link>https://dev.to/andyli/create-5-real-prs-in-an-hour-and-win-a-hacktoberfest-t-shirt-1ahl</link>
      <guid>https://dev.to/andyli/create-5-real-prs-in-an-hour-and-win-a-hacktoberfest-t-shirt-1ahl</guid>
      <description>&lt;p&gt;The annual &lt;a href="https://hacktoberfest.digitalocean.com"&gt;Hacktoberfest&lt;/a&gt;, which gives away free T-shirts to people who create 5 or more GitHub pull requests, is about to end in a week.&lt;/p&gt;

&lt;p&gt;I have been an active open source contributor for years, so I was pretty confident that I will eventually fulfill 5 PRs without actively working towards it. Turn out I was wrong - because I'm now part of the &lt;a href="https://github.com/HaxeFoundation"&gt;Haxe Foundation org&lt;/a&gt;, in which I contributed most, I don't really make PRs to contribute since I just push my commits, and that doesn't count towards the Hacktoberfest goal.&lt;/p&gt;

&lt;p&gt;Luckily, there are plenty of low-hanging fruits around and I have successfully reached the 5 PRs mark quite easily. Note that I didn't make useless PRs that paraphrase sentences or perform minor formatting to code. I made "real" contributions that is beneficial. Here is how.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maintain packages!
&lt;/h2&gt;

&lt;p&gt;The one thing that people may not realize that needs continuous work and is quite easy to do (even for beginner devs) is to maintain software packages. Every time you use a package manager to install something, it pull the package from a repository. It is often to have thousands of packages in a repository and the packages need to be updated (usually manually) all the time since new versions are coming out continuously.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Homebrew/homebrew-core"&gt;Homebrew-core&lt;/a&gt; is a pretty nice repository to work on since it is maintained though GitHub, which is familiar to most open source contributors nowadays. We simply send them PR to update its packages (which they call them formulae).&lt;/p&gt;

&lt;h3&gt;
  
  
  Find out what is outdated
&lt;/h3&gt;

&lt;p&gt;We can make use of &lt;a href="https://repology.org/"&gt;Repology&lt;/a&gt; to find out what is outdated. We look up the &lt;a href="https://repology.org/repository/homebrew"&gt;Repology homebrew page&lt;/a&gt;, and click on the "Outdated" metapackages number link.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://repology.org/metapackages/?inrepo=homebrew&amp;amp;outdated=1"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x9s_dYby--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/llh0tayhc0bepnncs71e.png" alt="Outdated homebrew packages" width="880" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, we just pick some familiar ones to work on - maybe you've used that software before, or it's a simple one that is built with languages that you're good at. Try to pick the ones that only need minor/patch update, e.g. from 1.2.3 to 1.2.4 or 1.3.0, but not to a major 2.0.0 release. Be sure to check that there is no existing &lt;a href="https://github.com/Homebrew/homebrew-core/pulls"&gt;update PRs&lt;/a&gt; created already.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do the update
&lt;/h3&gt;

&lt;p&gt;We can refer to the &lt;a href="https://github.com/Homebrew/homebrew-core/blob/master/CONTRIBUTING.md#submit-a-version-upgrade-for-the-foo-formula"&gt;homebrew-core's CONTRIBUTING.md&lt;/a&gt; for how to do the update.&lt;/p&gt;

&lt;p&gt;We can either (A) edit the formula file by updating &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;sha256&lt;/code&gt;, and then send a PR by hand, or (B) use the &lt;a href="https://github.com/Homebrew/brew/blob/master/Library/Homebrew/dev-cmd/bump-formula-pr.rb"&gt;&lt;code&gt;brew bump-formula-pr&lt;/code&gt;&lt;/a&gt; command to do the same thing.&lt;/p&gt;

&lt;p&gt;For reference, &lt;a href="https://github.com/Homebrew/homebrew-core/pull/33377"&gt;here is one PR&lt;/a&gt; that I made with the command as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew bump-formula-pr &lt;span class="nt"&gt;--strict&lt;/span&gt; bmake &lt;span class="nt"&gt;--url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://www.crufty.net/ftp/pub/sjg/bmake-20180919.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  That's it!
&lt;/h3&gt;

&lt;p&gt;After sending out the PRs, we can wait for the maintainer's feedback. If the package can be built successfully, it is usually accepted right away. Also, you can click on the "Check Your Progress" button in the Hacktoberfest homepage after you've logged in to make sure you've made enough PRs :)&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>homebrew</category>
      <category>github</category>
    </item>
  </channel>
</rss>
