<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>/gempesaw/writing</title>
  <subtitle></subtitle>
  <link href="https://blog.danielgempesaw.com/feed.xml" rel="self"/>
  <link href="https://blog.danielgempesaw.com/"/>
  <updated>2021-04-16T00:00:00Z</updated>
  <id>https://blog.danielgempesaw.com/</id>
  <author>
    <name>Daniel Gempesaw</name>
    <email>gempesaw@gmail.com</email>
  </author>
  
  
  <entry>
    <title>About</title>
    <link href="https://blog.danielgempesaw.com/post/about/"/>
    <updated>2013-01-01T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/about/</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://blog.danielgempesaw.com/post/about/whee&quot; alt=&quot;ultimate photo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;My name is Daniel Gempesaw, and I am a QA software developer for &lt;a href=&quot;http://www.sharecare.com/&quot;&gt;Sharecare&lt;/a&gt;. I create tools to improve our QA process, including an in-house browser automation suite based on Webdriver. I use Emacs for &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/tagged/jabber&quot;&gt;as&lt;/a&gt; &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/tagged/mu4e&quot;&gt;many&lt;/a&gt; &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/tagged/tumblesocks&quot;&gt;things&lt;/a&gt; &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/tagged/ssh&quot;&gt;as&lt;/a&gt; &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/tagged/unzip&quot;&gt;I&lt;/a&gt; &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/tagged/circe&quot;&gt;can&lt;/a&gt;; recently I&#39;ve been writing mostly Scala, Perl, elisp, and PHP in it. Anything Emacs, software, or web-dev related is on &lt;a href=&quot;http://elisp-solves-problems.tumblr.com/&quot;&gt;elisp-solves-problems&lt;/a&gt;: so far it&#39;s mainly explanations and snippets of my &lt;a href=&quot;http://github.com/gempesaw/dotemacs&quot;&gt;.emacs files&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&#39;ve also got a non-software tumblr at &lt;a href=&quot;http://danzorx.tumblr.com/&quot;&gt;danzorx&lt;/a&gt; for other things that I enjoy like &lt;a href=&quot;http://danzorx.tumblr.com/tagged/ultimate&quot;&gt;ultimate&lt;/a&gt;, &lt;a href=&quot;http://danzorx.tumblr.com/tagged/snowboarding&quot;&gt;snowboarding&lt;/a&gt;, and riding &lt;a href=&quot;http://danzorx.tumblr.com/tagged/bike&quot;&gt;bicycles&lt;/a&gt;. I&#39;m sometimes a pianist, bassist, and a novice ukulele-ist, but without a band or a gig in mind I&#39;m getting a bit rusty.&lt;/p&gt;
&lt;p&gt;I&#39;m on &lt;a href=&quot;http://plus.google.com/gempesaw&quot;&gt;Google+&lt;/a&gt;, and sparingly on &lt;a href=&quot;http://www.twitter.com/dgempesaw&quot;&gt;twitter&lt;/a&gt;, or you can shoot me an &lt;a href=&quot;mailto:gempesaw@gmail.com&quot;&gt;email&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>syntax highlighting this tumblr blog</title>
    <link href="https://blog.danielgempesaw.com/post/syntax-highlighting/"/>
    <updated>2013-03-14T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/syntax-highlighting/</id>
    <content type="html">&lt;p&gt;Syntax highlighting on tumblr is a completely manual effort, as far as I&#39;m aware. I don&#39;t know of any built-in highlighting or any certified methods that they advertise. I did some research and tried a couple different highlighters - some of them are out of date, some of them don&#39;t support lisp, and some of them are more complicated. I was looking for a decently recent one that had built-in lisp support and would be easiest to hook into a tumblr set up. I settled on &lt;a href=&quot;http://softwaremaniacs.org/soft/highlight/en/&quot;&gt;highlight.js&lt;/a&gt;, which has helpful documentation on its own website and everything.&lt;/p&gt;
&lt;p&gt;Because I needed somewhere to host the files, I got set up with Github Pages and put my versions of the highlight.pack.js file in there. That took a while, but once it was sorted, the rest was pretty straight forward. I just need to select and add a CSS stylesheet with the colors of my choosing, add one script tag to source the js file that does the work, and then call javascript command to do all the highlighting. So, the following lines have been added to my tumblr theme:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;http://gempesaw.github.com/stylesheets/ir_black.css&amp;quot; /&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://gempesaw.github.com/javascripts/highlight.pack.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;hljs.initHighlightingOnLoad();&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Stylesheet, highlight.js, and activation. A fancy part of highlight.js is that it has language autodetection, so if it figures out I&#39;m writing Lisp on its own, that&#39;s great! Sometimes, it misses though, and I have to manually wrap my source code in &lt;code&gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;quot;lisp&amp;quot;&amp;gt;source-code&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;/code&gt; tags, which isn&#39;t that bad.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>keeping my emacs windows balanced</title>
    <link href="https://blog.danielgempesaw.com/post/balance-windows/"/>
    <updated>2013-03-15T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/balance-windows/</id>
    <content type="html">&lt;p&gt;I&#39;ve decided to get a bit OCD about my window sizes in Emacs, and I got tired of hitting &lt;code&gt;C-x +&lt;/code&gt; to do &lt;code&gt;balance-windows&lt;/code&gt; all the time. I&#39;m not sure if there&#39;s a better way to do this, but I just added some advice around all of the commands I usually use to change the window layout: &lt;code&gt;split-window-below&lt;/code&gt;, &lt;code&gt;split-window-right&lt;/code&gt;, and &lt;code&gt;delete-window&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defadvice split-window-below (after restore-balanace-below activate)
  (balance-windows))

(defadvice split-window-right (after restore-balance-right activate)
  (balance-windows))

(defadvice delete-window (after restore-balance activate)
  (balance-windows))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So now my windows automatically balance themselves whenever I &lt;code&gt;C-x 2&lt;/code&gt; or &lt;code&gt;C-x 3&lt;/code&gt;, all the time! Nifty. On the off chance that I&#39;d like to manually control the size of a window, I&#39;ve found &lt;code&gt;enlarge-window&lt;/code&gt; under &lt;code&gt;C-x ^&lt;/code&gt;; along with a &lt;code&gt;C-u&lt;/code&gt; and &lt;code&gt;C-x z&lt;/code&gt;, I can enlarge a window by a bunch of lines pretty quickly.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>automatically save your bookmarks file</title>
    <link href="https://blog.danielgempesaw.com/post/bookmarks-advice/"/>
    <updated>2013-03-16T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/bookmarks-advice/</id>
    <content type="html">&lt;p&gt;Bookmarks in Emacs are very, very useful for getting to places you frequently go. If you don&#39;t use them to help you navigate, you should consider it! For whatever reason, bookmarks are saved in an external file, not in an Emacs variable. I can&#39;t count the number of times I added a bookmark, closed Emacs, and inadvertently deleted it. Even with version control, I still kept losing bookmarks because I kept forgetting to save.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq bookmarks-default-file &amp;quot;~/.emacs.d/bookmarks&amp;quot;)
(defadvice bookmark-set (after save-bookmarks-automatically activate)
  (bookmark-save))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let Emacs know where you want to save the bookmarks, and then use some advice! This little advice saves you all that woe: any time you set a bookmark, Emacs now saves all of them for you automatically. Presto :)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>circe - an alternative to erc :)</title>
    <link href="https://blog.danielgempesaw.com/post/circe/"/>
    <updated>2013-03-17T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/circe/</id>
    <content type="html">&lt;p&gt;I recently &lt;a href=&quot;https://plus.google.com/115251065755572046236/posts/iURXPzzSWaH&quot;&gt;heard about a new version&lt;/a&gt; of &lt;a href=&quot;https://github.com/jorgenschaefer/circe/wiki&quot;&gt;&lt;code&gt;circe&lt;/code&gt;&lt;/a&gt; coming out so I went to try it out. I don&#39;t remember why I stopped using &lt;code&gt;erc&lt;/code&gt; but afaik they both seem fine to use.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(package-install &#39;circe)
(setq circe-network-options
      `((&quot;Freenode&quot;
         :nick &quot;dgempesaw&quot;
         :channels (&quot;#emacs&quot; &quot;#selenium&quot;)
         :nickserv-password ,freenode-password
         )))
(circe)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That should be enough to get you up and running and autoconnected to &lt;code&gt;#emacs&lt;/code&gt; and &lt;code&gt;#selenium&lt;/code&gt;. You&#39;ll have to &lt;code&gt;setq&lt;/code&gt; your password in freenode-password, of course. Unfortunately, circe comes with &lt;code&gt;tracking-mode&lt;/code&gt; which fights with &lt;code&gt;ace-jump-mode&lt;/code&gt; for power over the &lt;code&gt;C-c C-SPC&lt;/code&gt; keybinding. I added &lt;code&gt;ace-jump-mode&lt;/code&gt; to that as well as its default at &lt;code&gt;C-c SPC&lt;/code&gt; to help me whenever I&#39;m clusmy. So, I&#39;ll just redefine the keys in the &lt;code&gt;tracking-mode-map&lt;/code&gt; to my liking:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(eval-after-load &quot;tracking&quot;
  &#39;(progn
     (define-key tracking-mode-map (kbd &quot;C-c C-SPC&quot;) &#39;ace-jump-mode)
     (define-key tracking-mode-map (kbd &quot;C-c C-@&quot;) &#39;ace-jump-mode)
     (define-key tracking-mode-map (kbd &quot;C-x C-j C-k&quot;) &#39;tracking-next-buffer)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;C-x C-j C-k&lt;/code&gt; is close to jabber&#39;s &lt;code&gt;C-x C-j C-l&lt;/code&gt; - all the new-message-buffer-cycling keys together, please! Otherwise, no complaints really, a pleasant time was had by all.&lt;/p&gt;
&lt;p&gt;In fact, my first day idling in &lt;code&gt;#emacs&lt;/code&gt;, I found out that you can bind the function keys sequentially like prefix keys, which OF COURSE makes sense but it opens up a whole new set of keybindings. For example,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(global-set-key (kbd &quot;&amp;lt;f5&amp;gt; &amp;lt;f6&amp;gt;&quot;) &#39;do-something-cool)
(global-set-key (kbd &quot;&amp;lt;f5&amp;gt; &amp;lt;f5&amp;gt;&quot;) &#39;do-someting-else-cool)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is that not the coolest? I felt kind of silly for a bit but luckily Fuco hadn&#39;t realized it either, and people write about Fuco all the time so nyahhh!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>clearing pngs off of my desktop</title>
    <link href="https://blog.danielgempesaw.com/post/delete-desktop-pngs/"/>
    <updated>2013-03-18T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/delete-desktop-pngs/</id>
    <content type="html">&lt;p&gt;A huge part of doing QA is taking screenshots and videos. Luckily, OS X makes it super easy to take screenshots with &lt;code&gt;Command + Shift + 4&lt;/code&gt;. Unluckily, doing that all day long every day means the desktop gets super cluttered with your beautiful bug report pngs! Instead of manually deleting &#39;em, let Emacs do it for you :)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun delete-all-pngs-on-desktop ()
  &amp;quot;Opens a dired to desktop, marks all pngs, and tries to delete
them&amp;quot;
  (interactive)
  (save-window-excursion
    (dired &amp;quot;~/Desktop&amp;quot;)
    (revert-buffer)
    (dired-mark-files-regexp &amp;quot;png&amp;quot; nil)
    (dired-do-delete)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Go to the desktop folder in dired, refresh so it&#39;s up to date, mark all the pngs, and delete &#39;em. Time saved, pew pew!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>fetchnotes and emacs, together at last</title>
    <link href="https://blog.danielgempesaw.com/post/fetchmacs/"/>
    <updated>2013-03-19T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/fetchmacs/</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.fetchnotes.com/&quot;&gt;Fetchnotes&lt;/a&gt; is yet another todo-list/note taking app. I like their service because everything is just plain text, so it&#39;s very straightforward from a usage standpoint. I don&#39;t have to worry about formatting or saving a url or just part of a page or anything that I&#39;m not concerned about; it&#39;s just text! Additionally, they use tags to organize your notes; I have an affinity for tagging/labelling things excessively with the assumption that future me will be able to think of at least one of the tags past me used.&lt;/p&gt;
&lt;p&gt;They&#39;ve got a web interface and a nice responsive mobile view, and they also have an iOS app, an iPad app, and an Android app, which means that I can CRUD notes from any device I&#39;ve got; since it&#39;s just text, it&#39;s easy on every device. As is the Emacs way, a thing worth doing is worth doing from inside Emacs. I&#39;ve written &lt;a href=&quot;https://github.com/gempesaw/fetchmacs.git&quot;&gt;fetchmacs&lt;/a&gt;, an Emacs major-mode to interact with their API from inside of Emacs. I&#39;ve been using for myself for a few weeks.&lt;/p&gt;
&lt;p&gt;It&#39;s pretty straightforward - the biggest issue that I always have with Elisp is figuring out how to dereference the data structures. Otherwise, it&#39;s just basic auth stuff and CRUD, with some keybindings to smooth things along. I haven&#39;t gotten around to MELPA/Marmalade integration, although that&#39;s my next goal. For the time being I&#39;ve just been &lt;code&gt;load-file&lt;/code&gt;ing it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defvar fetchmacs-user-email &amp;quot;user@n.ame&amp;quot;)
(defvar fetchmacs-user-pass &amp;quot;password&amp;quot;)
(load-file &#39;fetchmacs.el)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Put your user and pass in &lt;code&gt;fetchmacs-user-email&lt;/code&gt; and &lt;code&gt;fetchmacs-user-pass&lt;/code&gt; and you should be good to go. Invoke &lt;code&gt;fetchmacs-view-notes&lt;/code&gt; to get to the notes dashboard, using &lt;code&gt;fetchmacs-view-notes-mode&lt;/code&gt;. I&#39;ve got it bound as &lt;code&gt;C-x f&lt;/code&gt;, because I never use &lt;code&gt;set-fill-column&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(global-unset-key (kbd &amp;quot;C-x f&amp;quot;))
(global-set-key (kbd &amp;quot;C-x f&amp;quot;) &#39;fetchmacs-view-notes)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I really enjoy using &lt;a href=&quot;http://philjackson.github.com/magit/&quot;&gt;magit&lt;/a&gt;, so whenever I possible I tried using the same or similar keys.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RET&lt;/code&gt; or &lt;code&gt;e&lt;/code&gt; or &lt;code&gt;o&lt;/code&gt; : &lt;code&gt;fetchmacs-view-edit-note-at-point&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;c&lt;/code&gt; : &lt;code&gt;fetchmacs-create-new-note&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;D&lt;/code&gt; or &lt;code&gt;k&lt;/code&gt; : &lt;code&gt;fetchmacs-delete-note-at-point&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/&lt;/code&gt; : &lt;code&gt;fetchmacs-search&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;g&lt;/code&gt; : &lt;code&gt;fetchmacs-refresh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;n&lt;/code&gt; : &lt;code&gt;fetchmacs-goto-next-note&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p&lt;/code&gt; : &lt;code&gt;fetchmacs-goto-previous-note&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;t&lt;/code&gt; : &lt;code&gt;fetchmacs-filter-by-tag&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Outside of &lt;code&gt;fetchmacs-view-notes-mode&lt;/code&gt; there&#39;s also an editing mode which pops up in another window, just like editing &lt;code&gt;magit&lt;/code&gt; commits. In there, the the following keybindings are available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-c C-c&lt;/code&gt; : &lt;code&gt;fetchmacs-save-note&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-c C-k&lt;/code&gt; : &lt;code&gt;fetchmacs-cancel-edit&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So just like &lt;code&gt;magit&lt;/code&gt;, you can save or cancel from in there.&lt;/p&gt;
&lt;p&gt;And that&#39;s about it! On the off chance that a) there&#39;s actually anyone reading this, b) you&#39;re an Emacs user, c) &lt;em&gt;and&lt;/em&gt; you&#39;re a Fetchnotes user - a pretty unlikely cross section - please give it a try! :)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>convenience functions: eol punctuation and creating new lines</title>
    <link href="https://blog.danielgempesaw.com/post/going-to-next-line/"/>
    <updated>2013-03-20T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/going-to-next-line/</id>
    <content type="html">&lt;p&gt;Writing perl and php, I often find myself needing commas or semicolons at the end of a line. After I got tired of doing &lt;code&gt;C-e ; &amp;lt;return&amp;gt;&lt;/code&gt; and &lt;code&gt;C-e , &amp;lt;return&amp;gt;&lt;/code&gt; all the time I decided I&#39;d make things easier on myself.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(global-set-key (kbd &amp;quot;C-,&amp;quot;) (lambda () (interactive)
                              (end-of-line)
                              (insert &amp;quot;,&amp;quot;)
                              (indent-according-to-mode)
                              (forward-line 1)
                              (indent-according-to-mode)))

(global-set-key (kbd &amp;quot;C-;&amp;quot;) (lambda () (interactive)
                              (end-of-line)
                              (insert &amp;quot;;&amp;quot;)
                              (indent-according-to-mode)
                              (forward-line 1)
                              (indent-according-to-mode)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I bound &lt;code&gt;C-,&lt;/code&gt; and &lt;code&gt;C-;&lt;/code&gt; to get to the end of the line, insert the appropriate character, indent, go down a single line, and indent the new line, too. I find them to be useful because it allows me to finish up a line of code from anywhere on the line. I also did something similar on &lt;code&gt;C-&amp;lt;return&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(global-set-key (kbd &amp;quot;C-&amp;lt;return&amp;gt;&amp;quot;) (lambda () (interactive)
                                     (end-of-line)
                                     (reindent-then-newline-and-indent)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of inserting any punctuation, this just opens up a new line beneath the current one with the proper identation and moves the cursor there. These are pretty small little things but I use them multiple times a day to save me numerous keystrokes.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>setting up jabber.el</title>
    <link href="https://blog.danielgempesaw.com/post/jabber/"/>
    <updated>2013-03-21T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/jabber/</id>
    <content type="html">&lt;p&gt;I recently added &lt;a href=&quot;http://emacs-jabber.sourceforge.net/&quot;&gt;&lt;code&gt;jabber.el&lt;/code&gt;&lt;/a&gt; to my workflow via &lt;code&gt;package-install jabber&lt;/code&gt;. &lt;code&gt;Jabber.el&lt;/code&gt; seems to be in a really good place in terms of usage and polished development. The only hiccup I had was that it was complaining about starttls issues. That was easy enough to google, and it seemed like I should specify the connection type as starttls. We&#39;re apparently using an expired cert or something, so I had to make starttls insecure as well. I got the impression I should be more worried about that, but oh well.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(setq jabber-account-list &#39;((work-email-address
                             (:connection-type . starttls))))
(setq starttls-extra-arguments &#39;(&quot;--insecure&quot;))
(setq starttls-use-gnutls t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So that got me connected. As always, there were some customizations that were necessary. First, I don&#39;t care about seeing presence, and I don&#39;t care about who is offline:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(setq jabber-alert-presence-hooks nil
      jabber-show-offline-contacts nil)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I don&#39;t want to hear about the avatars, I don&#39;t even want to download them, and I don&#39;t want them showing up in the roster:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(setq jabber-avatar-verbose nil
      jabber-vcard-avatars-retrieve nil
      jabber-roster-line-format &quot; %c %-25n %u %-8s (%r)&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I do want the history, as well as alerts in my mode line, and we can shorten the buffer names for funsies.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(setq jabber-history-enabled t
      jabber-mode-line-mode t
      jabber-chat-buffer-format &quot;*-jabber-%n-*&quot;
      jabber-roster-buffer &quot;*-jabber-*&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I want to autojoin some chatrooms every time I connect:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lisp&quot;&gt;(setq jabber-muc-autojoin &#39;(&quot;qa@conference.sharecare.com&quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All together, I&#39;m quite happy with my jabber setup. Pretty low amount of customization necessary for being able to do away with Adium entirely.&lt;/p&gt;
&lt;p&gt;Oh, and keybindings - I only know and use a few of them&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C-x C-j C-c&lt;/code&gt; - connect! start out with this one obviously&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C-x C-j C-l&lt;/code&gt; - if you have a pending message, switch to that buffer! if you&#39;ve already switched to a pending message buffer, switch back to the one you came from if there are no more new messages! if there&#39;s no pending messages, do nothing! I really like this one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My only complaint is that I wish I started using &lt;code&gt;jabber.el&lt;/code&gt; earlier, as it&#39;s quite nice to stay in Emacs for chats; quite nice, indeed.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>save-window-excursion: protect your window layout</title>
    <link href="https://blog.danielgempesaw.com/post/window-excursion/"/>
    <updated>2013-03-22T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/window-excursion/</id>
    <content type="html">&lt;p&gt;Sometimes I&#39;ve got my window layout set up just right, and then a command like &lt;code&gt;tex-file&lt;/code&gt; stomps all over my hard work. &lt;code&gt;winner-mode&lt;/code&gt; helps with one off cases, but &lt;code&gt;tex-file&lt;/code&gt; always pops up a new window for the buffer containing the tex compilation. I usually don&#39;t care about the compilation, especially since it usually doesn&#39;t fail, so let&#39;s stop popping up that window:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(add-hook &#39;latex-mode-hook
          (lambda ()
            (define-key latex-mode-map (kbd &amp;quot;C-c C-f&amp;quot;)
              (lambda ()
                (interactive)
                (save-buffer)
                (save-window-excursion
                  (tex-file))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tex-file&lt;/code&gt; is usually at &lt;code&gt;C-c C-f&lt;/code&gt;, so let&#39;s replace it in the key map by my interactive function. It saves the buffer and uses &lt;code&gt;save-window-excursion&lt;/code&gt; to keep everything in the same place. Hooray :)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>markdown-preview with syntax highlighting</title>
    <link href="https://blog.danielgempesaw.com/post/markdown-preview/"/>
    <updated>2013-04-01T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/markdown-preview/</id>
    <content type="html">&lt;p&gt;In a previous post, I talked about &lt;a href=&quot;https://blog.danielgempesaw.com/post/markdown-preview/&quot;&gt;adding syntax-highlighting to this blog&lt;/a&gt;. It&#39;s working out quite well for me, but I wanted to pull it into my composition workflow better. My current suboptimal workflow is to compose markdown in Emacs and copy/paste into Tumblr&#39;s web app. (Tumblesocks is having connection problems that I don&#39;t feel like figuring out quite yet.) When I &lt;code&gt;markdown-preview&lt;/code&gt;, I want to be able to see my code in all its syntax highlighted glory. Let&#39;s look at &lt;code&gt;markdown-preview&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun markdown-preview (&amp;amp;optional output-buffer-name)
  &amp;quot;Run &#92;`markdown&#39; on the current buffer and preview the output in a browser.&amp;quot;
  (interactive)
  (browse-url-of-buffer (markdown markdown-output-buffer-name)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, looking into that fourth line, we call &lt;code&gt;markdown&lt;/code&gt; with the argument &lt;code&gt;markdown-output-buffer-name&lt;/code&gt;. &lt;code&gt;markdown&lt;/code&gt; itself runs markdown on the current buffer and outputs to the optional argument: in this case &lt;code&gt;markdown-output-buffer-name&lt;/code&gt;. Then, we pass that temporary buffer to &lt;code&gt;browse-url-of-buffer&lt;/code&gt; which opens it up in Chrome and voila! we see a preview of the markdown under composition.&lt;/p&gt;
&lt;p&gt;What I wanted to do was to add the same style and script sources that I added to the tumblr theme. That way, my markdown preview would have the same syntax highlighting that my tumblr would have! So, I wrote my own &lt;code&gt;markdown-preview&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun markdown-preview-with-syntax-highlighting (&amp;amp;optional output-buffer-name)
  &amp;quot;Run `markdown&#39; on the current buffer and preview the output in a browser.&amp;quot;
  (interactive)
  (browse-url-of-buffer
   (with-current-buffer (markdown markdown-output-buffer-name)
     (goto-char (point-min))
     (if (&amp;gt; (length markdown-css-path) 0)
         (insert &amp;quot;&amp;lt;link rel=&#92;&amp;quot;stylesheet&#92;&amp;quot; type=&#92;&amp;quot;text/css&#92;&amp;quot; media=&#92;&amp;quot;all&#92;&amp;quot; href=&#92;&amp;quot;&amp;quot;
                 markdown-css-path
                 &amp;quot;&#92;&amp;quot;  /&amp;gt;&#92;n&amp;quot;))

     (if (&amp;gt; (length markdown-script-path) 0)
         (progn
           (insert &amp;quot;&amp;lt;script type=&#92;&amp;quot;text/javascript&#92;&amp;quot; src=&#92;&amp;quot;&amp;quot;
                 markdown-script-path
                 &amp;quot;&#92;&amp;quot;  /&amp;gt;&amp;lt;/script&amp;gt;&#92;n&amp;quot;)
           (insert &amp;quot;&amp;lt;script type=&#92;&amp;quot;text/javascript&#92;&amp;quot;&amp;gt;hljs.initHighlightingOnLoad();&amp;lt;/script&amp;gt;&amp;quot;)))
     markdown-output-buffer-name)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where I want to jump in is after markdown has processed my file but before we send the output buffer to &lt;code&gt;browse-url-of-buffer&lt;/code&gt;. &lt;code&gt;(markdown markdown-output-buffer-name)&lt;/code&gt; returns the output buffer, so I catch that into the first argument of &lt;code&gt;with-current-buffer&lt;/code&gt;. I go to the beginning of the buffer and determine whether or not I know where the desired css and scripts are. Assuming they&#39;re defined somewhere else...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq markdown-css-path &amp;quot;/opt/highlight.js/src/styles/ir_black.css&amp;quot;)
(setq markdown-script-path &amp;quot;/opt/highlight.js/build/highlight.pack.js&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the function will insert analogous style and script tags that highlight the text!&lt;/p&gt;
&lt;p&gt;Last but not least, instead of calling &lt;code&gt;markdown-preview&lt;/code&gt; as my compile command for markdown buffers, I should call my improved version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(add-to-list &#39;smart-compile-alist &#39;(&amp;quot;&#92;&#92;.md&#92;&#92;&#39;&amp;quot; . (markdown-preview-with-syntax-highlighting)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Local automatic syntax highlighting in markdown previews complete!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Telling auth-source (and smtpmail-send-it) about my changed email password</title>
    <link href="https://blog.danielgempesaw.com/post/change-smtp-password/"/>
    <updated>2013-06-06T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/change-smtp-password/</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;http://d.pr/i/1SjL+&quot; alt=&quot;auth-source-forget-all-cached&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I recently had to change my email password, as properly dictated by
work&#39;s IT policies. I use &lt;code&gt;offlineimap&lt;/code&gt; to get my mail, &lt;code&gt;mu4e&lt;/code&gt; to read
it, and &lt;code&gt;smtpmail-send-it&lt;/code&gt; to send it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq message-send-mail-function &#39;message-send-mail-with-sendmail
      message-send-mail-function &#39;smtpmail-send-it
      smtpmail-stream-type &#39;starttls
      smtpmail-default-smtp-server &amp;quot;pod51019.outlook.com&amp;quot;
      smtpmail-smtp-server &amp;quot;pod51019.outlook.com&amp;quot;
      smtpmail-smtp-user &amp;quot;dgempesaw@sharecare.com&amp;quot;
      smtpmail-smtp-service 587)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Offlineimap&lt;/code&gt; manages its password stuff from a config file at
&lt;code&gt;~/.offlineimaprc&lt;/code&gt;. I updated that file and I was able to continue
retrieving my mail with no hiccoughs. I then updated my &lt;code&gt;~/.authinfo&lt;/code&gt;
file as well with the new password, but I continued to get the
authentication failed error.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Sending failed: 535 5.7.3 Authentication unsuccessful in response to base64-encoded-password
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That was pretty odd, considering that I changed the source file and
all. I tried digging through &lt;code&gt;smtpmail.el&lt;/code&gt; a little bit, looking for
occurences of password or auth or something. I happened to see a defun
called &lt;code&gt;auth-source-search&lt;/code&gt; which got me into &lt;code&gt;auth-source.el&lt;/code&gt;. Doing an
&lt;code&gt;apropos-command&lt;/code&gt; for &amp;quot;auth&amp;quot; led me to
&lt;code&gt;auth-source-forget-all-cached&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Apparently the auth sources like
&lt;code&gt;~/.authinfo&lt;/code&gt; are cached for a customizable length of time, so I just
had to clear the cache and everything is back in running order!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>On the E3 rape joke</title>
    <link href="https://blog.danielgempesaw.com/post/e3rapejoke/"/>
    <updated>2013-06-12T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/e3rapejoke/</id>
    <content type="html">&lt;p&gt;There was a rape comment &lt;a href=&quot;http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=P75YQHFnyKY&quot;&gt;during Microsoft&#39;s E3 demo&lt;/a&gt;. Many people are arguing that it wasn&#39;t a rape comment, mostly consisting of &amp;quot;I didn&#39;t parse it as a rape joke because (it&#39;s a stretch|I can think of something else it might refer to|I&#39;m not oversensitive|.*), so it&#39;s not and stop complaining about it.&amp;quot; It&#39;s narcissistic, misogynistic, and ignorant to assert &lt;em&gt;to other people&lt;/em&gt; (!!!! who have entirely different experiences!) that it&#39;s equivocally not a rape joke and to try to stop conversation about it.&lt;/p&gt;
&lt;p&gt;Regardless of anyone&#39;s dissenting opinion, the fact is that many people interpeted the comment as a reference to rape. This fact along with the context (Microsoft presenting to a huge audience practically guaranteed to include rapists and rape survivors in an industry plagued by gender issues) should be enough to make the entire situation reprehensible - why should it matter that there are some people who aren&#39;t offended, and why do they need to inject themselves into the conversation? The entitled attitude of &amp;quot;I&#39;m not offended so &lt;em&gt;you&lt;/em&gt; shouldn&#39;t be either&amp;quot; is infuriating.&lt;/p&gt;
&lt;p&gt;Still, some people don&#39;t care about offending others; they can&#39;t be bothered with being polite, politically correct, tactful, minimally empathetic, or whatever they want to derisively call it. Even for these people, this is still a problem that we shouldn&#39;t shout down or drown out, because &lt;a href=&quot;http://blog.jorgenschaefer.de/2013/05/words-matter.html&quot;&gt;words matter&lt;/a&gt;, because &lt;a href=&quot;http://juliepagano.tumblr.com/post/51565918563/to-all-those-who-dont-think-the-rape-joke-was-a#notes&quot;&gt;rape jokes make rapists feel comfortable&lt;/a&gt;; because &lt;a href=&quot;http://www.thefrisky.com/2013-06-03/the-soapbox-what-do-rape-jokes-make-rapists-think/&quot;&gt;we shouldn&#39;t make rapists feel better&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>On dudebros and sexism in games</title>
    <link href="https://blog.danielgempesaw.com/post/dudebros/"/>
    <updated>2013-06-15T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/dudebros/</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;I despise it when people take a small sampling of truly sexist games
(which I will readily admit exist, and some are legitimately good
games despite the fact), but the same people choose to ignore the
huge number of games with amazing, strong female characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&#39;s not enough that games with strong female characters exist, or
even that there&#39;s an (arguably) huge number of them. As I understand it,
it&#39;s the pervasive sexism in the entire industry, manifested in things
like: the actual game characters themselves, like when Microsoft
didn&#39;t release a single game with &lt;a href=&quot;https://blog.danielgempesaw.com/post/dudebros/%5Bhttp://femfreq.tumblr.com/post/52673540142/twitter-vs-female-protagonists-in-video-games%5D&quot;&gt;a female lead at E3 this year&lt;/a&gt;;
the attitudes executives of industry-leading game studios, like when
they publicly (and incorrectly) opine that
&lt;a href=&quot;https://blog.danielgempesaw.com/post/dudebros/%5Bhttp://www.penny-arcade.com/report/article/games-with-female-heroes-dont-sell-because-publishers-dont-support-them%5D&quot;&gt;games with female protags don&#39;t sell&lt;/a&gt;; the bullshit the few female
devs have to put up with, as seen when the
&lt;a href=&quot;https://blog.danielgempesaw.com/post/dudebros/%5Bhttp://www.buzzfeed.com/hillaryreinsberg/why-are-so-few-women-creating-video-games%5D&quot;&gt;#1ReasonWhy hashtag exploded&lt;/a&gt;, etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&#39;m tired of hearing uneducated hits at my favorite hobby. True
gamers, not the common Halo or Call of Duty &amp;quot;dudebros&amp;quot; that make up
the public front of gamers, are one of the least sexist groups one
could possibly meet. Many of us, from very young ages, have been
exposed to great female role models and characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &amp;quot;true gamers&amp;quot; label is disingenuous and doesn&#39;t excuse anyone on
either side of it of their behavior. Anyone who plays games is a
gamer, and it&#39;s just as ridiculous to say that all Halo/CoD players
are sexist as it is to say that &amp;quot;true gamers&amp;quot; are &amp;quot;one of the least
sexist groups.&amp;quot;&lt;/p&gt;
&lt;p&gt;I&#39;m going to mostly skip the entire ME section - the trilogy is
probably one of the best franchises in terms of female representation,
but it&#39;s still fraught with
&lt;a href=&quot;https://blog.danielgempesaw.com/post/dudebros/%5Bhttp://feministgaming.tumblr.com/post/52860244214/decorating-the-doldrums-so-i-asked-my-boyfriend-about%5D&quot;&gt;problems, like feministpoints mentions&lt;/a&gt;. I&#39;m not quite sure what
the list of female characters is supposed to do for the argument.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Alyx Vance from Half-Life 2, Half-Life 2: Episode 1 and Half-Life 2:
Episode 2 is widely considered to be the greatest companion in any
game, ever. Alyx is not sexualized in the story and is always
portrayed as a great friend to the protagonist, Gordon
Freeman. Faith from Mirror&#39;s Edge could have easily been taken
advantage of with her loose clothing, but the developers chose not
to, to respect her gender and character.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using Alyx Vance as an example seems to be a double edged sword -
sure, her character is a great companion, but who wants to grow up to
be a great companion? People don&#39;t want to be Midna, or Robin, or
Watson: they want to be Link, Batman, and Sherlock. Faith is, as far
as I can tell without having played the game, a great example, but
again, the existence of some or even many good games with strong
female protags and supporting characters has isn&#39;t enough to counter
the rest of the industry&#39;s rampant sexism.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Almost every game with character customisation allow males and
females to be made by the player. I, as a male gamer, often choose
to play female over males in these places, and so do many of my
friends. Females are often more convincing as leaders and heroes in
gaming, and the voice actors often give better performances and
carry more charisma. Plus, it is always nice for at least one form
of media to escape from normal sexist tropes surrounding the female
gender.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cool! These are nice anecdotes and opinions, but I don&#39;t think they
have much bearing on the state of gaming.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yes, there are many sexist and/or misogynistic games - Call of Duty,
Gears of War, and Halo come to mind - but they are poor
representations of the medium as a whole. Gaming is actually very
progressive in the image of strong, independent, competent female
characters, whether in side roles or as heroines. This wonderful
fledgling medium is getting a far worse reputation than it deserves.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, agreed! Some games have been very progressive with amazing
heroines, and that is awesome. Gaming is an amazing and exciting
medium with so much untapped potential, but to claim it&#39;s not sexist
just doesn&#39;t hold up.&lt;/p&gt;
&lt;p&gt;All that being said, there&#39;s nothing wrong with liking and loving
these games and the industry in spite their sexism - it&#39;s okay for us
to like problematic things. It doesn&#39;t make us a bad people, as long
as we are cognizant of the shortcomings of the game and the
industry. The ME series is one of my all time favorites, but it&#39;s far
from perfect in many ways and that&#39;s okay! It&#39;s paving the way for
better games in the future, and that&#39;s what is really exciting.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Lesser known Emacs helps</title>
    <link href="https://blog.danielgempesaw.com/post/lesser-known-helps/"/>
    <updated>2013-06-17T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/lesser-known-helps/</id>
    <content type="html">&lt;p&gt;I recently came across a pair of lesser known (for me) help
keybindings: &lt;code&gt;C-h c&lt;/code&gt; and &lt;code&gt;C-h w&lt;/code&gt;. I ran through the tutorial on a
flight because I haven&#39;t yet and I&#39;ve been meaning to, and that&#39;s
where I found &lt;code&gt;C-h c&lt;/code&gt; which invokes &lt;code&gt;describe-key-briefly&lt;/code&gt;. It&#39;s
basically a baby version of &lt;code&gt;C-h k&lt;/code&gt;, &lt;code&gt;describe-key&lt;/code&gt;. Instead of
popping up another window to tell you about the keystroke, it just
puts a short little description in the minibuffer. I think it&#39;ll be
pretty useful if I can remember to use it to keep from messing up my
own window config.&lt;/p&gt;
&lt;p&gt;Kind of going the other direction, &lt;code&gt;C-h w&lt;/code&gt; invokes &lt;code&gt;where-is&lt;/code&gt; which
prompts you for an interactive function and tells you what, if any,
keybinding it&#39;s attached to. This is pretty useful when I know the
name of the command I want to do, but I&#39;m not sure what the keybinding
is for it. I ran across that situation with a couple magit commands
the other day and I was able to work backwards to figure out the
keybindings. Previously, I&#39;d been doing &lt;code&gt;C-h m&lt;/code&gt; or &lt;code&gt;C-h b&lt;/code&gt; to get a
list of keybindings and then &lt;code&gt;C-s&lt;/code&gt;ing through that list for the name
of the command.&lt;/p&gt;
&lt;p&gt;Of course, both of these (and more) are immediately available through
&lt;code&gt;C-h C-h&lt;/code&gt;, and they&#39;ve been there for the entire time that I&#39;ve been
an Emacs user.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Using a command line argument for PhantomJS and the Selenium Server Standalone</title>
    <link href="https://blog.danielgempesaw.com/post/phantomjsbinary/"/>
    <updated>2013-08-19T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/phantomjsbinary/</id>
    <content type="html">&lt;p&gt;tl; dr - &lt;code&gt;-Dphantomjs.binary.path=/path/to/your/phantomjs&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://code.google.com/p/selenium/&quot;&gt;Selenium WebDriver&lt;/a&gt; is a
browser automation framework that uses &amp;quot;drivers&amp;quot; to drive
browsers. So, there is a &amp;quot;chromedriver&amp;quot; that you send instructions
like &amp;quot;click on the Sign In link&amp;quot; or &amp;quot;tell me what color that element
is,&amp;quot; and it will carry out the instructions in an actual Chrome
browser. &lt;a href=&quot;http://phantomjs.org/&quot;&gt;PhantomJS&lt;/a&gt;, by
&lt;a href=&quot;https://github.com/ariya&quot;&gt;Ariya Hidayat&lt;/a&gt;, is a quick, lightweight
headless browser that parses JS (unlike HTMLUnit! !). Since it doesn&#39;t
have to render anything on the screen, it can perform these tests much
faster, but the tradeoff is accuracy - you&#39;re no longer testing in the
&lt;em&gt;exact&lt;/em&gt; same environment as your users.&lt;/p&gt;
&lt;p&gt;Its driver is cleverly (?) named GhostDriver, written by
&lt;a href=&quot;https://github.com/detro&quot;&gt;Ivan De Marino&lt;/a&gt;. GhostDriver is built-in to
PhantomJS, so if you want to use PhantomJS in your WebDriver tests,
the only thing you need to do is
&lt;a href=&quot;http://phantomjs.org/download.html&quot;&gt;install PhantomJS&lt;/a&gt;, which Ariya
makes very easy (for example, &lt;code&gt;brew install phantomjs&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I&#39;m using the Perl WebDriver bindings, and I start the selenium server
with a shell command that looks something like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C:&#92;&amp;gt; java -jar selenium-server-standalone-2.35.0.jar ^
    -Dwebdriver.chrome.driver=C:&#92;chromedriver.exe ^
    -Dwebdriver.ie.driver=C:&#92;InternetExplorerDriver.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;code&gt;-Dwebdriver.chrome.driver&lt;/code&gt; option tells the Selenium server
where to go find my Chromedriver, and likewise for IE. Now, PhantomJS
makes it really easy to connect to an existing standalone server -
from their Github page, once PhantomJS is in your path, you just need
to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ phantomjs --webdriver=&amp;lt;PORT_TO_WEBDRIVER&amp;gt; # default is 4444
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, those two commands will start up the Selenium standalone server
and hook up PhantomJS to it, so you can request a PhantomJS browser of the server and run your tests. But, it&#39;s a pain to have to set up two
processes for PhantomJS when I can already add the Chrome and IE
drivers as options. I couldn&#39;t find this documented anywhere, but you
can also add the PhantomJS binary as a command line argument to the
standalone server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ java -jar selenium-server-standalone-2.35.0.jar &#92;
    -Dphantomjs.binary.path=/path/to/your/phantomjs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you use homebrew, it would be&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ java -jar selenium-server-standalone-2.35.0.jar &#92;
    -Dphantomjs.binary.path=/usr/local/bin/phantomjs
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Unknown command &#39;WaitForAllTabsToStopLoading&#39;</title>
    <link href="https://blog.danielgempesaw.com/post/chromedriver-version/"/>
    <updated>2013-08-21T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/chromedriver-version/</id>
    <content type="html">&lt;p&gt;I woke up this morning and went to run some Webdriver jobs in Chrome, but for some reason they weren&#39;t working! The browser would start up, and then it would die, complaining about an unknown command called &#39;WaitForAllTabsToStopLoading&#39;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dying: Error while executing command: An unknown server-side error occurred 
while processing the command.: Unknown command &#92;&#39;WaitForAllTabsToStopLoading&#92;&#39;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It seems like there&#39;s a problem with older versions of Chromedriver and the newest version of Chrome. While my day to day Chrome hasn&#39;t updated since I never close it, the Chrome that Webdriver uses gets restarted every time a test is run, so it updated itself to Version 29.0.1547.57. As a result, my old Chromedriver doesn&#39;t seem to know how to drive the new Chrome. Updating the chromedriver binary to the &lt;a href=&quot;https://code.google.com/p/chromedriver/downloads/list&quot;&gt;one released on August 6&lt;/a&gt; fixes the problem for me.&lt;/p&gt;
&lt;p&gt;For a few minutes, this was a really confusing bug. I&#39;m constantly tweaking our automation framework, so I wasn&#39;t too surprised when the tests were failing - I figured I must&#39;ve broken something on my dev branch of the framework. However, when a couple of my coworkers said they had the exact same issue, despite not changing anything from the day before, I had no idea what might be going wrong. I didn&#39;t think about Chrome updating itself on all of our computers at the same time, leading to duplicate bugs in systems that were supposedly unchanged. Fun :)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>I don&#39;t know anything about SQL Server 2008 R2</title>
    <link href="https://blog.danielgempesaw.com/post/sql-server-2008/"/>
    <updated>2013-09-18T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/sql-server-2008/</id>
    <content type="html">&lt;p&gt;One of my work assignments depended on an install of SQL Server 2008 R2. I needed to use the &lt;code&gt;sa&lt;/code&gt; account to log in and do some database-y things during latter parts of the install, but I didn&#39;t know the password for the &lt;code&gt;sa&lt;/code&gt; account, and I didn&#39;t know how to find it or change it. According to Google, &lt;a href=&quot;http://www.microsoft.com/en-us/download/details.aspx?id=7593&quot;&gt;SQL Server Management Studio&lt;/a&gt; is what I need to do admin things. At this point, I found out that the &lt;code&gt;sa&lt;/code&gt; account was actually disabled by default in new installations of 08 R2 as a security precaution, so my task was to get admin access, enable the &lt;code&gt;sa&lt;/code&gt; account, and change its password.&lt;/p&gt;
&lt;p&gt;There are apparently two methods of login for SQL Server 2008: Windows Authentication mode, wherein you use the same credentials that you do for logging in to the machine itself, and SQL Server and Windows Authentication mode. The latter allows us to use SQL logins alongside of the Windows credentials. Now, enabling the &lt;code&gt;sa&lt;/code&gt; account wouldn&#39;t have done anything on its own if the server authentication mode was Windows Authentication only, which would have prevented me from logging into the &lt;code&gt;sa&lt;/code&gt; account. So.&lt;/p&gt;
&lt;p&gt;First, in order to do admin things to other accounts, I apparently needed to temporarily enable single user mode for the server, described in a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd207004.aspx&quot;&gt;Microsoft article&lt;/a&gt; I had been lucky enough to find off &lt;a href=&quot;http://stackoverflow.com/questions/4188193/how-do-you-reset-the-sa-password&quot;&gt;stackoverflow&lt;/a&gt;. After changing the startup command and restarting the server, I was able to use SSMS with no restrictions and full freedom to muck about with all sorts of stuff.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://d.pr/i/KFS2+&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next, I had to change the server authentication to &amp;quot;Mixed&amp;quot; so that enabling the &lt;code&gt;sa&lt;/code&gt; account was worth anything at all. Docs for that courtesy of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms188670.aspx&quot;&gt;another Microsoft article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://d.pr/i/Byp7+&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Finally, I had to open the properties of the &amp;quot;sa&amp;quot; acconut up, &amp;quot;Enable&amp;quot; it, and change its password to something I knew.&lt;/p&gt;
&lt;p&gt;Hmm, I&#39;ve learned that I don&#39;t like to use GUIs to manage my databases, and that VM snapshots are quite useful after you&#39;ve done some crazy things to the db. Useful, I guess, but trouble shooting slow GUIs inside of a slow VM was super distracting, causing me painful context switches all day long.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>js2-mode timer errors: timer-set-function: Wrong type argument: timerp</title>
    <link href="https://blog.danielgempesaw.com/post/js2-mode-timer/"/>
    <updated>2013-09-25T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/js2-mode-timer/</id>
    <content type="html">&lt;p&gt;I started seeing the following timer error in &lt;a href=&quot;https://github.com/mooz/js2-mode&quot;&gt;mooz&#39;s &lt;code&gt;js2-mode&lt;/code&gt;&lt;/a&gt;,
the actively maintained fork of Steve Yegge&#39;s &lt;code&gt;js2-mode&lt;/code&gt;. This would
happen whenever I changed any javascript code, and the mode wouldn&#39;t
rehighlight the new code. Invoking &lt;code&gt;js2-mode&lt;/code&gt; interactively would
properly apply the syntax highlighting, but then the next change to
the file would cause the error again.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; timer-set-function: Wrong type argument: timerp, [t nil nil nil nil nil nil nil]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is also a fork of this fork, &lt;a href=&quot;https://github.com/thomblake/js3-mode&quot;&gt;&lt;code&gt;js3-mode&lt;/code&gt;&lt;/a&gt;, which was working
fine for me, but unfortunately &lt;a href=&quot;https://github.com/skeeto/skewer-mode&quot;&gt;&lt;code&gt;skewer-mode&lt;/code&gt;&lt;/a&gt; is only compatible
with the AST generated from &lt;code&gt;js2-mode&lt;/code&gt;. I&#39;d guess that making
&lt;code&gt;skewer-mode&lt;/code&gt; compatible with &lt;code&gt;js3-mode&lt;/code&gt; might be just a change to a
variable name or something, but I wasn&#39;t too interested in digging
into that on my own.&lt;/p&gt;
&lt;p&gt;I&#39;m unfortunately not sure what caused the issue for me. According to
the solution, it seems to have been updating to Emacs 24.3 instead of
24.2, but I hadn&#39;t recently updated my Emacs. Either way, I was
fortunate enough to find a solution in an &lt;a href=&quot;https://github.com/mooz/js2-mode/issues/72&quot;&gt;issue on Github&lt;/a&gt;. It
seems that the culprit is stale bytecode compiled by 24.2 that is
invalid on 24.3 So, as &lt;a href=&quot;https://github.com/mooz/js2-mode/issues/72#issuecomment-15176816&quot;&gt;described in the issue&lt;/a&gt;, recompiling js2-mode
and restarting Emacs fixed it for me as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(byte-recompile-directory
  (expand-file-name &amp;quot;~/.emacs.d/elpa/js2-mode-20130307.2012/&amp;quot;) 0 t)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&#39;ll have to replace the js2-mode version string with the date of
your actual js2-mode folder. &lt;code&gt;byte-recompile-directory&lt;/code&gt; also works
recursively, so it can be applied to the &lt;code&gt;~/.emacs.d/elpa&lt;/code&gt; folder to
recompile all of the elpa packages, or the &lt;code&gt;~/.emacs.d/&lt;/code&gt; folder to do
your entire init folder.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>How do you test a big ReST API binding?</title>
    <link href="https://blog.danielgempesaw.com/post/selenium-remote-driver/"/>
    <updated>2014-04-03T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/selenium-remote-driver/</id>
    <content type="html">&lt;p&gt;I recently became the maintainer of &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver&quot;&gt;Selenium::Remote::Driver&lt;/a&gt;,
which is the Perl bindings to the Selenium Webdriver API. I just
&lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver&quot;&gt;released version 0.18 to the CPAN&lt;/a&gt; and hopefully got the tests
passing again :D.&lt;/p&gt;
&lt;p&gt;I&#39;m still trying to figure out the Best Way to test a module that is
basically an interface to a ReST API. As far as I&#39;m aware, integration
testing these kinds of modules basically require you to mock or fake
out network responses, but there were a couple articles on
blogs.perl.org that &lt;a href=&quot;http://modernperlbooks.com/mt/2012/04/mock-objects-despoil-your-tests.html&quot;&gt;discouraged the use of mocks&lt;/a&gt;, so I&#39;m
a bit unsure about best practices.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://search.cpan.org/~ether/Test-LWP-UserAgent-0.023/lib/Test/LWP/UserAgent.pm&quot;&gt;Test::LWP::UserAgent&lt;/a&gt; is one way to mock/fake out network
traffic in Perl, and it&#39;s similar to &lt;a href=&quot;http://docs.angularjs.org/api/ngMock/service/$httpBackend&quot;&gt;AngularJS&#39;s $httpBackend&lt;/a&gt;:
you instantiate a fake network object, and then tell it what requests
it should expect. You inject the fake network object into your
module&#39;s constructor, and when it tries to make a request, the mock
catches it and lets you examine the request for tests and the
like. You can also specify responses to test out the different
branches of the module, like for error handling tests.&lt;/p&gt;
&lt;p&gt;For a big module, having to set up tests for every single request can
get a bit cumbersome, so &lt;code&gt;S::R::D&lt;/code&gt; went the way of simply recording
all of the requests/responses that its test suite makes, and including
the recordings with the module. When running the tests, it loads up
the recording and matches incoming requests to its list of recorded
REQ/RES pairs, and returns the appropriate response.&lt;/p&gt;
&lt;p&gt;Unfortunately, the recording process is different across platforms, so
every change to the module or the tests require new recordings for
each supported platform. Additionally complicating the issue was that
there was a bug somewhere in the recording code, so it would only work
with an LWP-Protocol-PSGI-0.04, which is the module used to record the
requests and responses.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>bookmarking magit buffers with projectile</title>
    <link href="https://blog.danielgempesaw.com/post/projectile-action/"/>
    <updated>2014-04-04T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/projectile-action/</id>
    <content type="html">&lt;p&gt;For the longest time, I&#39;ve wanted to be able to bookmark the
&lt;a href=&quot;https://github.com/magit/magit&quot;&gt;&lt;code&gt;magit&lt;/code&gt;&lt;/a&gt; buffers of my various git projects. It&#39;s really
useful to be able to jump to the top level view and get a &lt;code&gt;git status&lt;/code&gt;
summary of what I was in the middle of. However, I wasn&#39;t able to use
Emacs&#39;s built in bookmarks for this, because those require a file
reference to jump to, and the magit buffers were not file based. Enter
Projectile :)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/bbatsov/projectile&quot;&gt;Projectile&lt;/a&gt; (&lt;em&gt;Project&lt;/em&gt; &lt;em&gt;I&lt;/em&gt;nteraction &lt;em&gt;L&lt;/em&gt;ibrary for
&lt;em&gt;E&lt;/em&gt;macs) by &lt;a href=&quot;http://emacsredux.com/&quot;&gt;Bozhidar Batsov&lt;/a&gt; is a really nifty tool for managing
different projects in Emacs. For me it primarily smooths out finding
files in projects, and switching between project directories. In
particular, I&#39;v got &lt;code&gt;s-p&lt;/code&gt; bound to &lt;code&gt;projectile-switch-project&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(define-key projectile-mode-map [?&#92;s-p] &#39;projectile-switch-project)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Projectile keeps a cache of the different git directories I&#39;ve been
to, and provides it as a list of choices. You can customize the action
that Projectile does after you select a project, and there are a few
&lt;a href=&quot;https://github.com/bbatsov/projectile#switching-projects&quot;&gt;suggestions&lt;/a&gt; like &lt;code&gt;projectile-find-file&lt;/code&gt;, which would prompt
you for a file to visit, and &lt;code&gt;projectile-dired&lt;/code&gt;, which immediately
opens up the new project&#39;s directory in a &lt;code&gt;dired&lt;/code&gt; buffer. Both useful,
and for a while I settled for opening the project in a directory and
invoking &lt;code&gt;magit-status&lt;/code&gt; myself.&lt;/p&gt;
&lt;p&gt;However, my new favorite is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq projectile-switch-project-action &#39;projectile-vc)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which tells projectile to open up the vc buffer for the new project,
which would be the magit buffer for git projects. Itch scratched!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>convenience fns: open-jira-ticket-at-point</title>
    <link href="https://blog.danielgempesaw.com/post/open-jira-ticket-at-point/"/>
    <updated>2014-04-10T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/open-jira-ticket-at-point/</id>
    <content type="html">&lt;p&gt;Working with JIRA, there are a bunch of instances where I see a JIRA
ticket inside of Emacs and I want to open it in Chrome - they come up
often in jabber chatrooms, there&#39;s tons of them in emails, etc. No
reason for me to copy it manually or search for it again on JIRA -
just let Emacs do the work. :D&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun open-jira-ticket-at-point ()
  (interactive)
  (let ((ticket (thing-at-point &#39;sexp)))
    (if (eq nil (string-match-p &amp;quot;^[A-z]+-[0-9]+$&amp;quot; ticket))
        (setq ticket (read-from-minibuffer
                      &amp;quot;Not sure if this is a ticket: &amp;quot;
                      ticket)))
    (browse-url
     (concat
      &amp;quot;http://arnoldmedia.jira.com/browse/&amp;quot; ticket))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;(thing-at-point THING-TYPE)&lt;/code&gt; is a useful function that &amp;quot;returns the
&lt;em&gt;THING&lt;/em&gt; at point&amp;quot;. It accepts a couple different options of things
that it tries to look for - in our case, &lt;code&gt;sexp&lt;/code&gt; seems to be reasonable
at picking out JIRA tickets from different contexts. Sometimes, it
picks up some extra stuff and we need to manually fix the input. So,
if the thing-at-point doesn&#39;t match the regexp &lt;code&gt;&amp;quot;^[A-z]+-[0-9]+$&amp;quot;&lt;/code&gt;,
then ask the user to fix it a little bit, and then go ahead and
&lt;code&gt;browse-url&lt;/code&gt; the ticket in Chrome. Easy peasy.&lt;/p&gt;
&lt;p&gt;The better thing to do is probably go into &lt;code&gt;thingatpt.el&lt;/code&gt; and figure
out how to make my own &lt;code&gt;thing&lt;/code&gt; that it recognizes, but I couldn&#39;t be
bothered at the time.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>travis build badges, POD, dist::zilla and pod::weaver</title>
    <link href="https://blog.danielgempesaw.com/post/travis-and-pod-weaver/"/>
    <updated>2014-04-12T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/travis-and-pod-weaver/</id>
    <content type="html">&lt;p&gt;I&#39;ve taken the plunge with the excellent &lt;a href=&quot;https://metacpan.org/pod/Dist::Zilla&quot;&gt;Dist::Zilla&lt;/a&gt; recently
for authoring my Perl distributions. Since picking up the maintainer
role of &lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver&quot;&gt;S::R::D&lt;/a&gt;, D::Z fit my needs perfectly: speed up
distribution and alleviate all the repetitive parts of the process.&lt;/p&gt;
&lt;p&gt;I recently started work on Perl bindings to the
&lt;a href=&quot;http://bmp.lightbody.net/&quot;&gt;Browsermob Proxy&lt;/a&gt; REST API called, unimaginatively,
&lt;a href=&quot;https://metacpan.org/pod/Browsermob::Proxy&quot;&gt;Browsermob::Proxy&lt;/a&gt;. As usual, we want it to run its tests on
travis, and there&#39;s the lovely &lt;code&gt;[TravisYML]&lt;/code&gt; plugin for that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# dist.ini
[TravisYML]

[GatherDir]
include_dotfiles = 1

[PruneCruft]
except = &#92;.travis.yml

[PodWeaver]

[ReadmeAnyFromPod]
type = markdown
filename = README.md
location = root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and we also want to use Pod::Weaver for more of that DRY
goodness. Since we&#39;re writing all the documentation in the main module
anyway, &lt;code&gt;[ReadmeAnyFromPod]&lt;/code&gt; generates a markdown readme for us that
Github likes. The last bit is getting the Travis build status badge
into that readme. Surprisingly, Travis even have a suggested form for
POD badges:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=for HTML &amp;lt;a href=&amp;quot;https://travis-ci.org/gempesaw/Browsermob...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But unfortunately that won&#39;t work in our case, since we&#39;re outputting
to markdown. Via trial and error, I found that using the markdown form
of the build badge in a &lt;code&gt;=for markdown&lt;/code&gt; POD section works with
&lt;code&gt;[ReadmeAnyFromPod]&lt;/code&gt; with &lt;code&gt;type = markdown&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=for markdown [![Build Status](https://travis-ci.org/gempesaw...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in the POD does get it into the generated readme, but since it&#39;s not
in a dedicated section, &lt;code&gt;[Pod::Weaver]&lt;/code&gt; just lumped it into the
&lt;code&gt;[Leftovers]&lt;/code&gt; section, which by default is near the end of the
document. So, I &lt;a href=&quot;https://github.com/gempesaw/Browsermob-Proxy/commit/7e6e14cb9d8a1dc42bf9882af743176d692269c2&quot;&gt;moved leftovers up to the top&lt;/a&gt; and we&#39;re
&lt;a href=&quot;https://github.com/gempesaw/Browsermob-Proxy&quot;&gt;in business&lt;/a&gt;!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# weaver.ini
[@CorePrep]

[-SingleEncoding]

[Name]
[Leftovers]
[Version]
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(This may be troublesome if other things fall into the Leftovers
section, so we&#39;ll have to keep an eye out...)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>best practices for angular project structure</title>
    <link href="https://blog.danielgempesaw.com/post/angulars-project-structure/"/>
    <updated>2014-04-17T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/angulars-project-structure/</id>
    <content type="html">&lt;p&gt;A few months ago, the AngularJS team published a &lt;a href=&quot;https://docs.google.com/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub&quot;&gt;document&lt;/a&gt;
outlining a new best-practices project structure. There&#39;s also a
(huge) Github &lt;a href=&quot;https://github.com/yeoman/generator-angular/issues/109&quot;&gt;issue discussing its pros and cons&lt;/a&gt; in finer
detail, and it was mentioned in the &lt;code&gt;generator-angular&lt;/code&gt; &lt;a href=&quot;https://github.com/yeoman/generator-angular/issues/553&quot;&gt;2014 Q1
roadmap issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The old recommended structure, which is what &lt;code&gt;yo angular&lt;/code&gt; generates,
groups files together by function: controllers are with other
controllers, directives are with other directives, etc. In some cases,
they&#39;re all even in the same file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app/
    css/
        app.css
        bootstrap.css
    scripts/
        app.js
        controllers/
            main.js
            sidemenu.js
        services/
            backend.js
        directives/
            datepicker.js
    templates/
        datepicker.html
        main.html
    index.html
test/
    spec/
       controllers/
           mainSpec.js
       services/
           backendSpec.js
       directives/
           datepickerSpec.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That was easy for me to grasp initially and due to the strong tooling
built around that structure, it was easy to add new directives and
providers because the tools knew how to navigate the folder structure
and set up the boilerplate. But, I really like the new proposed
structure due to some shortcomings of the old one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It doesn&#39;t scale very well. In a large project, the controllers,
directives, and services folder will each have many files, and the
majority of them will be unrelated to each other.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It&#39;s hard to find things if you don&#39;t know where to look, or if
you&#39;ve just forgotten where you put it. Given a front end component
that in which you found a bug, it&#39;s not immediately evident where
you would look to find and edit that functionality.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When editing a file, it&#39;s not immediately evident from the filename
what kind of file you&#39;re looking at, as the &#39;type-of-thing&#39;
classification is done in the folder name.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The new structure is grouped by components and might look like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app/
    app.js
    index.html
    components/
        datepicker/
            datepicker-directive.js
            datepicker-directive_test.js
            datepicker.html
        backend/
            backend-service.js
            backend-service_test.js
    main/
        main-controller.js
        main-controller_test.js
        main.html
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The components are grouped by functionality and house services,
filters, directives, and related files (templates, test files,
etc). Meanwhile, the sub sections like &lt;code&gt;main&lt;/code&gt; would only have
controllers, css, and templates. I really enjoy using the new layout
and it makes it super easy to switch between the test and the
implementation, since they&#39;re right next to each other.&lt;/p&gt;
&lt;p&gt;When I converted my project to this structure, I had to account for
the new file structure in the Gruntfile and in the karma
configuration. Both of the config files have a useful &lt;code&gt;**/*.js&lt;/code&gt; glob
option that recursively includes all child files that match, but the
&lt;code&gt;bower_components&lt;/code&gt; folder also gets picked up, and then I end up
linting someone else&#39;s files.&lt;/p&gt;
&lt;p&gt;My current project only has one sub-section, &lt;code&gt;editor&lt;/code&gt;, so the end of
the &lt;a href=&quot;https://github.com/gempesaw/honeydew-ng/blob/18045cfd0d50fe48fcb8df9381f80354e7bec32e/karma.conf.js#L40-L45&quot;&gt;karma.conf.js files section looks like&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; // our scripts
 &#39;app/app.js&#39;,
 &#39;app/editor/**/*.js&#39;,
 &#39;app/components/**/*.js&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The gruntfile was a bit more of a pain, since the js files are
referenced in more places. But, the &lt;code&gt;watch:livereload&lt;/code&gt; task after the conversion
looked like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;livereload: {
    options: {
        livereload: &#39;&amp;lt;%= connect.options.livereload %&amp;gt;&#39;
    },
    files: [
        &#39;&amp;lt;%= yeoman.app %&amp;gt;/{components,editor}/**/*.{js,html,css}&#39;,
        &#39;&amp;lt;%= yeoman.app %&amp;gt;/index.html&#39;,
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s a bit unwieldy - the &lt;code&gt;a/{b,c}/e&lt;/code&gt; construct matches &lt;code&gt;a/b/e&lt;/code&gt; and
&lt;code&gt;a/c/e&lt;/code&gt;, and the &lt;code&gt;**/*&lt;/code&gt; does a recursive descent into folders, so that
one line catches everything in components and in my only subsection,
and skips the &lt;code&gt;bower_components&lt;/code&gt; folder.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>An unexpected dump_config error in Dist::Zilla projects using [TravisYML]</title>
    <link href="https://blog.danielgempesaw.com/post/debugging-travis-builds/"/>
    <updated>2014-04-20T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/debugging-travis-builds/</id>
    <content type="html">&lt;h3&gt;1. motivation&lt;/h3&gt;
&lt;p&gt;There&#39;s been a curious &lt;code&gt;dump_config&lt;/code&gt; build error in my Dist::Zilla
Travis-CI builds as of late. I&#39;m using the [TravisYML] Dist::Zilla
plugin to generate my &lt;code&gt;.travis.yml&lt;/code&gt; file, and up until now it&#39;s been
working great. But, there seems to be some dependency conflict that I
don&#39;t have on my local machine - at some point, the travis build box
can no longer run any &lt;code&gt;dzil&lt;/code&gt; commands, as it bombs out with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The method &#39;dump_config&#39; was not found in the inheritance hierarchy
for Dist::Zilla::App::CommandHelper::ChainSmoking at [...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which is then followed by a completely unhelpful (to me) Moose
stacktrace.&lt;/p&gt;
&lt;h3&gt;2. debugging travis builds?&lt;/h3&gt;
&lt;p&gt;I wasn&#39;t aware of a good method to debug travis builds - previously, I
had been just committing minor changes, pushing &#39;em to Github, and
then waiting for the Travis build to kick off. That feedback loop
could take up to 15 minutes, and wasn&#39;t really conducive to any sort
of debugging method.&lt;/p&gt;
&lt;p&gt;I emailed support AT travis-ci.com inquiring about getting access to
one of their build boxes, since the outdated vagrant box method was
&lt;a href=&quot;http://stackoverflow.com/questions/16677232/where-can-i-download-the-64-bit-travis-ci-vm-images/17133843#17133843&quot;&gt;now obsolete&lt;/a&gt; and one of their support staff got back to me
within minutes with a cloud box I could SSH into for 24 hours. Really
pleased with their turnaround time and support, considering it&#39;s a
free service!&lt;/p&gt;
&lt;h3&gt;3. perlbrew on travis debug boxes&lt;/h3&gt;
&lt;p&gt;The box I got had a &lt;code&gt;~/perl5&lt;/code&gt; folder with a bunch of perls already
installed. But, it didn&#39;t have the &lt;code&gt;perlbrew&lt;/code&gt; binary in the path. I
updated the path&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ export PATH=~/perl5/perlbrew/bin:$PATH
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but the commands like &lt;code&gt;perlbrew use&lt;/code&gt; and &lt;code&gt;perlbrew switch&lt;/code&gt; weren&#39;t
having any impact on &lt;code&gt;perl -v&lt;/code&gt;. It turns out I needed to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ perlbrew init
$ source ~/perl5/perlbrew/etc/bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in order to get &lt;code&gt;perl -v&lt;/code&gt; to recognize I didn&#39;t want to use the system
perl anymore. Had I been using more shells, I&#39;d probably want to put
all of that in the ~/.bash_profile, but I only needed the one,
especially since &lt;code&gt;perlbrew lib&lt;/code&gt; lets you manage completely separate
&lt;code&gt;local::lib&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;So, I switched to 5.19 and spun up a new local::lib and started
playing around with dependencies. If I got too far and broke
everything again, a new local::lib can reset all the installed deps
and get me into pristine condition.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ perlbrew switch 5.19
$ perlbrew lib create debug&#92;_dist&#92;_zilla
$ perlbrew use 5.19@debug&#92;_dist&#92;_zilla
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. getting to the heart of the issue&lt;/h3&gt;
&lt;p&gt;The generated &lt;code&gt;.travis.yml&lt;/code&gt; file does a couple of things - it exports
some global variables, configures a bit of necessary git settings, and
then gets to the business of handling author and project dependencies.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cpanm --quiet --notest --skip-satisfied Dist::Zilla
$ dzil authordeps | grep -vP &#39;[^&#92;&#92;w:]&#39; | &#92;
    xargs -n 5 -P 10 cpanm --quiet --notest --skip-satisfied&amp;quot;
$ dzil listdeps   | grep -vP &#39;[^&#92;&#92;w:]&#39; | cpanm --verbose --skip-satisfied&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The travis build boxes come with 5.006 installed, so the first line
actually doesn&#39;t do anything. As reported in the &lt;a href=&quot;https://github.com/SineSwiper/Dist-Zilla-TravisCI/issues/16#issuecomment-40705662&quot;&gt;github issue&lt;/a&gt;,
the &lt;code&gt;dump_config&lt;/code&gt; bug occurs at the &lt;code&gt;dzil listdeps&lt;/code&gt; step. So, one of
the authordeps must be causing it ... probably.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ dzil authordeps --missing | head -n 1 | cpanm --skip-satisfied &amp;amp;&amp;amp; dzil
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It just steps through each of the author dependencies one at a time,
installing it with cpanm, and then verifying that I can still &lt;code&gt;dzil&lt;/code&gt;
afterwards.&lt;/p&gt;
&lt;h3&gt;5. solutions?&lt;/h3&gt;
&lt;p&gt;In not-so stunning turn of events that seems incredibly obvious now,
the problem seems to arise after installing
&lt;a href=&quot;https://metacpan.org/pod/Dist::Zilla::Plugin::TravisYML&quot;&gt;Dist::Zilla::Plugin::TravisYML&lt;/a&gt;. In the generated travis script, the
author deps are installed with &lt;code&gt;cpanm --notest&lt;/code&gt;, so it&#39;s not caught
until the next time we attempt to &lt;code&gt;dzil listdeps&lt;/code&gt;. Stepping through
the tests one by one, the &lt;code&gt;::TravisCI&lt;/code&gt; install actually fails its own
tests with the same &lt;code&gt;dump_config&lt;/code&gt; error that we see in the travis logs
after &lt;code&gt;--notest&lt;/code&gt; installing it.&lt;/p&gt;
&lt;p&gt;So, in theory, commenting out the &lt;code&gt;[TravisYML]&lt;/code&gt; from dist.ini should
remove it from &lt;code&gt;dzil authordeps&lt;/code&gt; and we should be good to go. I&#39;m
going to go try that now...&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Getting started with Ionic and Appium for a new android app</title>
    <link href="https://blog.danielgempesaw.com/post/ionic-and-appium/"/>
    <updated>2014-04-25T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/ionic-and-appium/</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://ionicframework.com/&quot;&gt;Ionic&lt;/a&gt; enables you to author mobile apps using the powerful
&lt;a href=&quot;https://www.angularjs.org/&quot;&gt;AngularJS&lt;/a&gt; javascript framework. &lt;a href=&quot;http://appium.io/&quot;&gt;Appium&lt;/a&gt; is a cross-platform
mobile testing tool that lets you run your app on emulators &lt;em&gt;and&lt;/em&gt; real
devices. Both of these open source projects have full support for iOS
and Android, which is just great. This morning, I worked through
taking a generated Ionic app all the way to my device for testing with
Appium.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;h3&gt;0. prereqs&lt;/h3&gt;
&lt;p&gt;You&#39;ll need &lt;code&gt;ionic&lt;/code&gt; (which depends heavily on &lt;code&gt;cordova&lt;/code&gt;), and
&lt;code&gt;appium&lt;/code&gt;. Ionic needs &lt;code&gt;ant&lt;/code&gt; to build the android app; if you&#39;re using
Homebrew on OS X, they&#39;ve gotcha covered.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install -g cordova ionic appium
$ brew install ant
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&#39;ll also need the &lt;a href=&quot;http://developer.android.com/sdk/index.html?hl=sk&quot;&gt;Android SDK&lt;/a&gt;, which has the Android
Developer Tools in it, I think. I don&#39;t know of a better way to
install them other than downloading the zip and unzipping it to a
known folder. After unzipping the sdk somewhere, you&#39;ll want to add
&lt;code&gt;sdk/tools&lt;/code&gt; and &lt;code&gt;sdk/platform-tools&lt;/code&gt; to your path, and you&#39;ll also
want to export &lt;code&gt;ANDROID_HOME&lt;/code&gt;. Here&#39;s the relevant section of my
&lt;code&gt;~/.bash_profile&lt;/code&gt;; you&#39;ll need to edit &lt;code&gt;ANDROID_HOME&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export ANDROID_HOME=/opt/adt-bundle-mac-x86_64-20140321/sdk
ANDROID_TOOLS=$ANDROID_HOME/tools/:$ANDROID_HOME/platform-tools
export PATH=$ANDROID_TOOLS:$PATH
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Appium will also want you to export &lt;code&gt;$JAVA_HOME&lt;/code&gt;; stackoverflow says
you can &lt;a href=&quot;http://stackoverflow.com/a/1348940/1156644&quot;&gt;do it like this&lt;/a&gt; on OS X Mavericks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export JAVA_HOME=$(/usr/libexec/java_home)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. the ionic half&lt;/h3&gt;
&lt;p&gt;Seeing as I&#39;m not &lt;em&gt;too&lt;/em&gt; concerned with the app itself right now, just
working on getting all the pieces in place, we&#39;ll just use
&lt;code&gt;generator-ionic&lt;/code&gt; as our template.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install -g generator-ionic
$ yo ionic
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;ll lead you through a few set up steps and then generate a
boilerplate app that should be enough to make a baby app. Next thing
to do is to specify that you want android as a platform target:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ionic platform add android
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, you&#39;ll need to have &lt;code&gt;ant&lt;/code&gt; and &lt;code&gt;android&lt;/code&gt; installed and
in your &lt;code&gt;$PATH&lt;/code&gt;, or else the command will fail; see the prereqs part
above if you&#39;re missing anything. Pay a little bit of attention to the
output of this command - in particular, you&#39;ll want to hold on to the
&lt;code&gt;Package&lt;/code&gt; and &lt;code&gt;Activity&lt;/code&gt; lines for firing up Appium via desired
capabilities. I called my toy app &lt;code&gt;Breakside&lt;/code&gt;, so the relevant lines
for me said:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Creating Cordova project for the Android platform:
    Path: platforms/android
    Package: com.example.Breakside
[...snip...]
No project name specified, using Activity name &#39;Breakside&#39;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, you just have to build the &lt;code&gt;.apk&lt;/code&gt; for appium to use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ionic build android
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That should create a couple &lt;code&gt;.apk&lt;/code&gt;s in &lt;code&gt;platforms/android/ant-build&lt;/code&gt;,
including one called suffixed &lt;code&gt;-debug.apk&lt;/code&gt;. That&#39;s what I used for
with Appium in the next step.&lt;/p&gt;
&lt;h3&gt;2. the appium half&lt;/h3&gt;
&lt;p&gt;I ran Appium with my Galaxy Nexus hooked up to my laptop via USB, with
the &lt;a href=&quot;http://developer.android.com/tools/device.html&quot;&gt;USB debugging mode on&lt;/a&gt;; you&#39;ll need to do the same if you
want to run on a device&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/ionic-and-appium/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Appium comes with a useful binary called &lt;code&gt;appium-doctor&lt;/code&gt; which should
be in your path if you&#39;ve installed it with npm. You can run it to
double check whether your system is ready for testing Android devices.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ appium-doctor
Running iOS Checks
[...snip...]

Running Android Checks
✔ ANDROID_HOME is set to &amp;quot;/opt/adt-bundle-mac-x86_64-20140321/sdk&amp;quot;
✔ JAVA_HOME is set to &amp;quot;/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home.&amp;quot;
✔ ADB exists at /opt/adt-bundle-mac-x86_64-20140321/sdk/platform-tools/adb
✔ Android exists at /opt/adt-bundle-mac-x86_64-20140321/sdk/tools/android
✔ Emulator exists at /opt/adt-bundle-mac-x86_64-20140321/sdk/tools/emulator
✔ Android Checks were successful.

✔ All Checks were successful
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you already exported &lt;code&gt;$ANDROID_HOME&lt;/code&gt; and &lt;code&gt;$JAVA_HOME&lt;/code&gt;, everything
should be good to go! Run the &lt;code&gt;appium&lt;/code&gt; command after making sure that
the shell knows about &lt;code&gt;$ANDROID_HOME&lt;/code&gt; and &lt;code&gt;$JAVA_HOME&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ appium &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next thing is figuring out how to tell Appium what you want to
do. I&#39;m using the &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver&quot;&gt;Perl Webdriver bindings&lt;/a&gt;, but luckily desired
capabilities are the same in any language. Here&#39;s my short perl script
script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#! /usr/bin/perl

use strict;
use warnings;
use Selenium::Remote::Driver 0.1951;

my $caps = {
    &#39;app&#39; =&amp;gt; &#39;/opt/breakside/platforms/android/ant-build/Breakside-debug.apk&#39;,
    &#39;app-package&#39; =&amp;gt; &#39;com.example.Breakside&#39;,
    &#39;app-activity&#39; =&amp;gt; &#39;Breakside&#39;,
    &#39;browserName&#39; =&amp;gt; &#39;&#39;,
    &#39;platformName&#39; =&amp;gt; &#39;android&#39;,
};

my $android = Selenium::Remote::Driver-&amp;gt;new_from_caps(
    port =&amp;gt; 4723,
    desired_capabilities =&amp;gt; $caps
);

use DDP;
p $android;
sleep(60); # optional, if you want to see it open on your device
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;$caps&lt;/code&gt; object needs to know where your &lt;code&gt;apk&lt;/code&gt; is, as well
as the &lt;code&gt;app-package&lt;/code&gt; and &lt;code&gt;app-activity&lt;/code&gt; that we saved from earlier&#39;s
&lt;code&gt;ionic platform add android&lt;/code&gt;. The &lt;code&gt;browserName&lt;/code&gt; key is a holdover from
some old Appium dependecies, and &lt;code&gt;platformName&lt;/code&gt; is straightforward.
There&#39;s more information about the appium caps in
&lt;a href=&quot;https://github.com/appium/appium/blob/master/docs/en/caps.md&quot;&gt;their documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Remember to point your bindings at the correct port - by default,
&lt;code&gt;appium&lt;/code&gt; starts up on &lt;code&gt;4723&lt;/code&gt;. Pass in your capabilities object, and
you should be good to go - running that script with my Galaxy Nexus
plugged in on USB debugging mode opened the &lt;a href=&quot;https://24.media.tumblr.com/86e48dd9a4d562ada08f0e1f6a93d7e6/tumblr_n4jfqePOip1qahaiko1_1280.png&quot;&gt;app with the default
Cordova splash screen&lt;/a&gt;. Without that last sleep, the app pops open and
closed too quickly to notice, but of course you can remove it when
writing real test scripts.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;To emulate the Android app, there&#39;s some useful information
about how to get it working if you run &lt;code&gt;ionic emulate android&lt;/code&gt; in the
toy project directory. &lt;a href=&quot;https://blog.danielgempesaw.com/post/ionic-and-appium/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry>
    <title>An AngularJS File Tree (with a PHP backend)</title>
    <link href="https://blog.danielgempesaw.com/post/angular-file-tree/"/>
    <updated>2014-04-25T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/angular-file-tree/</id>
    <content type="html">&lt;p&gt;Something I needed in my AngularJS app was a file tree that exposed a
few folders full of flat files to the user. At the beginning of 2014,
there were only a few google groups &lt;a href=&quot;https://groups.google.com/forum/#!msg/angular/TbpjE-5XEM0/yUi8wqc7sWoJ&quot;&gt;posts&lt;/a&gt; about trees in angular -
apparently the recursive nature of the tree structure made it
complicated to express in the form of directives. Luckily, there are
now a few &lt;a href=&quot;https://github.com/eu81273/angular.treeview&quot;&gt;competing&lt;/a&gt; &lt;a href=&quot;https://github.com/jdewit/ez-file-tree&quot;&gt;file&lt;/a&gt; &lt;a href=&quot;http://nickperkinslondon.github.io/angular-bootstrap-nav-tree/test/bs2_ng115_test_page.html&quot;&gt;tree&lt;/a&gt; &lt;a href=&quot;http://jsfiddle.net/brendanowen/uXbn6/8/&quot;&gt;projects&lt;/a&gt; available. The
one I ended up going with is &lt;a href=&quot;https://github.com/wix&quot;&gt;wix&#39;s&lt;/a&gt; &lt;a href=&quot;http://github.com/wix/angular-tree-control/&quot;&gt;angular-tree-control&lt;/a&gt; for a
few reasons. I&#39;ll go over a few of those reasons, walk through the
frontend usage, and also detail the backend PHP code that generates
the tree in the right format that &lt;code&gt;angular-tree-control&lt;/code&gt; can
appropriately consume.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;h3&gt;1. reasons&lt;/h3&gt;
&lt;p&gt;I went with &lt;code&gt;angular-tree-control&lt;/code&gt; primarily because its light theme
looked the best in that it closely matched the old filetree that this
one was replacing. Most of the other projects weren&#39;t themed
appropriately (or at all) for my project. Although I have a decent
grasp of CSS, I&#39;d much rather leave the styling to some one else and
save myself the time. Additionally, it had the valuable built-in
option of clicking on the label to expand/collapse the children of a
node. This again was a constraint that came from the previous
implementation, and I was aiming to replicate the experience as much
as possible so as not to disrupt my users during the
transition. Finally, the documentation for this project was very good,
complete with a great &lt;a href=&quot;http://wix.github.io/angular-tree-control/&quot;&gt;example page&lt;/a&gt; that mimics the official AngularJS
docs. And, as an added bonus, it&#39;s still under current development,
with the author merging PRs in a timely fashion and recently making a
few new commits last week.&lt;/p&gt;
&lt;h3&gt;2. front-end usage&lt;/h3&gt;
&lt;p&gt;So. Getting the tree into place is &lt;a href=&quot;https://github.com/gempesaw/honeydew-ng/blob/master/app/components/filetree/filetree.html#L28-L34&quot;&gt;pretty straightforward&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;treecontrol&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;tree-classic&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
             &lt;span class=&quot;token attr-name&quot;&gt;tree-model&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;tab.data&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
             &lt;span class=&quot;token attr-name&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;treeOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
             &lt;span class=&quot;token attr-name&quot;&gt;on-selection&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;tree.show(node)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  {{ node.label }}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;treecontrol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;treecontrol&lt;/code&gt; is the name of the directive that we can drop into our
html template. The &lt;code&gt;class&lt;/code&gt; determines its theme; &lt;code&gt;tree-model&lt;/code&gt;
indicates where on the scope our model. &lt;code&gt;options&lt;/code&gt; is the object on our
scope that specifies the options, and &lt;code&gt;on-selection&lt;/code&gt; is our on-click
handler. Finally, the content of the &lt;code&gt;&amp;lt;treecontrol&amp;gt;&lt;/code&gt; element becomes
the label for each node.&lt;/p&gt;
&lt;p&gt;Each node is of the format&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;aBranch&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;aLeaf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the &lt;code&gt;children&lt;/code&gt; array is empty, then the node is displayed as a
leaf/file; otherwise it&#39;s a branch/folder.&lt;/p&gt;
&lt;p&gt;Getting into our controller, we have a few things to set up:&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Prevent Selenium Webdriver&#39;s Firefox from stealing focus on OS X</title>
    <link href="https://blog.danielgempesaw.com/post/firefox-background/"/>
    <updated>2014-05-03T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/firefox-background/</id>
    <content type="html">&lt;p&gt;When I&#39;m composing automated functional browser tests, I usually run
the tests against a local instance of Webdriver on my own computer to
keep the feedback loop tight. Once authoring is done, I&#39;ll kick it off
to Saucelabs for cross-browser testing and additional validation.&lt;/p&gt;
&lt;p&gt;On OS X, if I instantiate a new Chrome webdriver browser, it politely
stays in the background unless I go looking for it, so I can watch and
debug my test output on the CLI. Unfortunately, when Webdriver starts
a test in Firefox, it steals cursor focus, shows up on top of whatever
windows I already have, and interrupts my workflow.&lt;/p&gt;
&lt;p&gt;There&#39;s apparently a plist option that solves this very problem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;key&amp;gt;LSBackgroundOnly&amp;lt;/key&amp;gt;
&amp;lt;string&amp;gt;True&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By adding that to the top of my
&lt;code&gt;/Applications/Firefox.app/Contents/Info.plist&lt;/code&gt; file in the &lt;code&gt;&amp;lt;dict&amp;gt;&lt;/code&gt;
tag, Firefox no longer steals focus. (You may or may not have to
&lt;code&gt;sudo&lt;/code&gt; to edit that file...). Previously:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;plist version=&amp;quot;1.0&amp;quot;&amp;gt;
&amp;lt;dict&amp;gt;
    &amp;lt;key&amp;gt;CFBundleDevelopmentRegion&amp;lt;/key&amp;gt;
    ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and now,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;plist version=&amp;quot;1.0&amp;quot;&amp;gt;
&amp;lt;dict&amp;gt;
    &amp;lt;key&amp;gt;LSBackgroundOnly&amp;lt;/key&amp;gt;
    &amp;lt;string&amp;gt;True&amp;lt;/string&amp;gt;

    &amp;lt;key&amp;gt;CFBundleDevelopmentRegion&amp;lt;/key&amp;gt;
    ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In fact, with that key in the plist, Firefox doesn&#39;t show up in the
Alt-Tab menu, the dock, or in the &lt;code&gt;Force Quit Applications&lt;/code&gt; window
either! When I try to focus on it, it hides behind all other
windows. I ended up having to kill it via command line, which was nice
since I&#39;m trying to get more comfortable with awk.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ps aux | grep [f]irefox | awk &#39;{print $2 &amp;quot; &amp;quot;}&#39; | xargs kill -9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Seeing as it&#39;s a pretty generic plist solution, it probably works for
other apps too. But, it will affect all instances of Firefox, not just
the Webdriver one, so it&#39;s possible this may not be the right solution
if Firefox is your daily browser.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Trimming and down-casing strings with AngularJS Filters: lowercase and limitTo</title>
    <link href="https://blog.danielgempesaw.com/post/ng-trim-last-letter/"/>
    <updated>2014-05-04T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/ng-trim-last-letter/</id>
    <content type="html">&lt;p&gt;I&#39;ve got a small &lt;code&gt;ng-repeat&lt;/code&gt; over this array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$scope.tabs = [
    { label: &amp;quot;Features&amp;quot; },
    { label: &amp;quot;Phrases&amp;quot; },
    { label: &amp;quot;Sets&amp;quot;}
];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I need the labels to be capitalized in at least one place, as I&#39;m using
them as tab headers via &lt;a href=&quot;http://angular-ui.github.io/bootstrap/#/tabs&quot;&gt;UI-Bootstrap&#39;s Tab component&lt;/a&gt;. But, I&#39;d
like to also use the same text lowercased and in their singular forms,
so I can have &lt;a href=&quot;https://github.com/gempesaw/honeydew-ng/blob/4e81a41a602b606bfcefd80db07113e11ecd4c24/app/components/filetree/filetree.html#L9&quot;&gt;placeholder text&lt;/a&gt; like &amp;quot;search for your feature
files&amp;quot;. Enter the &lt;code&gt;lowercase&lt;/code&gt; and &lt;code&gt;limitTo&lt;/code&gt; filters!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lowercase&lt;/code&gt; does pretty much what you&#39;d expect:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{{ &amp;quot;Features&amp;quot; | lowercase }} =&amp;gt; features
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and on strings, &lt;code&gt;limitTo:integer&lt;/code&gt; trims the string length to the
specified integer argument. I tried putting an expression in as the
argument to &lt;code&gt;limitTo&lt;/code&gt; on a whim, and it worked wonderfully (&lt;a href=&quot;http://plnkr.co/edit/Lfg897uxorHno5QpU1VI?p=preview&quot;&gt;plnkr&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{{ &amp;quot;Features&amp;quot; | lowercase | limitTo: &amp;quot;Features&amp;quot;.length - 1 }} =&amp;gt; feature
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can of course replace &amp;quot;Features&amp;quot; with a variable on your scope to
make that more versatile - my expression with the array above ended up
being:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{{ tab.label | lowercase | limitTo: tab.label.length - 1 }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;N.B. - make sure you&#39;ve got your scope
&lt;a href=&quot;https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-repeat&quot;&gt;inheritance sorted when you&#39;re using &lt;code&gt;ng-repeat&lt;/code&gt;&lt;/a&gt; - bind to
objects, not primitives :)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Cleaning up whitespace in directories with some elisp</title>
    <link href="https://blog.danielgempesaw.com/post/cleanup-whitespace-in-directory/"/>
    <updated>2014-05-05T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/cleanup-whitespace-in-directory/</id>
    <content type="html">&lt;p&gt;I had a project with an outdated indentation convention. Present-me
recently decided to change bracket conventions from the way past-me
had been doing things. So, I updated my emacs settings so that
&lt;a href=&quot;http://whattheemacsd.com/buffer-defuns.el-01.html&quot;&gt;magnar&#39;s&lt;/a&gt; &lt;code&gt;(cleanup-buffer)&lt;/code&gt; function would properly format the
files. But, there were multiple files in the project and I didn&#39;t feel
like manually opening each one just to cleanup (&lt;code&gt;C-c n&lt;/code&gt;) and save
(&lt;code&gt;M-s&lt;/code&gt;) it. So, I had emacs do it for me, relying heavily on the
excellent &lt;a href=&quot;https://github.com/rejeep/f.el&quot;&gt;&lt;code&gt;f.el&lt;/code&gt;&lt;/a&gt; library and the aforementioned
&lt;code&gt;(cleanup-buffer)&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require &#39;f)
(defun cleanup-in-directory (directory &amp;amp;optional match recursive)
  (let* ((matcher (if (not (eq nil match))
                      (lambda (file) (string-match match it))
                    nil))
         (files (f-files directory matcher recursive)))
    (mapc (lambda (file)
            (ignore-errors
              (find-file file)
              (cleanup-buffer)
              (save-buffer)))
          files)))

(cleanup-in-directory &amp;quot;/opt/honeydew/lib&amp;quot; &amp;quot;.pm$&amp;quot; t)
(cleanup-in-directory &amp;quot;/opt/honeydew/bin&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It takes a directory, a regex to optionally match against, and a flag
to determine whether or not to recurse the parent directory. Small
problem, small elisp: problem solved :).&lt;/p&gt;
&lt;p&gt;I did glance at the changes before committing them, and caught one case where the formatter got confused and stopped indenting things
entirely, but there was only one such case that I noticed...&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Cannot open load file: subst-ksc - os x 10.9.2, emacs 24.4.50.1</title>
    <link href="https://blog.danielgempesaw.com/post/subst-ksc/"/>
    <updated>2014-05-17T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/subst-ksc/</id>
    <content type="html">&lt;p&gt;I&#39;m on OS X Mavericks 10.9.2, running Emacs 24.4.50.1 GNU Emacs
24.4.50.1 (x86_64-apple-darwin13.1.0, NS apple-appkit-1265.19)
&lt;a href=&quot;http://blog.danielgempesaw.com/post/81019534028/emacs-24-use-homebrew-instead-of-emacsformacosx&quot;&gt;compiled via homebrew&lt;/a&gt;. I was trying to get back into Emacs
package authoring with the help of &lt;a href=&quot;https://github.com/rejeep&quot;&gt;rejeep&#39;s&lt;/a&gt; excellent &lt;a href=&quot;https://cask.github.io/&quot;&gt;Cask&lt;/a&gt; and
&lt;a href=&quot;https://github.com/rejeep/ert-runner.el&quot;&gt;ert-runner&lt;/a&gt; tools, but I was getting an error that didn&#39;t pop up on
Google very well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bash-3.2$ cask exec emacs -batch -l test/grunt-test.el
Cannot open load file: subst-ksc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Searching for &lt;code&gt;subst-ksc&lt;/code&gt; on google pops up results from other OS X
users from two or three years ago and no obvious fixes. I tried a
couple different things and ended up putting a fake &lt;code&gt;subst-ksc.el&lt;/code&gt;
file in my load path with &lt;code&gt;(provide &#39;subst-ksc)&lt;/code&gt; in it just to push past
the error, but that just gave more of the same:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bash-3.2$ cask exec emacs -batch -l test/grunt-test.el
Cannot open load file: subst-gb2312
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eventually, I realized via &lt;code&gt;$ emacs --version&lt;/code&gt; that I recently
switched to a new computer where I didn&#39;t symlink/replace the default
&lt;code&gt;/usr/bin/emacs&lt;/code&gt; binary with my newer homebrew&#39;d version. I tried the
new method &lt;a href=&quot;http://blog.danielgempesaw.com/post/43467552978/installing-mu-and-mu4e-with-homebrew-with-emacs-from#comment-1388528799&quot;&gt;recommended in the comments&lt;/a&gt; of replacing that file with a short shell script to invoke the proper emacs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs &amp;quot;$@&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and all became well.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Playing with the new Perl bindings for the BrowserMob Proxy</title>
    <link href="https://blog.danielgempesaw.com/post/perl-browsermob-proxy/"/>
    <updated>2014-05-24T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/perl-browsermob-proxy/</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://bmp.lightbody.net/&quot;&gt;Browsermob Proxy&lt;/a&gt; is an open source project that
&lt;a href=&quot;https://github.com/lightbody&quot;&gt;Patrick Lightbody&lt;/a&gt; split off from the main Selenium project. It
works really well in tandem with Selenium Webdriver, but it was
missing Perl bindings. BMP exposes a RESTish interface for interacting
with the proxies, so I&#39;ve strung together a Perl module to take care
of it: &lt;a href=&quot;https://metacpan.org/pod/Browsermob::Proxy&quot;&gt;Browsermob::Proxy&lt;/a&gt;. Amongst other things, you can use BMP
to throttle net traffic during tests, analyze request/response pairs
for things like Omniture and Google Analytics, and even alter the
requests on the fly with custom headers. Here&#39;s a short run down and
some basic get-started scripts for using it!&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;The bindings are up on CPAN with pretty limited functionality at the
moment - definitely not the full BMP API. It can create proxies and
HARs, and spit out the HARs back out when requested, but it doesn&#39;t do
much else besides that as of v0.04. To get up and running with BMP,
you&#39;ll need to download the binary from the &lt;a href=&quot;http://bmp.lightbody.net/&quot;&gt;BMP website&lt;/a&gt; and
then execute the appropriate file in its &lt;code&gt;bin/&lt;/code&gt; folder to start the
BMP server.&lt;/p&gt;
&lt;p&gt;Here&#39;s an example of using &lt;a href=&quot;https://metacpan.org/pod/Browsermob::Proxy&quot;&gt;Browsermob::Proxy&lt;/a&gt; with
&lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver&quot;&gt;Selenium::Remote::Driver&lt;/a&gt; to capture all of the network traffic
during a single request to google:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#! /usr/bin/perl

use strict;
use warnings;
use DDP;
use Browsermob::Proxy;
use Selenium::Remote::Driver;

my $proxy = Browsermob::Proxy-&amp;gt;new(
    server_port =&amp;gt; 8080,
);

my $driver = Selenium::Remote::Driver-&amp;gt;new(
    browser_name =&amp;gt; &#39;chrome&#39;,
    proxy        =&amp;gt; $proxy-&amp;gt;selenium_proxy
);

$driver-&amp;gt;get(&#39;https://www.google.com&#39;);

p $proxy-&amp;gt;har;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is assuming your BMP server is already downloaded and currently
running on port 8080. But, that&#39;s all we need to create a new proxy
for the Chrome browser that Selenium::Remote::Driver is about to
make. The &lt;code&gt;$proxy&lt;/code&gt; comes with a convenience method &lt;code&gt;selenium_proxy()&lt;/code&gt;
that returns the appropriate desired capabilities to configure the
proxy for use with Chrome. (If you want to use a proxy with Firefox,
you&#39;ll need to use a &lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver::Firefox::Profile&quot;&gt;custom Firefox profile&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Once we&#39;ve instantiated our driver, having told it to use the proxy,
all that&#39;s left is to create some traffic and spit out the HAR.&lt;/p&gt;
&lt;p&gt;If you want to try out the module without having to install
Selenium::Remote::Driver, you can just &lt;code&gt;curl&lt;/code&gt; some traffic across the
proxy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#! /usr/bin/perl

use strict;
use warnings;
use DDP;
use Browsermob::Proxy;

my $proxy = Browsermob::Proxy-&amp;gt;new(
    server_port =&amp;gt; 8080,
);

$proxy-&amp;gt;new_har;
my $generate_traffic = &#39;curl -x http://127.0.0.1:&#39; . $proxy-&amp;gt;port
    . &#39; http://www.google.com &amp;gt; /dev/null 2&amp;gt;&amp;amp;1&#39;;

`$generate_traffic`;
p $proxy-&amp;gt;har;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a proxy in exactly the same fashion and then uses &lt;code&gt;curl&lt;/code&gt;
to generate the traffic.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Upcoming updates for Selenium::Remote::Driver</title>
    <link href="https://blog.danielgempesaw.com/post/s-r-d-v22-updates/"/>
    <updated>2014-10-20T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/s-r-d-v22-updates/</id>
    <content type="html">&lt;p&gt;We&#39;re gearing up for the release of v0.22 of Selenium-Remote-Driver, a set of Perl bindings for the Webdriver project. My primary motivation to get a new release out is to tweak some of the classes to be more easily extended, so that the perl bindings for &lt;a href=&quot;https://github.com/appium/perl-client&quot;&gt;Appium&lt;/a&gt; can be written more cleanly. But, there&#39;s also some cleanup for deprecated functions and a few bugfixes included, along with plans for another release in the near future.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before we get in to the changes, here&#39;s a heads up about the new mailing list for the perl bindings: https://groups.google.com/forum/#!forum/selenium-remote-driver :D&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A new subroutine &lt;code&gt;get_user_agent&lt;/code&gt; will be making it into the API for Driver.pm as a convenience method to, well, get the user agent!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The main &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver/commit/63e78e3&quot;&gt;changes&lt;/a&gt; for Appium were allowing for more dependency injection of classes like &lt;code&gt;::RemoteConnection&lt;/code&gt; and &lt;code&gt;::ErrorHandler&lt;/code&gt;. This lets us tweak things in the Appium module to address discrepancies between Appium and Webdriver. This is also the case for the &lt;code&gt;FINDERS&lt;/code&gt; constant defined in the &lt;code&gt;::Driver&lt;/code&gt; class - previously, the constant was privately scoped to Driver.pm, preventing modification from Appium.pm. But Appium has a different list of acceptable finders. So, &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver/commit/ea68e064fcf442cef1e1f9d0f9f1e01953c30dee&quot;&gt;ea68e0&lt;/a&gt; makes it so the &lt;code&gt;Appium&lt;/code&gt; class can declare its own &lt;code&gt;FINDERS&lt;/code&gt; constant via the &lt;code&gt;use constant&lt;/code&gt; pragma.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Thanks to a few updates to &lt;a href=&quot;https://metacpan.org/pod/Dist::Zilla::Plugin::TravisYML&quot;&gt;Dist::Zilla::Plugin::TravisYML&lt;/a&gt;, our Travis tests are passing again on the &lt;code&gt;master&lt;/code&gt; branch instead of just on &lt;code&gt;cpan&lt;/code&gt; - there used to be test failures just getting Dist::Zilla to install, even though our own tests were passing. The most recent version of ::TravisYML fixed those issues!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/peroumal1&quot;&gt;peroumal1&lt;/a&gt; caught a couple deprecated functions that will now be throwing warnings - &lt;code&gt;get_speed&lt;/code&gt;, and &lt;code&gt;set_speed&lt;/code&gt; are already no-ops and now will be warning appropriately. The same goes for the &lt;code&gt;drag&lt;/code&gt; subroutine in &lt;code&gt;::WebElement&lt;/code&gt;, which no longer seems to be in the (not actually official) &lt;a href=&quot;https://code.google.com/p/selenium/wiki/JsonWireProtocol&quot;&gt;JSONWireProtocol&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A few bugfixes made it in, including more helpful error messaging when failing to initiate a session on Saucelabs, or when chromedriver is incorrectly configured. There was also a casting issue reported that I still can&#39;t reproduce for setting window size where the JSON conversion was using strings instead of integers (&amp;quot;1280&amp;quot; x &amp;quot;1024&amp;quot; vs 1280 x 1024). I still can&#39;t reproduce the issue, but I can&#39;t imagine the fix to cast the variables into integers causing any other problems, so I&#39;ll probably include it anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On the horizon, we&#39;ve got a rewrite of our recording/mocking functionality on the way, courtesy of &lt;a href=&quot;https://github.com/peroumal1&quot;&gt;peroumal1&lt;/a&gt;. Looking over the code in their &lt;a href=&quot;https://github.com/peroumal1/Selenium-Remote-Driver/tree/mock-driver-experiment&quot;&gt;mock-driver-experiment&lt;/a&gt; branch, things seem to be shaping up quite nicely. This is a welcome change because we&#39;ve been dealing with a complicated process and an explicit dependency on LWP::Protocol::PSGI v0.04 to generate our recordings, effectively preventing anyone else from contributing recordings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of release versions, this is the numbering scheme I&#39;m trying to use. The impression I&#39;ve gotten is that CPAN version numbering is a bit of a grab bag, so perhaps explanation is in order.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;A point increase for deliberate releases with new/important functionality - ie, 0.21 to 0.22.&lt;/li&gt;
&lt;li&gt;A minor version increase for bugfixes - 0.21 to 0.2101 to 0.2102, etc.&lt;/li&gt;
&lt;li&gt;Dev releases to prepare for the next point release go out on the 0.XX50 namespace and increment - so, 0.2150, 0.2151, etc.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  
  <entry>
    <title>drag&#39;n&#39;drop with Perl, Webdriver, and Selenium::Remote::Driver</title>
    <link href="https://blog.danielgempesaw.com/post/perl-webdriver-drag-and-drop/"/>
    <updated>2014-11-23T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/perl-webdriver-drag-and-drop/</id>
    <content type="html">&lt;p&gt;&lt;small&gt;(This post is direct language translation of
&lt;a href=&quot;http://elementalselenium.com/tips/39-drag-and-drop&quot;&gt;ep 39&lt;/a&gt; of
&lt;a href=&quot;http://elementalselenium.com/&quot;&gt;Elemental Selenium&lt;/a&gt;, Dave Haeffner&#39;s
Ruby series about Webdriver. Go check &#39;em out, even if you don&#39;t use
Ruby, as Webdriver concepts are the same across bindings. We&#39;re even
reusing his fixture code, as it&#39;s quite useful!)&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Although the webdriver protocol offers a few endpoints that allow you
to accomplish drag and drop (&lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver#button_down&quot;&gt;button_down&lt;/a&gt;,
&lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver#mouse_move_to_location&quot;&gt;mouse_move_to_location&lt;/a&gt;, and &lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver#button_up&quot;&gt;button_up&lt;/a&gt;), there&#39;s an
&lt;a href=&quot;https://code.google.com/p/selenium/issues/detail?id=6315&quot;&gt;outstanding bug in webdriver for those endpoints on HTML5 pages.&lt;/a&gt;
So, there&#39;s nothing we can do from the side of the Perl bindings, as
invoking the endpoints won&#39;t actually do the drag and drop. Luckily,
there&#39;s a javascript workaround that allows us to
&lt;a href=&quot;https://gist.github.com/rcorreia/2362544&quot;&gt;simulate drag and drop events&lt;/a&gt; with jQuery (or Zepto), courtesy of
Rob Correia&#39;s gist.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;First things first, you&#39;ll need the helper javascript downloaded
somewhere - you can use &lt;code&gt;__FILE__&lt;/code&gt; or
&lt;a href=&quot;https://metacpan.org/pod/FindBin&quot;&gt;&lt;code&gt;FindBin&lt;/code&gt;&lt;/a&gt; to locate it relative to
your perl script. Assuming you save the helper js as &lt;code&gt;drag.js&lt;/code&gt; in the
same directory as your test script, your test might look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#! /usr/bin/perl

use strict;
use warnings;
use FindBin;
use Selenium::Remote::Driver;
use Test::More;

my $d = Selenium::Remote::Driver-&amp;gt;new;

$d-&amp;gt;get(&#39;http://blog.danielgempesaw.com/post/103347925809&#39;);

my $grab = $d-&amp;gt;find_element(&#39;column-a&#39;, &#39;id&#39;);
my $target = $d-&amp;gt;find_element(&#39;column-b&#39;, &#39;id&#39;);

my $drag_file = $FindBin::Bin . &#39;/drag.js&#39;;
open (my $fh, &amp;quot;&amp;lt;&amp;quot;, $drag_file);
my $drag_js = join(&#39;&#39;, &amp;lt;$fh&amp;gt;);
close ($fh);

my $simulate_js = &#39;$(arguments[0]).simulateDragDrop({ dropTarget: arguments[1] })&#39;;
$d-&amp;gt;execute_script( $drag_js . $simulate_js, $grab, $target);

is($grab-&amp;gt;get_text, &#39;B&#39;, &#39;text in column-a has changed!&#39;);
is($target-&amp;gt;get_text, &#39;A&#39;, &#39;text in column-b has changed!&#39;);

$d-&amp;gt;quit;

done_testing;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is accomplishing exactly the same thing as the Ruby version of
the script. We load up our driver, get to our test page, and then
we&#39;re deviating slightly. I prefer to find the elements in webdriver
separately and pass them into the &lt;code&gt;execute_script&lt;/code&gt;, as my framework
allows users to locate elements in various with multiple &lt;code&gt;by&lt;/code&gt;
strategies, so we&#39;d need account for that deviation. Luckily,
&lt;code&gt;execute_script&lt;/code&gt; puts any additional arguments it receives into the
special &lt;code&gt;arguments&lt;/code&gt; array in javascript, transforming them to and from
actual DOM elements if necessary. So our &lt;code&gt;$grab&lt;/code&gt; and &lt;code&gt;$target&lt;/code&gt; are
available in their DOM element form as &lt;code&gt;arguments[0]&lt;/code&gt; and
&lt;code&gt;arguments[1]&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;The final step is to concatenate the tiny drag library with the
javascript to simulate the drag and drop. After that, we just verify
that the text in the columns changed, and we&#39;re good to go!&lt;/p&gt;
&lt;p&gt;I&#39;m wondering if I should include the &lt;code&gt;$drag_js&lt;/code&gt; in
Selenium::Remote::Driver somewhere. We recently found a deprecated
&lt;code&gt;drag&lt;/code&gt; method on our WebElement class - since the &lt;code&gt;drag&lt;/code&gt; endpoint no
longer exists in the JSONWireProtocol, we&#39;ve begun the process to
deprecate it in our module. However, the aforementioned workaround
means that we could restore our binding&#39;s &lt;code&gt;drag&lt;/code&gt; method with this hack
until an official fix comes in. But, the official fix might lead to a
change in API that would confuse our users.&lt;/p&gt;
&lt;p&gt;On the one hand, it always feels a bit icky to include javascript in a
perl module. On the other hand, drag and drop is pretty commonly
requested and it could be useful to many users. I think I&#39;ll leave it
out of our library until there&#39;s an explicit need for it, and point
people to this method until then.&lt;/p&gt;
&lt;div class=&quot;drag&quot;&gt;
  &lt;h4&gt;Drag and Drop Test Fixture&lt;/h4&gt;
  &lt;div id=&quot;columns&quot;&gt;
    &lt;div class=&quot;column&quot; id=&quot;column-a&quot; draggable=&quot;true&quot;&gt;&lt;header&gt;A&lt;/header&gt;&lt;/div&gt;
    &lt;div class=&quot;column&quot; id=&quot;column-b&quot; draggable=&quot;true&quot;&gt;&lt;header&gt;B&lt;/header&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;style&gt;
.drag .columns {
  width: 400px;
}
.drag .column {
  height: 150px;
  width: 150px;
  float: left;
  border: 2px solid #666666;
  background-color: #ccc;
  margin-right: 5px;
  text-align: center;
  cursor: move;
}
.drag .column.over {
  border: 2px dashed #000;
}

&lt;/style&gt;
&lt;script&gt;
var dragSrcEl = null;

function handleDragStart(e) {
  this.style.opacity = &#39;0.4&#39;;

  dragSrcEl = this;

  e.dataTransfer.effectAllowed = &#39;move&#39;;
  e.dataTransfer.setData(&#39;text/html&#39;, this.innerHTML);
}

function handleDragOver(e) {
  if (e.preventDefault) {
    e.preventDefault();
  }

  e.dataTransfer.dropEffect = &#39;move&#39;;

  return false;
}

function handleDragEnter(e) {
  this.classList.add(&#39;over&#39;);
}

function handleDragLeave(e) {
  this.classList.remove(&#39;over&#39;);
}

function handleDrop(e) {
  if (e.stopPropagation) {
    e.stopPropagation();
  }

  if (dragSrcEl != this) {
    dragSrcEl.innerHTML = this.innerHTML;
    this.innerHTML = e.dataTransfer.getData(&#39;text/html&#39;);
  }

  return false;
}

function handleDragEnd(e) {
  [].forEach.call(cols, function (col) {
    col.classList.remove(&#39;over&#39;);
  });
  this.style.opacity = &#39;1&#39;;
}

var cols = document.querySelectorAll(&#39;#columns .column&#39;);
[].forEach.call(cols, function(col) {
  col.addEventListener(&#39;dragstart&#39;, handleDragStart, false);
  col.addEventListener(&#39;dragenter&#39;, handleDragEnter, false);
  col.addEventListener(&#39;dragover&#39;, handleDragOver, false);
  col.addEventListener(&#39;dragleave&#39;, handleDragLeave, false);
  col.addEventListener(&#39;drop&#39;, handleDrop, false);
  col.addEventListener(&#39;dragend&#39;, handleDragEnd, false);
});
&lt;/script&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js&quot;&gt;&lt;/script&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Using SIPE through Bitlbee in Emacs on OS X Mavericks</title>
    <link href="https://blog.danielgempesaw.com/post/sipe-bitlbee-and-mavericks/"/>
    <updated>2014-12-10T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/sipe-bitlbee-and-mavericks/</id>
    <content type="html">&lt;p&gt;I like using Emacs as often as possible. Our work server was
previously jabber, so I was using the excellent &lt;code&gt;jabber.el&lt;/code&gt; to chat
with my coworkers. We&#39;re switching over to Microsft Lync, so it
appears my best option is to use Bitlbee and an Emacs IRC client (like
&lt;a href=&quot;https://github.com/jorgenschaefer/circe&quot;&gt;Circe&lt;/a&gt;!). Bitlbee is a server that you can run on your computer
that acts as a gateway to different chat protocols. It handily exposes
your IM interactions to you through an IRC server. One of the
protocols it supports is SIPE, which is what Microsoft Lync uses. It
was slightly involved to get all the pieces working together; here are
the steps I followed.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;h3&gt;1. get pidgin and bitlbee&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ brew update
$ brew install bitlbee --with-pidgin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--with-pidgin&lt;/code&gt; specifies the &lt;code&gt;pidgin&lt;/code&gt; package as a dependency, which
I believe we&#39;ll need to manually compile &lt;code&gt;pidgin-sipe&lt;/code&gt;, since it&#39;s not
available on homebrew. In case &lt;code&gt;brew link bitlbee&lt;/code&gt; doesn&#39;t put &lt;code&gt;bitlbee&lt;/code&gt; in your path, you can just&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ln -s /usr/local/Cellar/bitlbee/3.2.2/sbin/bitlbee /usr/local/bin/bitlbee
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. get pidgin-sipe&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pidgin-sipe&lt;/code&gt; will teach bitlbee how to speak SIPE! Download the
latest tarball from the sipe project &lt;a href=&quot;http://sourceforge.net/projects/sipe/files/sipe/&quot;&gt;on SourceForge&lt;/a&gt;. At time
of writing, the direct download link to 1.18.4 is &lt;a href=&quot;http://sourceforge.net/projects/sipe/files/sipe/pidgin-sipe-1.18.4/pidgin-sipe-1.18.4.tar.gz/download&quot;&gt;here&lt;/a&gt;. Compiling
it requires &lt;code&gt;gettext&lt;/code&gt;, and it may not be linked by default, so link it if necessary:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ brew link --force gettext
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unzip the &lt;code&gt;pidgin-sipe.tar.gz&lt;/code&gt; tarball, get in that folder, and get to work &lt;a href=&quot;http://sourceforge.net/p/sipe/discussion/688534/thread/9b11e2b4&quot;&gt;compiling&lt;/a&gt;
it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ./configure --disable-quality-check --prefix=/usr/local/
$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;-prefix&lt;/code&gt; option apparently is used to tell pidgin-sipe where to find the libpurple files that we installed as part of &lt;code&gt;pidgin&lt;/code&gt; during the earlier &lt;code&gt;bitlbee --with-pidgin&lt;/code&gt; step.&lt;/p&gt;
&lt;h3&gt;3. tell bitlbee what&#39;s up!&lt;/h3&gt;
&lt;p&gt;Once you&#39;ve got &lt;code&gt;pidgin&lt;/code&gt;, &lt;code&gt;pidgin-sipe&lt;/code&gt;, and &lt;code&gt;bitlbee&lt;/code&gt; all installed,
you should be able to get started playing around with bitlbee
(finally!). You&#39;ll want to run it in ForkDaemon mode via &lt;code&gt;-F&lt;/code&gt;, as it
suggests as a consequence of compiling &lt;code&gt;--with-pidgin&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ bitlbee -F
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fire up your IRC client of choice and connect to &lt;code&gt;localhost:6667&lt;/code&gt; and
join the control channel &amp;quot;&amp;amp;bitlbee&amp;quot;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/sipe-bitlbee-and-mavericks/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. Say &lt;code&gt;help purple&lt;/code&gt; in the
&amp;amp;bitlbee channel to see your potential protocols, and hopefully &lt;code&gt;sipe (Office Communicator)&lt;/code&gt; will show up in the list! If it&#39;s missing,
you&#39;ll need to go back and verify your dependencies. Forging bravely
on, add an account with the sipe protocol - although the &lt;a href=&quot;http://wiki.bitlbee.org/HowtoSIPE&quot;&gt;Bitlbee wiki&lt;/a&gt; says to include DOMAIN&#92;LOGIN for the &lt;code&gt;account add sipe&lt;/code&gt; command, I left it blank and had no troubles logging in. YMMV.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;account add sipe EMAIL@ADDRESS.COM PASSWORD
account sipe set authentication tls-dsk
account sipe set useragent &amp;quot;UCCAPI/15.0.4481.1000 OC/15.0.4481.1000 (Microsoft Lync)&amp;quot;
account 0 on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There were a final few things to tweak: we needed to set the
authentication scheme (TLS-DSK) and masquerade as an actual lync
client by setting our user agent&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/sipe-bitlbee-and-mavericks/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;, but after that, we get the golden
output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;root&amp;gt; sipe - Logging in: Connecting
&amp;lt;root&amp;gt; sipe - Logging in: Logged in
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use &lt;code&gt;blist all&lt;/code&gt; to see your verbose buddy list, and chat away! Ta-da!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;small&gt;Honestly, I&#39;m not very good at IRC so it might bring up that
channel automatically, or something - I&#39;m autojoined to it in Circe,
at least. You can optionally register an admin account to persist
your settings via bitlbee&#39;s &lt;code&gt;register&lt;/code&gt;, and subsequently &lt;code&gt;identify&lt;/code&gt;,
commands.&lt;/small&gt; &lt;a href=&quot;https://blog.danielgempesaw.com/post/sipe-bitlbee-and-mavericks/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;small&gt;And perhaps we need to set an environment variable? I
didn&#39;t need to, but obviously some people did:
http://blog.mattwoodward.com/2012/08/pidgin-sipe-and-read-error-on-ubutnu.html&lt;/small&gt; &lt;a href=&quot;https://blog.danielgempesaw.com/post/sipe-bitlbee-and-mavericks/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Getting Started with the Appium Perl Bindings</title>
    <link href="https://blog.danielgempesaw.com/post/appium-perl-client/"/>
    <updated>2015-01-08T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/appium-perl-client/</id>
    <content type="html">&lt;p&gt;We&#39;ve started work on a set of Perl client bindings for Appium. We&#39;re
using Appium to test out a few different ideas for mobile apps, and
since our existing browser automation framework is written in Perl, it
makes sense to use Perl for our mobile automation as well. I recently
received an email from probably the first person other than myself
interested in such a pairing (Perl &amp;amp; Appium) for some help getting
started, so I&#39;m putting together a collection of steps to get going
with the Appium Perl bindings.&lt;/p&gt;
&lt;h3&gt;1. Install Appium&lt;/h3&gt;
&lt;p&gt;You can install Appium via npm:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; npm install -g appium
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It comes with a helpful binary &lt;code&gt;appium-doctor&lt;/code&gt; that will give you the
status of your setup. The Appium project has official
&lt;a href=&quot;http://appium.io/slate/en/master/#setting-up-appium&quot;&gt;installation docs&lt;/a&gt;, and I made a &lt;a href=&quot;http://blog.danielgempesaw.com/post/83809119400/getting-started-with-ionic-and-appium-for-a-new&quot;&gt;previous post&lt;/a&gt; with
OS X steps on this blog a few months ago. This post will be slightly
more Windows focused, but it&#39;s all a bit theoretical, as I&#39;m not using
a Windows machine to write this post :P. For running Android tests
specifically, you&#39;ll need to download the Android SDK Tools, and
set/modify a couple environment variables; we&#39;ve broken each part down
into the following steps.&lt;/p&gt;
&lt;h3&gt;2. Download Android Dependencies&lt;/h3&gt;
&lt;p&gt;Follow the &lt;a href=&quot;http://developer.android.com/sdk/installing/index.html?pkg=tools&quot;&gt;instructions&lt;/a&gt; on the Android Developer website for
downloading at least the SDK Tools. After the download, you&#39;ll need to
open the SDK Manager and get the appropriate tools that correspond to
the version of Android you&#39;re interested in; the Android developer
website has a &lt;a href=&quot;http://developer.android.com/sdk/installing/adding-packages.html#GetTools&quot;&gt;short guide on how to do so&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://developer.android.com/images/sdk_manager_packages.png&quot; alt=&quot;sdk manager&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From the Tools folder, you definitely want the &lt;code&gt;SDK Tools&lt;/code&gt;, the
&lt;code&gt;Platform-Tools&lt;/code&gt;, and the &lt;code&gt;Build-Tools&lt;/code&gt;. Choose the highest version of
Android, or whatever version of Android your device has, and select at
least the &lt;code&gt;SDK Platform&lt;/code&gt; and a system image like &lt;code&gt;ARM EABI v7a System Image&lt;/code&gt;. My SDK Manager looks like
&lt;a href=&quot;http://monosnap.com/image/qiC1NNcPMZaNJqamSBEnNNQRRqplkz&quot;&gt;this with those checked&lt;/a&gt;. Select at least those, click
&lt;code&gt;Install packages...&lt;/code&gt; and accept all the licenses for those packages.&lt;/p&gt;
&lt;h3&gt;3. Set up Android Environment Variables&lt;/h3&gt;
&lt;p&gt;You&#39;ll need to set &lt;code&gt;JAVA_HOME&lt;/code&gt; if it&#39;s not set; Atlassian has a
&lt;a href=&quot;https://confluence.atlassian.com/display/DOC/Setting+the+JAVA_HOME+Variable+in+Windows&quot;&gt;nice article&lt;/a&gt; about doing that. You&#39;ll need to do the same
thing for &lt;code&gt;ANDROID_HOME&lt;/code&gt;: find the path of where you downloaded the
Android SDK, create a new environment variable called &lt;code&gt;ANDROID_HOME&lt;/code&gt;
and set it to the download path of the sdk.&lt;/p&gt;
&lt;p&gt;Finally, you need to add the &lt;code&gt;tools/&lt;/code&gt; and &lt;code&gt;platform-tools/&lt;/code&gt;
directories inside of &lt;code&gt;ANDROID_HOME&lt;/code&gt; to your PATH. It will be in the
same place as when you edited &lt;code&gt;JAVA_HOME&lt;/code&gt; and &lt;code&gt;ANDROID_HOME&lt;/code&gt;; choose
to edit the &lt;code&gt;PATH&lt;/code&gt; variable and add
&lt;code&gt;;E:&#92;android-sdk&#92;tools;E:&#92;android-sdk&#92;platform-tools&lt;/code&gt; to the end,
assuming of course that your SDK was in &lt;code&gt;E:&#92;android-sdk&#92;&lt;/code&gt;; adjust as
necessary.&lt;/p&gt;
&lt;h3&gt;4. Build or obtain an .apk of your app, or pre-install it&lt;/h3&gt;
&lt;p&gt;This will vary wildly depending on the app you&#39;re building and your
particular build tools. Build your app and get a hold the path to your
&lt;code&gt;.apk&lt;/code&gt;. You also have the option to pre-install the app on the
emulator or device on which you will be testing.&lt;/p&gt;
&lt;h3&gt;5. Make and start your Android emulator&lt;/h3&gt;
&lt;p&gt;If you&#39;re using a real device, plug it in and allow the USB debugging
permissions when prompted on your device. You may need to install
drivers, or perhaps Windows is smart enough to do it for you - I can&#39;t
quite recall.&lt;/p&gt;
&lt;p&gt;Alternatively, you can create and start an emulator with the following
commmands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; android create avd --force -n appium -t android-21 --abi x86
&amp;gt; emulator @appium
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That will create an Android Emulator called &amp;quot;appium&amp;quot; for the latest
version of android (android-21/lollipop). The second command will
start it up; you should see it pop up on the screen.&lt;/p&gt;
&lt;p&gt;At the end of this step, doing &lt;code&gt;adb devices&lt;/code&gt; in a command prompt or
console should get you some output like the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; adb devices
List of devices attached
emulator-5554   device
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&#39;re using a real device, it won&#39;t say emulator. If the output of
&lt;code&gt;adb devices&lt;/code&gt; is blank, something went wrong :(&lt;/p&gt;
&lt;h3&gt;6. Write a perl test!&lt;/h3&gt;
&lt;p&gt;At this point, you should be able to run &lt;code&gt;appium-doctor&lt;/code&gt; in a command
prompt without any complaints; if you see some, you should go back and
fix any outstanding issues. Hopefully all checks are successful; if
so, kick off the Appium server and keep reading.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; appium
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To install the Perl bindings, you can use &lt;code&gt;CPAN&lt;/code&gt; or &lt;code&gt;cpanm&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; cpanm Appium
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With your emulator or device connected (verify via &lt;code&gt;adb devices&lt;/code&gt;) and
Appium server running (verify via &lt;code&gt;wget localhost:4723/wd/hub/status&lt;/code&gt;), the following script should get you
started after you fill in the path to your apk.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use strict;
use warnings;
use Appium;
use Test::More;

my $path_to_apk = &#39;&#39;;
my %caps = (
    app =&amp;gt; $path_to_apk,
    deviceName =&amp;gt; &#39;Android Emulator&#39;,
    platformName =&amp;gt; &#39;Android&#39;,
    platformVersion =&amp;gt; &#39;5.0.1&#39;,
);

my $appium = Appium-&amp;gt;new(caps =&amp;gt; { %caps });
ok($appium, &#39;We have an Appium driver available!&#39;);
$appium-&amp;gt;quit;

done_testing;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, it&#39;s up to you to write your tests! :) If anything
doesn&#39;t work, check the Appium log for warnings and errors, especially
about &lt;code&gt;ANDROID_HOME&lt;/code&gt; or any of the environment variables we set up
previously.&lt;/p&gt;
&lt;p&gt;Feel free to reach out with any issues; if you come across bugs in the Perl client bindings, its &lt;a href=&quot;https://github.com/appium/perl-client&quot;&gt;Github repository&lt;/a&gt; is waiting for its first bug report! Good luck!&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Using Emacs for daily reminders to write in my ~/diary</title>
    <link href="https://blog.danielgempesaw.com/post/diary-management/"/>
    <updated>2015-02-01T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/diary-management/</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/gempesaw/writing/master/published/diary-management.png&quot; alt=&quot;diary&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I worked remotely for a year or so and I took it upon myself to figure
out ways to improve my communication with HQ. One of the useful things
I found was &lt;a href=&quot;https://dria.wordpress.com/2010/02/25/on-11s/&quot;&gt;sending a weekly email summary&lt;/a&gt; to my manager, as
a touch point for them to be able to see my week to week
progress&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/diary-management/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. I soon realized that I had no memory at all for
recalling what I did the previous day, much less for a whole week, so
I began looking into what options Emacs offered for daily diary
note-keeping kind of things&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/diary-management/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;Google told me that I should to use the &lt;code&gt;calendar&lt;/code&gt; and &lt;code&gt;diary&lt;/code&gt;
functions to make my notes. &lt;code&gt;M-x calendar&lt;/code&gt; brings up a three month
calendar view, and &lt;code&gt;M-x diary&lt;/code&gt; opens the &lt;code&gt;~/diary&lt;/code&gt; file on your
computer in a special &lt;code&gt;diary-mode&lt;/code&gt;. Each line in the diary file starts
with the date in whatever format you want (&lt;code&gt;&#39;iso&lt;/code&gt;), and then you can
put notes for that day. When cursoring about the calendar, pressing
&lt;kbd&gt;i d&lt;/kbd&gt; opens up the diary with a new entry for that date ready
to accept some text.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; dg-diary.el
(require &#39;calendar)
(calendar-set-date-style &#39;iso)


;; ~/diary
2015-01-17 some notes for the day!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The diary and the calendar have a pretty tight integration that I&#39;m
still trying to learn! Of course, the biggest issue was remembering to
actually remember to write in my diary in the first place. For a
while, I had a Google Now reminder, but a daily reminder ended up
clogging the entire Inbox interface, as they really call reminders to
the forefront there. So, I tried to figure out how to set a daily
reminder in Emacs and came up with the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun remind-me-daily (fn time)
  (when (and (boundp &#39;daily-reminder)
             (timerp daily-reminder))
    (cancel-timer daily-reminder))
  (let ((daily (* 60 60 24)))
    (setq daily-reminder
          (run-at-time time daily &#39;funcall fn))))

(remind-me-daily &#39;toggle-diary-windows &amp;quot;4:30pm&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Basically, &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/elisp/Timers.html&quot;&gt;&lt;code&gt;run-at-time&lt;/code&gt;&lt;/a&gt; is doing all the work here. There&#39;s a
little work to make sure I&#39;m not setting tons of reminders by
automatically clearing the existing &lt;code&gt;daily reminder&lt;/code&gt;. Otherwise, we
just handle the number of seconds in a day and set our function to be
called daily.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;toggle-diary-windows&lt;/code&gt; is a function that stores my current window
configuration before bringing up the calendar and the diary, putting
my cursor at the correct spot in the diary file to make notes for the
current day.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun toggle-diary-windows ()
  (interactive)
  (toggle-app-and-home
   &amp;quot;Calendar&amp;quot;
   (lambda ()
     (window-configuration-to-register 6245)
     (calendar)
     (delete-other-windows)
     (text-scale-adjust 3)
     (execute-kbd-macro [?m ?. ?i ?d])
     (text-scale-adjust 0)
     (text-scale-adjust 2)
     (recenter-top-bottom))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;toggle-app-and-home&lt;/code&gt; is a custom function that checks whether any of
my open buffers match its first argument and decides if it should show
me the app (Calendar, in this case) or my previous window
configuration (&amp;quot;home&amp;quot;). A little involved, but probably easier to
understand in person. Basically, I&#39;ve got a couple different apps that
I use in Emacs that are completely separate from authoring code: diary
things, mu4e for my mail, jabber for chat, etc. At any point, it&#39;s
useful to be able to toggle my whole window configuration to and from
setups that allow me to do those tasks.&lt;/p&gt;
&lt;p&gt;After penning quick summary of the day&#39;s work, I use my diary
keybinding to toggle back to my previous window configuration and
continue on my way. At the end of the week, I&#39;ve got a few sentence
fragments for each day and an easy way to write the Accomplishments,
Blockers, and Next Week sections of my weekly summary.&lt;/p&gt;
&lt;p&gt;If you liked this post, you may also be interested in how
&lt;a href=&quot;http://sachachua.com/blog/2014/11/using-org-mode-keep-process-journal/&quot;&gt;Sacha Chua is doing her process journaling!&lt;/a&gt;! My complete file for
customizing my diary interactions is &lt;a href=&quot;https://github.com/gempesaw/dotemacs/blob/emacs/dg-elisp/dg-diary.el&quot;&gt;on Github&lt;/a&gt;.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This was in addition to daily standup check-ins and weekly 1 on 1s and so on - I wanted to do &lt;em&gt;more&lt;/em&gt; communication on top of all that. &lt;a href=&quot;https://blog.danielgempesaw.com/post/diary-management/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This is unfortunately not an org mode post, as that&#39;s one of the Emacs things that I have actually managed not to do so far. &lt;a href=&quot;https://blog.danielgempesaw.com/post/diary-management/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Running perl&#39;s Test::More tests in parallel on OS X</title>
    <link href="https://blog.danielgempesaw.com/post/osx-parallel-perl/"/>
    <updated>2015-02-21T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/osx-parallel-perl/</id>
    <content type="html">&lt;p&gt;Integration tests and e2e tests are very useful when developing apps,
but unlike unit tests it&#39;s harder to keep them fast and snappy. In my
case, I have to spin up multiple webdriver instances to test my
webdriver automation framework as part of the e2e process. Although
webdriver is now significantly faster than it used to be, running
twenty tests in parallel is an order of magnitude quicker than running
them all in series. I&#39;ve started using &lt;a href=&quot;https://metacpan.org/pod/Test::ParallelSubtest&quot;&gt;Test::ParallelSubtest&lt;/a&gt; to
achieve this speedup, due to trouble installing Test::Parallel on OS
X.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;Previously, &lt;a href=&quot;https://metacpan.org/pod/Test::Parallel&quot;&gt;Test::Parallel&lt;/a&gt; was my perl package of choice for
dropping into a normal &lt;a href=&quot;https://metacpan.org/pod/Test::More&quot;&gt;Test::More&lt;/a&gt; file and getting an immediate
speed up. But at some point a few OS X versions ago, I tried
reinstalling Test::Parallel to no
avail. &lt;a href=&quot;https://metacpan.org/pod/Sys::Statistics::Linux::MemStats&quot;&gt;Sys::Statistics::Linux::MemStats&lt;/a&gt; is failing its
configuration because OS X/darwin isn&#39;t the intended platform.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bash-3.2$ cpanm -nf Test::Parallel
--&amp;gt; Working on Test::Parallel
Fetching http://www.cpan.org/authors/id/A/AT/ATOOMIC/Test-Parallel-0.20.tar.gz ... OK
Configuring Test-Parallel-0.20 ... OK
==&amp;gt; Found dependencies: Sys::Statistics::Linux::MemStats
--&amp;gt; Working on Sys::Statistics::Linux::MemStats
Fetching http://www.cpan.org/authors/id/B/BL/BLOONIX/Sys-Statistics-Linux-0.66.tar.gz ... OK
Configuring Sys-Statistics-Linux-0.66 ... N/A
! Configure failed for Sys-Statistics-Linux-0.66. See /Users/dgempesaw/.cpanm/work/1424475457.49669/build.log for details.
! Installing the dependencies failed: Module &#39;Sys::Statistics::Linux::MemStats&#39; is not installed
! Bailing out the installation for Test-Parallel-0.20.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and in the build log&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Configuring Sys-Statistics-Linux-0.66
Running Build.PL
OS unsupported! Sorry, but this system seems not to be a linux system! at Build.PL line 5.
Running Makefile.PL
OS unsupported! Sorry, but this system seems not to be a linux system! at Makefile.PL line 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But, like previously mentioned, Test::ParallelSubtest installs just
fine. It does take a little change to the test code itself, as it
requires you to organize the tests in subtests.&lt;/p&gt;
&lt;p&gt;One small issue I ran into was keeping my tiny webserver alive for the
entire duration of the test. I have to start up the webserver, wait
for it to be ready to accept connections, and then I can kick off the
tests that hit the server. Since the server I was using automatically
cleans itself up during destruction, I got bit when the main process
was finishing rather quickly - all it needed to do was put the tests
together, and then quit. Meanwhile, the background subtests had barely
gotten started.&lt;/p&gt;
&lt;p&gt;Luckily, &lt;code&gt;bg_subtest_wait()&lt;/code&gt; solves this problem for me. The docs do
say that it gets called implicitly along with &lt;code&gt;done_testing&lt;/code&gt;, but it
wasn&#39;t working for me. Manually invoking it at the end of the script
kept the parent webserver process alive while all of its kids played
in its server sandbox.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Imitating live reload in Emacs for Perl (or any) project :)</title>
    <link href="https://blog.danielgempesaw.com/post/auto-recompile/"/>
    <updated>2015-03-18T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/auto-recompile/</id>
    <content type="html">&lt;p&gt;One of my favorite parts about my frontend JS workflow is using Live
Reload with Grunt/Gulp. Saving a few keystrokes a couple times a
minute is pretty great, especially if I can stay on the home
keys. Grunt and Gulp have a task that watches the files in your
project and then you kick can off certain tasks when they change, like
refreshing your display and re-running all the unit tests. In Scala,
you can get a similar thing by invoking your &lt;code&gt;sbt&lt;/code&gt; command prefixed
with a &lt;code&gt;~&lt;/code&gt;, but I didn&#39;t have anything for my Perl projects (not to
mention a general solution!).&lt;/p&gt;
&lt;p&gt;At first, I looked for a similar tool that would watch files for
changes and let me hook into that action. I found
&lt;a href=&quot;https://metacpan.org/pod/App::Prove::Watch&quot;&gt;App::Prove::Watch&lt;/a&gt; which
was a Perl-only solution. It worked swimmingly after a quick PR, but
it only solved the problem for Perl projects. It wasn&#39;t until a few
days later that I realized I could leverage Emacs to get a reasonably
general solution, only depending on use of the &lt;code&gt;*compilation*&lt;/code&gt; buffer
(no idea why it didn&#39;t occur to me earlier!).&lt;/p&gt;
&lt;p&gt;Of course, Emacs knows exactly when my files change, as we always
eventually invoke &lt;code&gt;(save-buffer)&lt;/code&gt; - even if it&#39;s advised with with
whitespace cleanup, or if it&#39;s invoked via some sort of
autosave. Instead of watching files on disk for changes, we can just
use Emacs to have the &lt;code&gt;(save-command)&lt;/code&gt; trigger our tasks - aka
re-compiling the &lt;code&gt;*compilation*&lt;/code&gt; buffer.&lt;/p&gt;
&lt;p&gt;I used a global variable &lt;code&gt;ar-auto-recompile&lt;/code&gt; to turn autocompilation
on and off, and made a function to handle the toggling for me:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq ar-auto-recompile nil)
(defun ar-auto-re-compile ()
  (interactive)
  (setq ar-auto-recompile (not ar-auto-recompile))
  (message (format &amp;quot;Auto recompile is now %s&amp;quot;
                   (if ar-auto-recompile &amp;quot;ON&amp;quot; &amp;quot;OFF&amp;quot;))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It just toggles the variable and messages us about it. Next, our
advice to save-buffer should check whether the user wants
auto-recompilation. I also decided I only wanted it to re-compile if
the &lt;code&gt;*compilation*&lt;/code&gt; buffer was in a visible window, which
&lt;code&gt;(get-buffer-window)&lt;/code&gt; happily tells us.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defadvice save-buffer (after ar-auto-recompile activate)
  (when (and ar-auto-recompile
             (get-buffer-window &amp;quot;*compilation*&amp;quot;))
    (set-buffer compilation-last-buffer)
    (revert-buffer t t)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This solution isn&#39;t &lt;em&gt;quite&lt;/em&gt; the same as the watch behavior of the
other tools, as they smartly only respond to changes in files in their
own project. When turned on, this would blindly recompile any time a
buffer is saved and the &lt;code&gt;*compilation*&lt;/code&gt; buffer is open. But, I don&#39;t
really mind - a few extra compilations probably won&#39;t hurt anything
unless the compilation wasn&#39;t safe to repeat in the first place.&lt;/p&gt;
&lt;p&gt;So, my workflow is now to open up my test file, toggle on the
recompilation with &lt;code&gt;(ar-auto-re-compile)&lt;/code&gt;, run a test to bring up the
&lt;code&gt;*compilation*&lt;/code&gt; buffer. I keep that buffer visible and then do edits
and such as usual, &lt;a href=&quot;https://github.com/gempesaw/dotemacs/blob/6ca8a3995d558ac924e576bd60c516dbd1c450e2/dg-elisp/dg-kbd.el#L135-L140&quot;&gt;saving with &lt;code&gt;M-s&lt;/code&gt;&lt;/a&gt;, which automatically
re-runs the test. And, if I need a more complicated compilation
command, it&#39;s just a &lt;code&gt;C-u M-x compile&lt;/code&gt; away, and then that can get
repeated for me. As an extra bonus, this works perfectly with
&lt;a href=&quot;https://github.com/bbatsov/projectile&quot;&gt;projectile&lt;/a&gt;&#39;s compilation and test running commands (by default on
&lt;kbd&gt;C-c p c&lt;/kbd&gt; and &lt;kbd&gt;C-c p P&lt;/kbd&gt;), as they utilize the
&lt;code&gt;*compilation*&lt;/code&gt; buffer as well. I also made a key-chord to switch the
current buffer over to the compilation one, as I often accidentally
close it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(key-chord-define-global &amp;quot;vv&amp;quot; (lambda () (interactive)
                                (switch-to-buffer &amp;quot;*compilation*&amp;quot;)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, if you don&#39;t want to use advice, it&#39;s &lt;a href=&quot;https://github.com/gempesaw/dotemacs/blob/8e7cb17e72339069d5e318fd7eb44d4718faa36c/dg-elisp/dg-defun.el#L461-L466&quot;&gt;simple enough&lt;/a&gt; to
use a wrapper around &lt;code&gt;(save-buffer)&lt;/code&gt; and update your save keybinding
to use your own function. And as usual, the whole snippet is in my
github &lt;a href=&quot;https://github.com/gempesaw/dotemacs/blob/6ca8a3995d558ac924e576bd60c516dbd1c450e2/dg-elisp/dg-defun.el#L459-L470&quot;&gt;somewhere&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Selenium::Remote::Driver@0.25: now with slightly less JRE</title>
    <link href="https://blog.danielgempesaw.com/post/srd-no-jre/"/>
    <updated>2015-04-20T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/srd-no-jre/</id>
    <content type="html">&lt;p&gt;We&#39;ve just released version 0.25 of Selenium::Remote::Driver to the
various CPANs. The big push this time around was to get around our
hard dependency on the JRE. Previously, the Perl bindings demanded a
standalone selenium server be operating on the browser&#39;s machine. So,
if you wanted to run tests on your own box, you&#39;d need the Java
Runtime Environment installed, as the selenium-standalone-server is a
&lt;code&gt;.jar&lt;/code&gt; and needs the JRE to execute. However, as &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver/pull/189&quot;&gt;akafred&lt;/a&gt; pointed
out, this is a prohibitive constraint (perhaps especially so for Perl
programmers?).&lt;/p&gt;
&lt;p&gt;When I first started out working with Webdriver years ago, I only used
the standalone server and for a while I thought there was no other way
to run the tests. Eventually, when various webdrivers began replacing
Selenium RC, I found out that it was possible to &amp;quot;talk&amp;quot; directly to
them with the same exact API as the standalone server, but I never
connected that with the ability to avoid needing the standalone server
and the JRE!&lt;/p&gt;
&lt;p&gt;Anyway, thanks to some long-awaited prodding, Perl can now run
&lt;a href=&quot;https://metacpan.org/pod/Selenium::Firefox&quot;&gt;Firefox&lt;/a&gt;, &lt;a href=&quot;https://metacpan.org/pod/Selenium::Chrome&quot;&gt;Chrome&lt;/a&gt;, and &lt;a href=&quot;https://metacpan.org/pod/Selenium::PhantomJS&quot;&gt;PhantomJS&lt;/a&gt; without the JRE! What follows are
some implementation details, and simple usage examples. :)&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;h3&gt;usage&lt;/h3&gt;
&lt;p&gt;Hopefully the usage is pretty straightforward - instead of
constructing a &lt;code&gt;Selenium::Remote::Driver&lt;/code&gt; instance, use the
constructor for the browser of your choice instead. Just like the
Selenium standalone server, Firefox will work out of the box, as long
as you have Firefox installed locally on your machine in the default
location:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my $firefox = Selenium::Firefox-&amp;gt;new;
$firefox-&amp;gt;get(&#39;http://www.mozilla.org&#39;);

# &amp;quot;We’re building a better Internet — Mozilla&amp;quot;
print $firefox-&amp;gt;get_title;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The usage is exactly analogous for the ::Chrome and ::PhantomJS
classes, except you need to have the browser installed along with its
associated webdriver. For PhantomJS, GhostDriver is automatically
bundled for all recent versions, but for Chrome, you&#39;ll need to
&lt;a href=&quot;https://sites.google.com/a/chromium.org/chromedriver/downloads&quot;&gt;download the Chromedriver separately&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If your driver executables are not in your $PATH, or you&#39;d like to
specify a certain one, the constructors take a &lt;code&gt;binary&lt;/code&gt; option that
lets you tell us what executable to start. You can also specify a
&lt;code&gt;binary_port&lt;/code&gt; if there&#39;s a specific port that you&#39;d like the webdriver
server to bind to.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my $firefox = Selenium::Firefox-&amp;gt;new(
    binary =&amp;gt; &#39;/custom/path/to/firefox-bin&#39;,
    binary_port =&amp;gt; 65432
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As expected, usage is analogous for the other two classes.&lt;/p&gt;
&lt;p&gt;As a last note, we skipped creation of Selenium::InternetExplorer
hoping that &lt;a href=&quot;https://www.google.com/search?q=yagni&quot;&gt;YAGNI&lt;/a&gt;, but if that&#39;s the browser that floats your boat,
we can definitely throw a class together for the next release. Let us
know in our &lt;a href=&quot;https://groups.google.com/forum/#!forum/selenium-remote-driver&quot;&gt;Google group&lt;/a&gt;, or in the &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver/issues&quot;&gt;Github issues&lt;/a&gt;!&lt;/p&gt;
&lt;h3&gt;implementation&lt;/h3&gt;
&lt;p&gt;The implementation is ideally pretty straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Find the binary webdriver&lt;/li&gt;
&lt;li&gt;Figure out what arguments to pass it to make it mimic a standalone
server&lt;/li&gt;
&lt;li&gt;Start it on the right port&lt;/li&gt;
&lt;li&gt;Afterwards, clean it up so we don&#39;t orphan processes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first step is easy - just check the &lt;code&gt;$PATH&lt;/code&gt;/&lt;code&gt;%PATH%&lt;/code&gt; - exceeept
for Firefox, where it&#39;s apparenty quite complicated. Different
operating systems install it in multiple distinctly different places,
and if different versions of Firefox are named differently - basically
it&#39;s seems like a big headache, and I mostly threw my hands up if the
Firefox binary wasn&#39;t in the first specific default location. There&#39;s
also a bit of extra complication involved to let the user choose their
own path, and validating it for them afterwards.&lt;/p&gt;
&lt;p&gt;Passing the arguments is more or less straightforward as well -
exceeept for Firefox, which doesn&#39;t take arguments, as the webdriver
for Firefox is actually just a Firefox extension. Luckily, we
previously implemented a Firefox::Profile class, so we just use the
newly renamed &lt;a href=&quot;https://metacpan.org/pod/Selenium::Firefox::Profile&quot;&gt;Selenium::Firefox::Profile&lt;/a&gt; to create a profile with
the extension loaded. We actually now bundle the &lt;code&gt;webdriver.xpi&lt;/code&gt;
extension from the 2.45.0 version of Selenium in our release, and each
time a new Selenium is released, we&#39;ll have to do a mirror release of
our bindings with the updated extension. The other webdriver language
bindings also start up Firefox with a few pre-compiled &lt;code&gt;.so&lt;/code&gt; files for
solving focus errors that I was also too lazy to do.&lt;/p&gt;
&lt;p&gt;Finding an open port is simple enough, and we got to re-use
Selenium::Waiter&#39;s &lt;a href=&quot;https://metacpan.org/pod/Selenium::Waiter#wait_until&quot;&gt;wait_until&lt;/a&gt; in a few places.  And, starting the
webdriver up is usually easy, although at first I was a bit unfamiliar
using &lt;code&gt;system&lt;/code&gt; to start up an asynchronous process across different
platforms (namely Windows...).&lt;/p&gt;
&lt;p&gt;Finally, cleaning up the process we started is straightforward on OS X
and Linux, as I &lt;em&gt;think&lt;/em&gt; it just cleans itself up when the Perl script
ends. At least, that&#39;s what some superficial tests seemed to prove - I
didn&#39;t see anything in &lt;code&gt;ps aux&lt;/code&gt; after the test was over, and I
couldn&#39;t open sockets to the server port afterwards. But, on Windows,
the task stays open and we need to kill it by string-matching the
title of the process. It ended up being a bit of a mess!&lt;/p&gt;
&lt;p&gt;We went through a bunch of attempts &amp;amp; refactors at organizing the
functionality and ended up at something that&#39;s decently organized -
the &lt;a href=&quot;https://metacpan.org/pod/Selenium::CanStartBinary&quot;&gt;Selenium::CanStartBinary&lt;/a&gt; role implements most of the common work
between the different classes. Since Firefox is special, it gets a few
extra classes of its own. Meanwhile, each class holds its own
arguments, default binary name, and default binary port.&lt;/p&gt;
&lt;h3&gt;conclusion&lt;/h3&gt;
&lt;p&gt;For a first pass, I think the functionality works pretty decently - as
usual, I&#39;ve been using it locally for a month or two now on OS X with
no major issues, but I&#39;m sure I missed a few bugs. If you run across
any bugs, definitely &lt;a href=&quot;https://github.com/gempesaw/Selenium-Remote-Driver/issues&quot;&gt;let us know&lt;/a&gt; or even fix them for us, since I
bet you can do it better than me! :D Cheers...&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Waiting for a page to load in Selenium::Remote::Driver with Selenium::Waiter</title>
    <link href="https://blog.danielgempesaw.com/post/webdriver-ajax/"/>
    <updated>2015-04-21T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/webdriver-ajax/</id>
    <content type="html">&lt;p&gt;One of the first problems we come up against when trying to use
Webdriver to automate a web application is handling the asynchronicity
of loading a web page. For the test to be useful at all, it needs to
be as fast and reliable as possible, or else there&#39;s a very real risk
that devs and QA engineers will give up running the tests. The problem
is that making the test run faster can sacrifice reliability if the
async javascript isn&#39;t properly handled.&lt;/p&gt;
&lt;p&gt;Instead of trying to figure out when a page loads, we should take a
hint from what an actual user does. Users don&#39;t care when a page is
done loading - they just wait for the exact element they want to
interact with, and then start clicking/inputting right away. We can
mimic that behavior with &lt;code&gt;wait_until&lt;/code&gt;, a utility function exported by
&lt;a href=&quot;https://metacpan.org/pod/Selenium::Waiter&quot;&gt;Selenium::Waiter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;The general case of determining when a page is done loading is a
variation of the &lt;a href=&quot;https://groups.google.com/forum/#!msg/webdriver/7K2QWGVNCYo/PngL9YDXDLgJ&quot;&gt;halting problem&lt;/a&gt;. When you ask Webdriver to load a
page, it does block briefly while it runs through its own algorithms
to figure out when the page is done loading. But, it being the halting
problem and all, they obviously can&#39;t solve it for all the cases.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my $d = Selenium::Firefox-&amp;gt;new;
$d-&amp;gt;get($tricky_slow_loading_page);

# this will throw when the element isn&#39;t present
my $text = $d-&amp;gt;find_element_by_css(&#39;div&#39;)-&amp;gt;get_text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem with putting in a sleep before attempting to find the
element is that it will usually work, but maybe one time in twenty it
will fail, and it won&#39;t be immediately apparent why it failed,
especially months down the line. What we want is a method that
reliably and consistently waits exactly until the element in question
is ready. We don&#39;t want to wait any longer than necessary, so a long
explicit sleep is out, but we don&#39;t want to go early, or else we&#39;ll
get exceptions all over the place. &lt;code&gt;wait_until&lt;/code&gt; lets us get pretty
close to this ideal behavior:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# wait_until will also catch dies and croaks
my $elem = wait_until { $d-&amp;gt;find_element_by_css(&#39;div&#39;) };

if ($elem) {
    say &#39;Text: &#39; . $elem-&amp;gt;get_text;
}
else {
    say &#39;We waited thirty seconds without finding css=div&#39;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;wait_until&lt;/code&gt; takes a block and an optional hashref of arguments. It
wraps the block execution in a &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; from &lt;a href=&quot;https://metacpan.org/pod/Try::Tiny&quot;&gt;Try::Tiny&lt;/a&gt;. By
&lt;a href=&quot;https://metacpan.org/pod/Selenium::Waiter#Timeouts-and-Intervals&quot;&gt;default&lt;/a&gt;, it will run for thirty seconds, sleeping one second
between iterations. If at any point the block returns something true,
it immediately returns that value as its result. Note that
&lt;code&gt;wait_until&lt;/code&gt; expects a block that is generally NON-blocking, so if
webdriver has an associated timeout, like the implicit wait timeout
for finding elements, you&#39;ll want to set it to a second or less if
you&#39;ve increased it. The exact number of iterations will depend on how
long the block takes to execute.&lt;/p&gt;
&lt;p&gt;To be clear, if your &lt;code&gt;implicit_wait_time&lt;/code&gt; is 31 seconds, and you put a
&lt;code&gt;find_element&lt;/code&gt; inside a &lt;code&gt;wait_until&lt;/code&gt;, we&#39;ll run it once, Webdriver
itself will block for 31 seconds, and by the time we get control back
in our &lt;code&gt;wait_until&lt;/code&gt; block, the timeout will have expired, and we&#39;ll
return control to your script after executing exactly one
&lt;code&gt;find_element&lt;/code&gt;. (This may be the behavior you desire - but just make
sure you&#39;re doing it on purpose!)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my $d = Selenium::Firefox-&amp;gt;new;
$d-&amp;gt;set_implicit_wait_timeout(30000);
my $one_iteration = wait_until { $d-&amp;gt;find_element(&#39;this is blocking&#39;, &#39;css&#39;) };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also use &lt;code&gt;wait_until&lt;/code&gt; to have your test block until the
element is visible, or some other boolean property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my $visible_elem = wait_until {
    $d-&amp;gt;find_element_by_id(&#39;eventually-visible&#39;)-&amp;gt;is_displayed
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, as mentioned, &lt;code&gt;wait_until&lt;/code&gt; wraps everything in a &lt;code&gt;try&lt;/code&gt;, so if
the BLOCK you passed in does die, it&#39;ll get demoted to a warn. This
means you MUST check the return value of &lt;code&gt;wait_until&lt;/code&gt;. Normally,
Selenium::Remote::Driver will croak when we run into something we
don&#39;t understand &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/webdriver-ajax/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. Since we&#39;re only warning, it&#39;s possible you may
get into some weird territory if you make assumptions about the return
value. Honestly, I&#39;m still not sure about this behavior - perhaps it
makes sense for &lt;code&gt;wait_until&lt;/code&gt; to die if the expected value never
returns true.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Although it can be frustrating, it&#39;s helpful for the
program to die as close as possible to the source of the crash. Also,
from the test&#39;s point of view, we have no idea what to do if we get an
unexpected exception. &lt;a href=&quot;https://blog.danielgempesaw.com/post/webdriver-ajax/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry>
    <title>The Abuse and Misuse of Test Automation – Interview with Alan Page - Fog Creek Blog</title>
    <link href="https://blog.danielgempesaw.com/post/automation-improvement-musings/"/>
    <updated>2015-05-28T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/automation-improvement-musings/</id>
    <content type="html">&lt;p&gt;I&#39;ve been thinking recently that one of the big problems we&#39;re having
with automation at work is caused by previous-me of years past
encouraging the idea of &amp;quot;oh doing automation is easy, look, gherkin is
close to readable English, that makes it simple!&amp;quot; However, we&#39;re a
couple years in to our (perl!) Gherkin &amp;amp; Selenium based automation
framework and we&#39;re running into a lot of pain points.&lt;/p&gt;
&lt;p&gt;What I&#39;ve realized, perhaps unfortunately a few years too late, is
that E2E automation is very complicated to do well &amp;amp; usefully. It
takes a deep knowledge of multiple working &amp;amp; changing systems (app
under test, the automation framework, and everything in between) to do
it effectively. Bringing in people who aren&#39;t familiar with either
(through no fault of their own) and neglecting to train them properly
is a good way to get a brittle automation suite.&lt;/p&gt;
&lt;p&gt;I think that&#39;s one of the big problems I should try to solve this
year. In the linked podcast episode, Alan Page espouses some pretty
similar ideas about how to do automated testing well, pointing out
that having junior developers write (e2e) tests often leads to
failure, where as more senior developers who are comfortable with the
complexity of the entire system are actually able to successfully
write useful tests:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Another reason, and I’m sorry to say this, is often we have is this,
really scary when you think about it, to me at least… We often have
our most junior developers, our brand new testers who are learning
to code or maybe some company that’s where you start people. You get
these very junior people without a lot of design knowledge for
software and a lot of experience. You tell them write this GUI
automation. You have junior people doing something that’s much, much
harder than most people admit and it just makes it more prone for
failure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I think when you get success is you have developers who know what
they’re doing, more senior developers. It doesn’t have to be your
top developer but you have experienced people who know what they’re
doing. They understand design and they’re very careful about writing
tests that they can trust to show product status. That’s the case
that GUI automation can actually work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He&#39;s also pretty strict about flaky tests, which I unfortunately don&#39;t
have the luxury to get too hung about. Since I&#39;m the main (aka only)
developer on our automation framework, supporting a growing group of
QA engineers, I don&#39;t have time to dig into every flaky issue. Hm,
but, putting it on paper like that, it actually becomes pretty
apparent to me that I do need to spend some time digging into flaky
issues - otherwise I&#39;ll get drowned in flaky bugs that negatively
impact our view of the framework. That&#39;s already happening, and we do
need to actively combat it.&lt;/p&gt;
&lt;p&gt;Another question that we&#39;re always curious about is what to
automate. Although they&#39;re not wrong with their &amp;quot;automate all the
tests that should be automated,&amp;quot; and &amp;quot;automate when you&#39;re bored,&amp;quot;
heuristics, I find it a bit lacking to translate that into specific
situations that I can tell our team about.&lt;/p&gt;
&lt;p&gt;( also I like this trend of transcribing podcasts! I can read much
faster than I can listen :) )&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Bitlbee’s account xml file on os x</title>
    <link href="https://blog.danielgempesaw.com/post/bitlbee-account-file/"/>
    <updated>2015-07-29T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/bitlbee-account-file/</id>
    <content type="html">&lt;p&gt;This is primarily for me to find next time I run into this issue!
Having previously installed bitlbee on my OS X machine via
&lt;a href=&quot;http://blog.danielgempesaw.com/post/104839206054/using-sipe-through-bitlbee-in-emacs-on-os-x&quot;&gt;homebrew &amp;amp; some elbow grease&lt;/a&gt;, I made a one-off password for the
local bitlbee server I run to store my account credentials. Since I
run the bitlbee server through Emacs and like a well behaved Emacs
user, I hardly ever restart Emacs, I&#39;m sure to have forgotten my
bitlbee credentials between server restarts. At those times it&#39;s
pretty useful to be able to find the bitlbee XML file that houses my
username and encoded password. This is also useful in case I need to
change other account setting things.&lt;/p&gt;
&lt;p&gt;So, for bitlbee installed on OS X via homebrew, the account xml file
is in the following folder on my machine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/local/var/bitlbee/lib/&amp;lt;username&amp;gt;.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the bitlbee server wants the credentials like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; identify &amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  
  <entry>
    <title>My own reference for flashing new android without losing root or user data</title>
    <link href="https://blog.danielgempesaw.com/post/updating-android/"/>
    <updated>2015-08-04T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/updating-android/</id>
    <content type="html">&lt;p&gt;Humm, so my nexus 6 has a persistent notification about wanting me to
upgrade to 5.1.1. I was lazy this time and didn&#39;t bother doing it at
the end of May when the stock images came out, but my phone doesn&#39;t
know how to do it on its own since it&#39;s rooted and unencrypted and/or
it&#39;s using TWRP recovery instead of the stock recovery. I don&#39;t do
this frequently enough to remember, but too infrequently to want to
write a script for it (especially since Wug&#39;s toolkit already
exists). Anyway, here&#39;s my pretty straightforward steps to getting my
N6 to 5.1.1, generic enough to apply to any update&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/updating-android/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ol start=&quot;0&quot;&gt;
&lt;li&gt;
&lt;p&gt;start &lt;a href=&quot;https://developers.google.com/android/nexus/images?hl=en&quot;&gt;downloading whatever factory image&lt;/a&gt; that needs flashing&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;on the phone, make a backup via TWRP&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;copy the backup to a desktop, just in case of lightning strikes!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;whenever the DL finishes, unzip the &lt;code&gt;.tgz&lt;/code&gt; and go in that folder&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;in that folder unzip the &lt;code&gt;.zip&lt;/code&gt;, cuz it has &lt;code&gt;boot.img&lt;/code&gt; and &lt;code&gt;system.img&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;wire the phone to a computer (probably already done in 2)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reboot to bootloader (power off, hold vol down &amp;amp; power)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;use &lt;code&gt;fastboot&lt;/code&gt; to do some things:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; fastboot flash bootloader bootloader.img
 fastboot flash radio radio.img
 fastboot reboot-bootloader
 fastboot flash boot boot.img
 fastboot flash system system.img
 fastboot reboot-bootloader
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;head into TWRP recovery, supposedly I should wipe cache &amp;amp; Dalvik,
but I forgot and it seems fine. anyway, reboot to system and it&#39;ll
prompt about installing SU for us since we lost root (yay TWRP).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Make sure not to flash the recovery from the download since we&#39;d like
to keep TWRP, not the stock recovery. TWRP&#39;s reboot into system will
spin the &amp;quot;optimizing app M of N&amp;quot; for a while, and then it should be
gravy!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I used to go to theSiteThatShallNotBeNamed for this, but after
seeing their recent behaviors and reading the thoughts of some
industry thought leaders (heh, heh, thought leaders is a funny
concept - but here I am following their thoughts...), I figure I&#39;d
ought to make a reference for myself so I can stop giving them
traffic. &lt;a href=&quot;https://blog.danielgempesaw.com/post/updating-android/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Chromedriver and the Weak Ephemeral Diffie-Hellman Public Key</title>
    <link href="https://blog.danielgempesaw.com/post/diffie-hellman/"/>
    <updated>2015-09-04T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/diffie-hellman/</id>
    <content type="html">&lt;p&gt;As of Chrome 45, there&#39;s a new error message about a
&lt;a href=&quot;https://www.chromium.org/administrators/err_ssl_weak_server_ephemeral_dh_key&quot;&gt;weak ephemeral Diffie-Hellman public key&lt;/a&gt; that started showing up
in our webdriver &amp;amp; chromedriver proxy tests. The intent of the block
was to secure users from the &lt;a href=&quot;https://weakdh.org/&quot;&gt;LogJam vulnerability&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our testing set up at $WORK, we use &lt;a href=&quot;https://metacpan.org/pod/Browsermob::Proxy&quot;&gt;Browsermob Proxy&lt;/a&gt; to MitM
our E2E test traffic so that we can analyze the network traffic. Using
a proxy allows us to test things like Omniture &amp;amp; Google analytics, and
also enables us to simulate XSS attacks against our website.&lt;/p&gt;
&lt;p&gt;Our E2E test suite depends heavily on the proxy being allowed to MitM
the traffic, and Chrome started noticing that the DH key that our
proxy presented was insecure. This is pretty valid for Chrome to want
to block, since we are after all attacking ourselves&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/diffie-hellman/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. Luckily,
Chrome allows us to blacklist certain ciphers as an argument during
startup and after some wild googling, I arrived upon the following CLI
argument for Chrome:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--cipher-suite-blacklist=0x0039,0x0033
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;Basically, we are blacklisting the cipher suites that we don&#39;t want to
run, and this allows Browsermob::Proxy to go on its merry
man-in-the-middle-attack way. Using the &lt;a href=&quot;https://metacpan.org/pod/Selenium::Remote::Driver&quot;&gt;perl webdriver bindings&lt;/a&gt; to
start up a proxy and then chromedriver, this ends up looking like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use strict;
use warnings;
use feature qw/say/;
use Selenium::Remote::Driver;
use Browsermob::Proxy;

my $proxy = Browsermob::Proxy-&amp;gt;new(
    server_addr =&amp;gt; $server,
    server_port =&amp;gt; 8080
);

my $d = Selenium::Remote::Driver-&amp;gt;new(
    desired_capabilities =&amp;gt; {
        browserName =&amp;gt; &#39;chrome&#39;,
        proxy =&amp;gt; $proxy-&amp;gt;selenium_proxy,
        chromeOptions =&amp;gt; {
            args  =&amp;gt; [
                &#39;cipher-suite-blacklist=0x0039,0x0033&#39;
            ],
        }
    }
);

$d-&amp;gt;get(&#39;https://www.google.com&#39;);
say $d-&amp;gt;get_body;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Probably the most interesting part&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://blog.danielgempesaw.com/post/diffie-hellman/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; is the particular data
structure that &lt;code&gt;chromeOptions&lt;/code&gt; requires. The same idea will work with
any of the other webdriver language bindings as well - if you can
figure out how to pass arguments to your chromedriver via your
bindings of choice, just append the &lt;code&gt;cipher-suite-blacklist&lt;/code&gt; argment
to the list of args.&lt;/p&gt;
&lt;p&gt;Also of note - a lot of sources recommended blacklisting a longer list
of ciphers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--cipher-suite-blacklist=0x0088,0x0087,0x0039,0x0038,0x0044,0x0045,0x0066,0x0032,0x0033,0x0016,0x0013
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After little trial and error I was able to determine which particular
ciphers that I needed to blacklist, so I only chose &lt;code&gt;0x0039,0x0033&lt;/code&gt;,
but others may be necessary; YMMV! For further reading, there were a
couple very helpful links I found:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Frank Ehlis already figured out how to
&lt;a href=&quot;http://fehlis.blogspot.com/2013/12/how-to-disable-ssl-ciphers-in-google.html&quot;&gt;disable SSL ciphers in Dec 2013&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There&#39;s a chromium issue &lt;a href=&quot;https://code.google.com/p/chromium/issues/detail?id=58833&quot;&gt;listing all the ciphers&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This superuser also helpfully had the answer about
&lt;a href=&quot;http://superuser.com/a/966879/493387&quot;&gt;disabling the SSL suites&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;a href=&quot;https://cc.dcsec.uni-hannover.de/&quot;&gt;diagnostic page&lt;/a&gt; for determining which SSL cipher suites your
browser supports!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Coincidentally, the security block also to inadvertently caused
issues for people with intranet websites that aren&#39;t properly secure,
amongst other things. This has somewhat understadably ended up
&lt;a href=&quot;https://productforums.google.com/forum/#!topic/chrome/o3vZD-Mg2Ic&quot;&gt;angering plenty of internet users&lt;/a&gt;
who feel very entitled to their free browsers. &lt;a href=&quot;https://blog.danielgempesaw.com/post/diffie-hellman/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;The other &lt;em&gt;gotcha&lt;/em&gt; that I ran into while troubleshooting this
issue is that if the Browsermob proxy server was on the same machine
as the browser in question, the issue didn&#39;t manifest itself at
all. We only experienced the issue when the proxy server and the
browser were operating on different machines. &lt;a href=&quot;https://blog.danielgempesaw.com/post/diffie-hellman/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Stopping footnotes here from opening in a new tab</title>
    <link href="https://blog.danielgempesaw.com/post/tumblrs-footnotes/"/>
    <updated>2015-09-05T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/tumblrs-footnotes/</id>
    <content type="html">&lt;p&gt;Tumblr&#39;s markdown formatting mode somewhat secretly supports
footnotes. But, it seems like my settings or my theme or something
makes footnote links with the &lt;code&gt;target=&amp;quot;_blank&amp;quot;&lt;/code&gt; attribute set, which
is pretty odd. Who wants a footnote to pop them to a new tab ? And
furthermore, the return links in the footer also have the same
&lt;code&gt;target=&amp;quot;_blank&amp;quot;&lt;/code&gt;. Basically, the footnotes on this blog have been
nigh unusable, since they keep spawning new tabs all over the place.&lt;/p&gt;
&lt;p&gt;So, some quick javascript to get things sorted:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Array.prototype.slice.call(
    document.querySelectorAll( &#39;a[rel=footnote], a[rev=footnote]&#39; )
).forEach( function (node) { node.target = &#39;&#39;; } );
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;find the impacted nodes with &lt;code&gt;document.querySelectorAll&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;convert that NodeList to an Array&lt;/li&gt;
&lt;li&gt;clear the &lt;code&gt;target&lt;/code&gt; on each node&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Honestly, I&#39;m not entirely sure why this happens on this blog -
&lt;a href=&quot;http://www.marco.org/tagged-bestof#fnref:pcclmCSDW1&quot;&gt;other&lt;/a&gt; &lt;a href=&quot;http://onethingwell.org/post/1680780219/tumblr-markdown#fnref:p1680780219-1&quot;&gt;people&lt;/a&gt; &lt;a href=&quot;http://nancym.tumblr.com/post/59594358553/links-footnotes-and-abbreviations-in-markdown#fnref:p59594358553-markdown&quot;&gt;don&#39;t&lt;/a&gt; seem to have the issue. In case anyone else
is seeing this behavior on their tumblr footnotes, just add the code
above to a &lt;code&gt;&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; tag at the bottom of the HTML for the
page :)&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Fixing a laggy compilation buffer</title>
    <link href="https://blog.danielgempesaw.com/post/maven-compilation-error-regex/"/>
    <updated>2015-09-25T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/maven-compilation-error-regex/</id>
    <content type="html">&lt;p&gt;I use Emacs compilation mode to execute most of my scripts - it has a
lot of nice built in things, including error highlighting with
automatic navigation. But, I&#39;ve noticed that with really long lines,
the compliation buffer gets so slow that it makes Emacs unresponsive
to input, and I end up having to frantically &lt;kbd&gt;Ctrl+G&lt;/kbd&gt; and
hope that I can stop the compilation before I lose Emacs and have to
Force Quit it.&lt;/p&gt;
&lt;p&gt;One particular instance is when I&#39;m using Webdriver to take
screenshots - Webdriver takes the screenshot (in binary format?) and
base64 encodes it, so that means I&#39;ve got a very long string to work
with, and if I accidentally print it out, Emacs gets quite overwhelmed.&lt;/p&gt;
&lt;p&gt;As usual, I&#39;m not the only one to run into this issue, and there&#39;s a
&lt;a href=&quot;http://comments.gmane.org/gmane.emacs.bugs/28783&quot;&gt;gmane.emacs.bugs thread&lt;/a&gt; (&lt;a href=&quot;http://webcache.googleusercontent.com/search?q=cache%3Acomments.gmane.org%2Fgmane.emacs.bugs%2F28783&amp;amp;oq=cache%3Acomments.gmane.org%2Fgmane.emacs.bugs%2F28783&amp;amp;aqs=chrome..69i57j69i58.734j0j4&amp;amp;sourceid=chrome&amp;amp;es_sm=91&amp;amp;ie=UTF-8&quot;&gt;cache&lt;/a&gt;)
about disabling the Maven regular expression in the
&lt;code&gt;compilation-error-mode-alist&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(setq compilation-error-regexp-alist
      (delete &#39;maven compilation-error-regexp-alist))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I had thought it had to do with colorization, or perhaps the rainbow
delimiters that I use, but &lt;a href=&quot;https://github.com/gempesaw/dotemacs/commit/a8bf86d3c4148fcbf630b5f2a1c8ae6c9d981237&quot;&gt;that simple line&lt;/a&gt; of disabling the
Maven regex made a huge difference. Hooray for correcting
long-standing annoyances.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Executing promises serially with [].reduce</title>
    <link href="https://blog.danielgempesaw.com/post/serial-promises/"/>
    <updated>2017-03-03T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/serial-promises/</id>
    <content type="html">&lt;p&gt;Recently at $WORK, we were writing a data migration script in node
that needed to make a couple hundred requests. The first attempt was
just to wrap everything up in a Promise.all:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const rp = require(&#39;request-promise-native&#39;);
const urls = [
    &#39;url1&#39;,
    &#39;url2&#39;,
    // ...,
    &#39;url300&#39;
];

Promise.all(urls.map((url) =&amp;gt; rp.get(url)
                     .then(sendRelatedRequests)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;p&gt;However, the internal server we were talking to wasn&#39;t able to handle
all of the requests concurrently, and since the subsequent logic would
also send a few more requests of its own, we ended up taking down the
server because we were spawning all the promises at the same time,
and since Promises execute once they&#39;re made, that means all the
requests were starting off at roughly the same time.&lt;/p&gt;
&lt;p&gt;So, for our second pass, we decided we wanted to only send one request
at a time, lining up all of our requests serially, since we know that
when the server finishes responding to our nth request, it should be
ready to handle the (n+1)th request. One way to accomplish this is
with a big long chain of &lt;code&gt;.then&lt;/code&gt;s, as by the time we&#39;re in a &lt;code&gt;.then&lt;/code&gt;, we&#39;re guaranteed that its preceding promise is completed. And one way we can construct that chain is with a reduce:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;urls.reduce(
    (acc, url) =&amp;gt; acc.then(() =&amp;gt; rp.get(url).then(sendRelatedRequests)),
    Promise.resolve()
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;[].reduce&lt;/code&gt; takes two arguments: the reducing function, and the
initial value. We need to start with a Promise, because our reduce
function assumes that the accumulator &lt;code&gt;acc&lt;/code&gt; has a &lt;code&gt;.then&lt;/code&gt; on it.&lt;/p&gt;
&lt;p&gt;For the reducing function, we have an accumular, and a url. Each time,
&lt;code&gt;acc&lt;/code&gt; is the existing serial chain of promises, and we add another
&lt;code&gt;.then&lt;/code&gt; on to it. The important part is that the function in the
&lt;code&gt;.then&lt;/code&gt; handler is &lt;em&gt;not&lt;/em&gt; immediately creating the promise, because
that would mean the request is immediately sent. Instead, passing the
function expression means the Promise isn&#39;t created until the &lt;code&gt;.then&lt;/code&gt;
handler is invoked, and since the &lt;code&gt;.then&lt;/code&gt; handler is invoked until its
preceding Promise is complete, we get our serial behavior.&lt;/p&gt;
&lt;p&gt;Also, since the requests don&#39;t care about each other, we don&#39;t need to
use the arguments that are coming from the previous promise, so the
function expression doesn&#39;t use its arguments.&lt;/p&gt;
&lt;p&gt;The one last catch (hoho) is that if any of the &lt;code&gt;rp.get(url)&lt;/code&gt; promises
fail, then all of the subsequent &lt;code&gt;.then&lt;/code&gt;s are skipped, as the promise
flow dictates that it should jump to a &lt;code&gt;.catch&lt;/code&gt; handler, if one
exists. So, to guarantee that we do make all the requests that we
wanted to, we need to add a catch handler to each of the promises in
the chain.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;urls.reduce(
    (acc, url) =&amp;gt; acc.then(() =&amp;gt; rp.get(url)
                           .then(sendRelatedRequests)
                           .catch(console.error)),
    Promise.resolve()
);
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Connecting to Mongo with a self signed CA on a JVM in Kubernetes</title>
    <link href="https://blog.danielgempesaw.com/post/kubernetes-mongo-ssca-jvm/"/>
    <updated>2017-12-10T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/kubernetes-mongo-ssca-jvm/</id>
    <content type="html">&lt;p&gt;At $WORK, we&#39;re creating an internal platform on top of Kubernetes for
developers to deploy their apps. Our Ops people have graciously
provided us with Mongo clusters that all use certificates signed by a
self-signed certificate authority. So, all our clients need to know
about the self-signed CA in order to connect to Mongo. For Node or
Python, it&#39;s possible to pass the self-signed CA file in the code
running in the application.&lt;/p&gt;
&lt;p&gt;But, things are a little more complicated for Java or Scala apps,
because configuration of certificate authorities is done at the JVM
level, not at the code level. And for an extra level of fun, we want
to do it in Kubernetes, transparently to our developers, so they don&#39;t have to worry about it on their own.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;h3&gt;err, wha? telling the JVM about our CA&lt;/h3&gt;
&lt;p&gt;First off, we had to figure out how to tell the JVM to use our CA. And
luckily since all the JVM languages use the same JVM, it&#39;s the same
steps for Scala, or Clojure, or whatever other JVM language you
prefer. The &lt;a href=&quot;http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/ssl/#jvm-system-properties-for-tls-ssl&quot;&gt;native MongoDB Java driver docs&lt;/a&gt; tell us exactly
what we need to do: use &lt;code&gt;keytool&lt;/code&gt; to import the cert into a keystore
that the JVM wants, and then use system properties to tell the JVM to
use that keystore. The &lt;code&gt;keytool&lt;/code&gt; command in the docs is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ keytool -importcert -trustcacerts -file &amp;lt;path to certificate authority file&amp;gt; &#92;
  -keystore &amp;lt;path to trust store&amp;gt; -storepass &amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The path to the existing keystore that the JVM uses by default is
&lt;code&gt;$JAVA_HOME/jre/lib/security/cacerts&lt;/code&gt;, and its default password is
&lt;code&gt;changeit&lt;/code&gt;. So if you wanted to add your self signed CA to the
existing keystore, it&#39;d be something like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ keytool -importcert -trustcacerts -file ssca.cer &#92;
  -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Even this very first step had complications. Our self signed CA was a
Version 1 cert with v3 extensions, and while no other language cared,
&lt;code&gt;keytool&lt;/code&gt; refused to create a keystore with it. We ended up having to
create a new self-signed CA with the appropriate version. Some lucky
googling led us to that conclusion, but of particular use was using
&lt;code&gt;openssl&lt;/code&gt; to examine the CA and check its versions and extensions:)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ openssl x509 -in ssca.cer -text -noout
// Certificate:
//     Data:
//         Version: 3 (0x2)
//         Serial Number: ...
//         ...
//         X509v3 extensions:
//             X509v3 Subject Key Identifier: ...
//             X509v3 Key Usage: ...
//             X509v3 Basic Constraints: ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another useful command was examining the keystore before and after we
imported our self signed CA:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ keytool -list -keystore /path/to/keystore/file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;as you can look for your self-signed CA in there to see if you ran the
command correctly.&lt;/p&gt;
&lt;p&gt;Anyway, once you&#39;ve created a keystore for the JVM, the next step is
to set the appropriate system properties, again as out lined in the &lt;a href=&quot;http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/ssl/#jvm-system-properties-for-tls-ssl&quot;&gt;docs&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ java &#92;
  -Djavax.net.ssl.trustStore=/path/to/cacerts &#92;
  -Djavax.net.ssl.trustStorePassword=changeit &#92;
  -jar whatever.jar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the default password is &lt;code&gt;changeit&lt;/code&gt;, you may want to change
it... but if you don&#39;t change it, you wouldn&#39;t have to specify the
trustStorePassword system property.&lt;/p&gt;
&lt;h3&gt;handling this in kubernetes&lt;/h3&gt;
&lt;p&gt;The above steps aren&#39;t too complicated on their own. We just need to
make sure we add our CA to the existing ones, and point the JVM
towards our new and improved file. But, since we&#39;ll eventually need to
rotate the self-signed CA, we can&#39;t just run &lt;code&gt;keytool&lt;/code&gt; once and copy
it everywhere. So, an &lt;code&gt;initContainer&lt;/code&gt; it is! &lt;code&gt;keytool&lt;/code&gt; is a java
utility, and it&#39;s handily available on the &lt;code&gt;openjdk:8u121-alpine&lt;/code&gt;
image, which means we can make a initContainer that runs &lt;code&gt;keytool&lt;/code&gt; for
us dynamically, as part of our Deployment.&lt;/p&gt;
&lt;p&gt;Since seeing the entire manifest at once doesn&#39;t necessarily make it
easy to see what&#39;s going on, I&#39;m going to show the key bits piece by
piece. All of the following chunks of yaml belong to in the
&lt;code&gt;spec.template.spec&lt;/code&gt; object of a Deployment or Statefulset.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;spec:
  template:
    spec:
      volumes:
      - name: truststore
        emptyDir: {}
      - name: self-signed-ca
        secret:
          secretName: self-signed-ca
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, first things first, volumes: an empty volume called &lt;code&gt;truststore&lt;/code&gt;
which we&#39;ll put our new and improved keystore-with-our-ssca. Also,
we&#39;ll need a volume for the self-signed CA itself. Our Ops provided it
for us in a secret with a key &lt;code&gt;ca.crt&lt;/code&gt;, but you can get it into your
containers any way you want.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ kubectl get secret self-signed-ca -o yaml --export
apiVersion: v1
data:
  ca.crt: ...
kind: Secret
metadata:
  name: self-signed-ca
type: Opaque
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the volumes in place, we need to set up init containers to do our
keytool work. I assume (not actually sure) that we need to add our
self-signed CA to the existing CAs, so we use one initContainer to
copy the existing default &lt;code&gt;cacerts&lt;/code&gt; file into our &lt;code&gt;truststore&lt;/code&gt; volume,
and another initContainer to run the &lt;code&gt;keytool&lt;/code&gt; command. It&#39;s totally
fine to combine these into one container, but I didn&#39;t feel like
making a custom docker image with a shell script or having a super
long command line. So:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;spec:
  template:
    spec:
      initContainers:
      - name: copy
        image: openjdk:8u121-alpine
        command: [ cp,
                   /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts,
                   /ssca/truststore/cacerts ]
        volumeMounts:
        - name: truststore
          mountPath: /ssca/truststore

      - name: import
        image: openjdk:8u121-alpine
        command: [ keytool, -importcert, -v, -noprompt, -trustcacerts,
                   -file, /ssca/ca/ca.crt, -keystore, /ssca/truststore/cacerts,
                   -storepass, changeit ]
        volumeMounts:
        - name: truststore
          mountPath: /ssca/truststore
        - name: self-signed-ca
          mountPath: /ssca/ca
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the &lt;code&gt;truststore&lt;/code&gt; volume in the &lt;code&gt;copy&lt;/code&gt; initContainer, grab the
file cacerts file, and put it in our &lt;code&gt;truststore&lt;/code&gt; volume. Note that
while we&#39;d like to use $JAVA_HOME in the &lt;code&gt;copy&lt;/code&gt; initContainer, I
couldn&#39;t figure out how to use environment variables in the
command. Also, since we&#39;re using a tagged docker image, there is a
pretty good guarantee that the filepath shouldn&#39;t change underneath
us, even though it&#39;s hardcoded.&lt;/p&gt;
&lt;p&gt;Next, the import step! We need to mount the self-signed CA into this
container as well. Run the &lt;code&gt;keytool&lt;/code&gt; command as described above,
referencing our copied &lt;code&gt;cacerts&lt;/code&gt; file in our &lt;code&gt;truststore&lt;/code&gt; volume and
passing in our ssCA.&lt;/p&gt;
&lt;p&gt;Two things to note here: the &lt;code&gt;-noprompt&lt;/code&gt; argument to &lt;code&gt;keytool&lt;/code&gt; is
mandatory, or else &lt;code&gt;keytool&lt;/code&gt; will prompt for interaction, but of
course the initContainer isn&#39;t running in a shell for someone to hit
&lt;code&gt;yes&lt;/code&gt; in. Also, the mountPaths for these volumes should be separate
folders! I know Kubernetes is happy to overwrite existing directories
when a volume mountPath clashes with a directory on the image, and
since we have different data in our volumes, they can&#39;t be in the same
directory. (...probably, I didn&#39;t actually check)&lt;/p&gt;
&lt;p&gt;The final step is telling the JVM where our new and improved trust
store is. My first idea was just to add &lt;code&gt;args&lt;/code&gt; to the manifest and set
the system property in there, but if the Dockerfile &lt;code&gt;ENTRYPOINT&lt;/code&gt; is
something like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java -jar whatever.jar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then we&#39;d get a command like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java -jar whatever.jar -Djavax.net.ssl.trustStore=...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which would pass the option to the jar instead of setting a system
property. Plus, that wouldn&#39;t work at all if the &lt;code&gt;ENTRYPOINT&lt;/code&gt; was a
shell script or something that wasn&#39;t expecting arguments.&lt;/p&gt;
&lt;p&gt;After some searching, StackOverflow taught us about the &lt;code&gt;JAVA_OPTS&lt;/code&gt;
and &lt;code&gt;JAVA_TOOL_OPTIONS&lt;/code&gt; &lt;a href=&quot;https://stackoverflow.com/questions/28327620/difference-between-java-options-java-tool-options-and-java-opts&quot;&gt;environment variables&lt;/a&gt;. We can
append our trustStore to the existing value of these env vars, and
we&#39;d be good to go!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;spec:
  template:
    spec:
      containers:
      - image: your-app-image
        env:
          # make sure not to overwrite this when composing the yaml
        - name: JAVA_OPTS
          value: -Djavax.net.ssl.trustStore=/ssca/truststore/cacerts
        volumeMounts:
        - name: truststore
          mountPath: /ssca/truststore

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our app that we use to construct the manifests, we check if the
developer is already trying to set JAVA_OPTS to something, and make
sure that we append to the existing value instead of overwriting it.&lt;/p&gt;
&lt;h3&gt;a conclusion of sorts&lt;/h3&gt;
&lt;p&gt;Uh, so that got kind of long, but the overall idea is more or less
straightforward. Add our self-signed CA to the existing cacerts file,
and tell the JVM to use it as the truststore. (Note that it&#39;s the
trustStore option you want, not the keyStore!). The entire Deployment
manifest all together &lt;a href=&quot;https://github.com/gempesaw/writing/blob/master/published/kubernetes-mongo-ssca-jvm.yaml&quot;&gt;is also available&lt;/a&gt;, if that sounds
useful...&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Uninstalling Mersive&#39;s Solstice Audio Driver from MacOS Mojave</title>
    <link href="https://blog.danielgempesaw.com/post/mersive-solstice-desktop-audio-streaming-client/"/>
    <updated>2019-08-06T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/mersive-solstice-desktop-audio-streaming-client/</id>
    <content type="html">&lt;p&gt;This was a minor annoyance, but since my Google searches were particularly unfruitful, I figured I&#39;d make a note of it. Our WeWork uses the Mersive Solstice client for broadcasting our devices to the meeting room televisions. It has the option to install its own audio driver to try to mirror the audio on its own.&lt;/p&gt;
&lt;p&gt;The client&#39;s built-in audio driver is called &amp;quot;Desktop Audio Streaming Device&amp;quot; and it shows up as an output and an input device. It also completely failed to work at all. The only way I managed to get sound on to the TV was by using AirPlay after connecting with the Solstice client - basically using it as little as possible.&lt;/p&gt;
&lt;p&gt;Uninstalling audio drivers is apparently something weird in OS X - the device was listed in the &lt;code&gt;Audio Midi Setup&lt;/code&gt; built-in macOS app, but couldn&#39;t be uninstalled from the app. Some wild googling directed me to &lt;code&gt;/Library/Audio/Plug-Ins/HAL/&lt;/code&gt;, or &lt;code&gt;/Library/Preferences&lt;/code&gt;, or their &lt;code&gt;~/Library&lt;/code&gt; counterparts. In the end, it was a &lt;code&gt;kext&lt;/code&gt; in &lt;code&gt;/System/Library/Extensions&lt;/code&gt;: &lt;code&gt;SolsticeAudioDevice.kext&lt;/code&gt;. Trashing that file and restarting the computer fixed the issue.&lt;/p&gt;
</content>
  </entry>
  
  
  <entry>
    <title>Getting started with standalone Kayenta + Referee for Automated Canary Analysis</title>
    <link href="https://blog.danielgempesaw.com/post/kayenta-referee-quickstart/"/>
    <updated>2021-04-16T00:00:00Z</updated>
    <id>https://blog.danielgempesaw.com/post/kayenta-referee-quickstart/</id>
    <content type="html">&lt;p&gt;Automated canary analysis is a deploy strategy wherein you direct a
subset of your (production?) traffic to a canary version of your
application. The idea is that your baseline application and your
canary application will then be shipping metrics off to your metrics
provider, and Kayenta + Referee help you determine whether your new
code fails any metrics! This replaces developers manually looking at
dashboards &amp;amp; logs during deploys.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/spinnaker/kayenta&quot;&gt;Kayenta&lt;/a&gt; is an open source Java microservice for performing
automated canary analysis - it&#39;s just one microservice of many that
make up Netflix&#39;s &lt;a href=&quot;https://github.com/spinnaker&quot;&gt;Spinnaker&lt;/a&gt; platform. &lt;a href=&quot;https://github.com/nikeinc/referee&quot;&gt;Referee&lt;/a&gt; is an
open-source React frontend that sits in front of Kayenta and allows
for rapid iteration of your canary configurations. This blog post will
outline the steps I took to get this set up at $WORK recently!&lt;/p&gt;
&lt;p&gt;You can read through the details below in this blog post, or go
straight to the &lt;a href=&quot;https://github.com/gempesaw/kayenta-referee-quickstart&quot;&gt;kayenta-referee-quickstart repo&lt;/a&gt; to get started
right away.&lt;/p&gt;
&lt;p&gt;[[MORE]]&lt;/p&gt;
&lt;h2&gt;Configuring Kayenta&lt;/h2&gt;
&lt;p&gt;Starting up Kayenta consists mainly of configuring its three data
stores in the &lt;code&gt;kayenta.yml&lt;/code&gt; config: &lt;code&gt;METRICS_STORE&lt;/code&gt;,
&lt;code&gt;CONFIGURATION_STORE&lt;/code&gt;, and &lt;code&gt;OBJECT_STORE&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;METRICS_STORE&lt;/code&gt;, choose the one that your applications is
shipping its metrics to. Kayenta supports Atlas, Google, Datadog,
graphite, New Relic, Prometheus, SignalFX, and Wavefront. You&#39;ll need
to obtain the appropriate API keys to allow Kayenta to query the
metrics API, which will depend on the datastore you&#39;re using. For
datadog, the config excerpt looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  datadog:
    enabled: false
    metadataCachingIntervalMS: 900000
    accounts:
      - name: my-datadog-account
        apiKey: xxxx
        applicationKey: xxxx
        supportedTypes:
          - METRICS_STORE
        endpoint.baseUrl: https://app.datadoghq.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For &lt;code&gt;CONFIGURATION_STORE&lt;/code&gt; and &lt;code&gt;OBJECT_STORE&lt;/code&gt;, you can start out with
the built-in &lt;code&gt;in-memory-store&lt;/code&gt;, and this is already configured in the
quickstart repo. Later, you can switch that to S3/GCP/Azure if you need to
persist your configs/objects.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  memory:
    enabled: true
    accounts:
    - name: in-memory-store
      supportedTypes:
      - OBJECT_STORE
      - CONFIGURATION_STORE
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;running kayenta + referee&lt;/h2&gt;
&lt;p&gt;Over in the kayenta-referee-quickstart Github repo, there are
dockerfiles and a &lt;code&gt;docker-compose.yml&lt;/code&gt; that you can use to run both of
the microservices locally. Fill out your metrics store API keys in the
&lt;code&gt;kayenta.yml&lt;/code&gt; config at the root of the repo, and then you can start
it up:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Kayenta API documentation will be available at
http://localhost:3001/swagger-ui.html, and Referee will be running at
http://localhost:8090/dashboard. If the containers don&#39;t come up,
check their logs for any telling messages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker-compose logs kayenta
docker-compose logs referee
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you decide you want to deploy Kayenta &amp;amp; Referee into your internal
infrastructure, you&#39;ll need to provide a Redis instance for Kayenta to
talk to. This will depend on your internal infrastructure, but in a
pinch, you could use a Docker container running Redis even without a
persistent data volume backing it, if you don&#39;t need to store the
Canary configurations inside Kayenta.&lt;/p&gt;
&lt;h2&gt;integrating kayenta + referee into your production deploys&lt;/h2&gt;
&lt;p&gt;If you&#39;re embarking on the canary  production deploy integration
road, one of the most useful tips I came across was to start out with
an asynchronous canary pipeline separate from your existing production
pipeline. Have the canary pipeline run in parallel to your existing
production deploy, and don&#39;t let the canary pipeline block or even
fail deploys. Instead, the idea is to set up the canary pipeline with
a few metrics and have it gather data on every production deploy until
you can see whether the metrics you chose are appropriate and would
catch real production issues.&lt;/p&gt;
&lt;h2&gt;canary configurations&lt;/h2&gt;
&lt;p&gt;Configuring a canary consists of constructing the POST body for the
standalone canary endpoint; there&#39;s probably enough material there for
its own blog post, so we&#39;ll defer that to a potential part two!&lt;/p&gt;
</content>
  </entry>
  
</feed>
