<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[mozilla - Muffin Research Labs]]></title><description><![CDATA[The blog of Stuart Colville, a Web Developer at Mozilla. Focusing primarily on web technologies, web development techniques and highly efficient yak shaving. ]]></description><link>https://muffinresearch.co.uk/</link><generator>Ghost 0.11</generator><lastBuildDate>Wed, 11 Apr 2018 18:42:52 GMT</lastBuildDate><atom:link href="https://muffinresearch.co.uk/tag/mozilla/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Using the latest version of Firefox in Travis CI]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2016/03/travis-firefox.jpg" alt=""></p>

<p>A quick tip. If you're running karma tests via Firefox on <a href="https://travis-ci.org/">Travis CI</a> by default the Firefox version used is quite old (31 at time of writing).</p>

<p>To always use the latest (current) version you can add this snippet to your <code>.travis.yml</code>.</p>

<pre><code class="language-yaml">addons:  
  firefox: latest
</code></pre>

<p>This will keep your</p>]]></description><link>https://muffinresearch.co.uk/using-the-latest-version-of-firefox-in-travis-ci/</link><guid isPermaLink="false">4f174099-bcbf-410a-8271-7d9905385c5c</guid><category><![CDATA[Firefox]]></category><category><![CDATA[mozilla]]></category><category><![CDATA[tip]]></category><category><![CDATA[testing]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Wed, 09 Mar 2016 10:26:21 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2016/03/travis-firefox.jpg" alt=""></p>

<p>A quick tip. If you're running karma tests via Firefox on <a href="https://travis-ci.org/">Travis CI</a> by default the Firefox version used is quite old (31 at time of writing).</p>

<p>To always use the latest (current) version you can add this snippet to your <code>.travis.yml</code>.</p>

<pre><code class="language-yaml">addons:  
  firefox: latest
</code></pre>

<p>This will keep your firefox up-to-date as new versions are released. Two other special release aliases are available:</p>

<ul>
<li><code>latest-esr</code> - The latest extended support release.</li>
<li><code>latest-beta</code> - The latest beta version.</li>
</ul>

<p>You can of course specify a specific version like so:</p>

<pre><code class="language-yaml">addons:  
  firefox: "44.0"
</code></pre>

<p>For for info see the <a href="https://docs.travis-ci.com/user/firefox/">Travis docs on setting firefox versions here</a>.</p>]]></content:encoded></item><item><title><![CDATA[Removing leading whitespace in ES6 template strings]]></title><description><![CDATA[<p>In some recent code at work we're using fairly large strings for error descriptions.</p>

<p>JavaScript has always made it hard to deal with long strings, especially when you need to format them across multiple lines. The solutions have always been that you need to concatenate multiple strings like so:</p>

<pre><code class="language-javascript">var</code></pre>]]></description><link>https://muffinresearch.co.uk/removing-leading-whitespace-in-es6-template-strings/</link><guid isPermaLink="false">518f2e7e-4116-4475-a71d-6a9101d4576d</guid><category><![CDATA[ES6]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[mozilla]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Mon, 12 Oct 2015 21:50:02 GMT</pubDate><content:encoded><![CDATA[<p>In some recent code at work we're using fairly large strings for error descriptions.</p>

<p>JavaScript has always made it hard to deal with long strings, especially when you need to format them across multiple lines. The solutions have always been that you need to concatenate multiple strings like so:</p>

<pre><code class="language-javascript">var foo = "So here is us, on the " +  
  "raggedy edge. Don't push me, " +
  "and I won't push you.";
</code></pre>

<p>Or use line-continuations:</p>

<pre><code class="language-javascript">var foo = "So here is us, on the \  
  raggedy edge. Don't push me, \
  and I won't push you.";
</code></pre>

<p>Neither of these are pretty. <a href="http://snook.ca/archives/javascript/multi-line-javascript#c63466">The latter was originally strictly illegal in ECMAScript</a> (hattip Joseanpg):</p>

<blockquote><p>A 'LineTerminator' character cannot appear in a string literal, even if preceded by a backslash \. The  
correct way to cause a line terminator character to be part of the string value of a string literal is to use  
an escape sequence such as \n or \u000A.</p>  
<footer>— <cite><a href="http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf">ECMA-262 3rd Edition</a></cite></footer>  
</blockquote>

<p>There's a rather wonderful <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=92944">bug on bugzilla discussing the ramifications of changing behaviour to strictly enforce the spec back in 2001</a>. In case you're wondering it was WONTFIXED.</p>

<p>In ECMAScript 5th edition this part was revised to the following:</p>

<blockquote><p>A line terminator character cannot appear in a string literal, except as part of a LineContinuation to produce the empty character sequence. The correct way to cause a line terminator character to be part of the String value of a string  
literal is to use an escape sequence such as \n or \u000A.</p>  
<footer>— <cite><a href="http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262%205th%20edition%20December%202009.pdf">ECMA-262 5th Edition</a></cite></footer>  
</blockquote>

<p>Anyway, enough with the history lesson, we now have features in ES6 on the horizon and if you're already starting to use ES6 via the likes of <a href="https://babeljs.io/">babel</a> or as features become available then it provides some interesting possibilities.</p>

<h2 id="divinginwithes6templatestrings">Diving in with ES6 template strings</h2>

<p>Having seen template strings I jumped right in only to find this happening.</p>

<pre><code class="language-javascript">var raggedy = 'raggedy';  
console.log(`So here is us, on the  
             ${raggedy} edge. Don't push
             me, and I won't push you.`);
</code></pre>

<p>So that looks neat right? But hang-on what does it output?</p>

<pre><code class="language-text">So here is us, on the  
             raggedy edge. Don't push
             me, and I won't push you.
</code></pre>

<p><img src="https://muffinresearch.co.uk/content/images/2015/10/mal-uh-whut.gif" alt=""></p>

<p>Dammit - so by default template strings preserve leading whitespace like heredoc in PHP (which is kind of a memory I'd buried).</p>

<p>Ok so <a href="https://esdiscuss.org/topic/multiline-template-strings-that-don-t-break-indentation">reading more on the subject of es6 template strings</a>, processing template strings differently is possible with tag functions. Tags are functions that allow you to process the template string how you want.</p>

<h2 id="makingatemplatetag">Making a template tag</h2>

<p>With that in mind I thought OK, I'm going to make a tag to make template strings have no leading whitespace on multiple lines but still handle var interpolation as by default.</p>

<p>Here's the code (es6) (<em>note a simpler version is linked to at the end of this post if you're not using full-fat es6 via babel</em>):</p>

<pre><code class="language-javascript">export function singleLineString(strings, ...values) {  
  // Interweave the strings with the
  // substitution vars first.
  let output = '';
  for (let i = 0; i &lt; values.length; i++) {
    output += strings[i] + values[i];
  }
  output += strings[values.length];

  // Split on newlines.
  let lines = output.split(/(?:\r\n|\n|\r)/);

  // Rip out the leading whitespace.
  return lines.map((line) =&gt; {
    return line.replace(/^\s+/gm, '');
  }).join(' ').trim();
}
</code></pre>

<p>The way tags work is they're passed an array of strings and the rest of the args are the vars to be substituted. Note: as we're using ES6 in this example we've made values into an array by using the spread operator. If the original source string was setup as follows:</p>

<pre><code class="language-javascript">var two = 'two';  
var four = 'four';  
var templateString = `one ${two} three ${four}`;  
</code></pre>

<p>Then strings is: <code>["one ", " three ", ""]</code> and values is <code>["two", "four"]</code></p>

<p>The loop up front is just dealing with interleaving the two lists to do the var substitution in the correct position.</p>

<p>The next step is to split on newlines to get a list of lines. Then the leading whitespace is removed from each line. Lastly the list is joined with a space between each line and the result is trimmed to remove any trailing space.</p>

<p>The net effect is that you get an easy way to have a long multiline string formatted nicely with no unexpected whitespace.</p>

<pre><code class="language-javascript">var raggedy = 'raggedy';  
console.log(singleLineString`So here is us, on the  
            ${raggedy} edge. Don't push
            me, and I won't push you.`);
</code></pre>

<p>Outputs:</p>

<pre><code class="language-text">So here is us, on the raggedy edge. Don't push me, and I won't push you.  
</code></pre>

<h2 id="tryingthisoutinthebrowser">Trying this out in the browser</h2>

<p>As template strings are <a href="http://kangax.github.io/compat-table/es6/#template_strings">becoming more and more available</a> - here's a version without the fancy ES6 syntax which should work in anything that supports template strings:</p>

<p>See <a href="http://jsbin.com/yiliwu/4/edit?js,console">http://jsbin.com/yiliwu/4/edit?js,console</a></p>

<p>All in all it's not too bad. Hopefully someone else will find this useful. Let us know if you have suggestions or alternative solutions.</p>]]></content:encoded></item><item><title><![CDATA[Python: testing beyond exceptions]]></title><description><![CDATA[<p>Recently working on some code I was doing some basic tests that checked for an exception being raised. </p>

<p>The tests looked like this: </p>

<pre><code>def test_user_identification_is_valid_option(self):  
   with self.assertRaises(ValueError):
       example_seller(products=[
           'id': 'hai',
           'description': 'a description',
           'recurrence': None,
           'user_identification': True,
       }])


def test_</code></pre>]]></description><link>https://muffinresearch.co.uk/python-testing-beyond-exceptions/</link><guid isPermaLink="false">11adc77c-62f8-45fe-9221-a2f02527cd96</guid><category><![CDATA[Python]]></category><category><![CDATA[mozilla]]></category><category><![CDATA[testing]]></category><category><![CDATA[assertions]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Fri, 28 Aug 2015 21:15:08 GMT</pubDate><content:encoded><![CDATA[<p>Recently working on some code I was doing some basic tests that checked for an exception being raised. </p>

<p>The tests looked like this: </p>

<pre><code>def test_user_identification_is_valid_option(self):  
   with self.assertRaises(ValueError):
       example_seller(products=[
           'id': 'hai',
           'description': 'a description',
           'recurrence': None,
           'user_identification': True,
       }])


def test_user_identification_is_required(self):  
     with self.assertRaises(ValueError):
         example_seller(products=[{
             'id': 'hai',
             'description': 'a description',
             'recurrence': None,
         }])
</code></pre>

<p>I realised that it was really easy to be tricked by other parts of the code that might raise the same exception. For example, in this case the required code is raising <code>ValueError</code> separately.</p>

<p>In JavaScript using assertions in chai, <a href="http://chaijs.com/api/assert/#throws"><code>assert.throws</code></a> takes a function that should throw an exception, the 2nd arg is the exception instance you're expecting and the third arg can be a regex to match the string passed to the exception.</p>

<p>I wanted to do the same thing in Python.</p>

<h2 id="assertraisesregexp">assertRaisesRegexp</h2>

<p>In Python (2.7+) <code>assertRaisesRegexp</code> does exactly what we want so we can fix our tests to be more explicit like so:</p>

<pre><code>def test_user_identification_is_valid_option(self):  
    with self.assertRaisesRegexp(ValueError, 'user_identification must'):
       example_seller(products=[
           'id': 'hai',
           'description': 'a description',
           'recurrence': None,
           'user_identification': True,
       }])


def test_user_identification_is_required(self):  
     with self.assertRaisesRegexp(ValueError, 'Missing user_ident'):
         example_seller(products=[{
             'id': 'hai',
             'description': 'a description',
             'recurrence': None,
         }])
</code></pre>

<p>The second argument can either be a <a href="https://docs.python.org/2/library/unittest.html#unittest.TestCase.assertRaisesRegexp">a regular expression object or a string containing a regular expression suitable for use by <code>re.search()</code></a>.</p>

<p>With this in place we can be sure our tests are asserting on the actual part of the code that raises the exception not just asserting that any old <code>ValueError</code> is good enough.</p>]]></content:encoded></item><item><title><![CDATA[Back to the future: ES6 + React]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/07/delorean.jpg" alt=""></p>

<p>I've just recently finished shaving about a billion yaks * to convert a React app over to use ES6 modules and classes so we can start living in the future that is ES6 with a sprinkling of ES7.</p>

<p><em>* Might not be true</em></p>

<h2 id="transpilingbacktothepresent">Transpiling back to the present</h2>

<p>We're using <a href="https://babeljs.io/">babel</a> via</p>]]></description><link>https://muffinresearch.co.uk/back-to-the-future-using-es6-with-react/</link><guid isPermaLink="false">a7580646-f711-45d4-8688-589b330d74a6</guid><category><![CDATA[mozilla]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[ES6]]></category><category><![CDATA[Babel]]></category><category><![CDATA[ES7]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Fri, 24 Jul 2015 18:21:42 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/07/delorean.jpg" alt=""></p>

<p>I've just recently finished shaving about a billion yaks * to convert a React app over to use ES6 modules and classes so we can start living in the future that is ES6 with a sprinkling of ES7.</p>

<p><em>* Might not be true</em></p>

<h2 id="transpilingbacktothepresent">Transpiling back to the present</h2>

<p>We're using <a href="https://babeljs.io/">babel</a> via <a href="http://webpack.github.io/">webpack</a> to transpile our ES6+ code into ES5. <a href="http://babeljs.io/docs/usage/experimental/">Babel exposes the various stages of ECMAScript proposals</a> so you can choose whatever stages are appropriate for your project. For example Stage 0 will give you the most features, but that will include things like strawman proposals that may never actually see the light of day.</p>

<p>For our project we've tried to stick to Stage2 which is Babel's default (Stage 2 features Draft specs), and then add to that a couple of more modern features which should hopefully make it to prime time.</p>

<p>The two features we've specifically added are:</p>

<ul>
<li><a href="https://github.com/sebmarkbage/ecmascript-rest-spread"><code>es7.objectRestSpread</code></a> from Stage 1. (A must for JSX e.g. <code>{...otherProps}</code>)</li>
<li><a href="https://gist.github.com/jeffmo/054df782c05639da2adb"><code>es7.classProperties</code></a> from Stage 0 - more on this one in a bit</li>
</ul>

<h2 id="es6modules">ES6 Modules</h2>

<p>Es6 Modules are very powerful, it takes a bit of getting used to coming from commonJS or AMD modules.</p>

<p>One of the really great things is that you can export more than one thing by using a default export and exporting something else. <br>
In this example the instance will be the default export that you'll get when importing this module:</p>

<p>E.g. </p>

<pre><code class="language-javascript">export class Tracking {  
    // Whatever
}

export default new Tracking();  
</code></pre>

<p>So now I have two options: </p>

<pre><code class="language-javascript">// Get an instance
import tracking from tracking;  
tracking.init();

// Get the class (handy for tests)
import { Tracking } from tracking;  
var tracking = new Tracking();  
tracking.init();  
</code></pre>

<p><a href="http://www.2ality.com/2014/09/es6-modules-final.html">There's lots of great info on the full range or what's possible with es6 modules here.</a></p>

<h2 id="reactcomponentswithes6classes">React components with ES6 classes</h2>

<p>When converting from ES5 there's quite a number of things to be aware of.</p>

<h3 id="settingdefaultstate">Setting default state</h3>

<p>You can easily do this in the constructor rather than using a separate <code>getInitialState</code> method.</p>

<pre><code>import React, { Component } from 'react';

class MyComponent  extends Component {  
    constructor() {
        super();
        this.state = {
            // Default state here.
        }
    }

    //... Everything else  
}
</code></pre>

<h3 id="settingdefaultpropsandproptypes">Setting <code>defaultProps</code> and <code>propTypes</code></h3>

<p>When using <code>defaultProps</code> and <code>propTypes</code> are defined as static class properties.</p>

<p>If you have <code>es7.classProperties</code> you can do this like so:</p>

<pre><code>import React, { Component, PropTypes } from 'react';

class MyComponent  extends Component {

    static propTypes = {
        foo: PropTypes.func.isRequired,
        bar: PropTypes.object,
    }

    static defaultProps = {
        foo: () =&gt; {
               console.log('hai');
        },
        bar: {},
    }

    //... Everything else
}
</code></pre>

<p>The alternative to this (when you don't have es7 shiny enabled) is to just set props directly on the class e.g:</p>

<pre><code class="language-javascript">class MyComponent  extends Component {  
    //... Everything else
}
MyComponent.propTypes = {foo: PropTypes.func.isRequired};  
MyComponent.defaultProps = {foo: function() { console.log('hai'); }};  
</code></pre>

<p>I found this very ugly though, so static class props seems to be a good way to go for now.</p>

<h3 id="ismountedisntavailable"><code>isMounted()</code> isn't available</h3>

<p>If you'd used <code>isMounted()</code> then this isn't availabe on ES6 classes extended from <code>Component</code>. If you really need it you can set a flag in <code>componentDidMount</code> and unset it again in <code>componentWillUnMount</code>.</p>

<h3 id="methodbinding">Method binding</h3>

<p>When passing methods around as props you'll find with ES6 classes <code>this</code> doesn't refer to the component like it used to with <code>React.createClass</code>.</p>

<p>To get back the same behaviour without using something ugly like:</p>

<pre><code>&lt;Foo onClick={this.handleClick.bind(this)} /&gt;  
</code></pre>

<p>You can use an arrow function instead: </p>

<pre><code class="language-javascript ">class MyComponent  extends Component {  
    handleClick = (e) =&gt; {
        // this is now the component instance.
        console.log(this);
    }
}
</code></pre>

<p>This works because arrow functions capture the <code>this</code> value of the enclosing context. In otherwords an arrow function gets the this value from where it was defined, rather than where it's used.</p>

<p>If you want to get really fancy you can use <a href="http://babeljs.io/blog/2015/05/14/function-bind/">"function bind syntax"</a>.</p>

<p>Which you get by doing this:</p>

<pre><code>&lt;Foo onClick={::this.handleClick} /&gt;  
</code></pre>

<p>Which is equivalent to the previous <code>bind()</code> example. But to do that you'd need to enable <a href="https://github.com/zenparsing/es-function-bind"><code>es7.functionBind</code></a>. For me this was a step too far and I'm happy to stick with the arrow functions.</p>

<h2 id="testingwithes67">Testing with ES6/7</h2>

<p>Our previous tests had made some good use of <a href="https://github.com/jhnns/rewire">rewire.js</a> to modify requires and vars that weren't exported from the module (It does this with some cheeky injection techniques).</p>

<p>Unfortunately due to some changes in Babel rewire isn't compatible (at the moment) with ES6 modules. There's an alternative <a href="https://github.com/speedskater/babel-plugin-rewire">babel-plugin-reqire</a> but that injects getters and setters into every module. </p>

<h3 id="dependencyinjectioninreactclasses">Dependency Injection in React Classes</h3>

<p>Instead of using module mangling it was easiest to fall-back to dependency injection for the places where we were changing Components to fake ones. </p>

<p>In React props look like a good fit for dep injection:</p>

<pre><code class="language-javascript">import DefaultOtherComponent from 'components/other';

class MyComponent extends Component {

    static defaultProps: {
        OtherComponent: DefaultOtherComponent,
    }

    //... Snip

    render() {
        var OtherComponent = this.props.OtherComponent;
        return (
          &lt;OtherComponent {...this.props} /&gt;
        );
    }
}
</code></pre>

<p>Now in the test we can inject a fake component:</p>

<pre><code class="language-javascript">TestUtils.renderIntoDocument(  
  &lt;MyComponent OtherComponent={FakeOtherComponent} /&gt;
);
</code></pre>

<h3 id="getdomnodeisdeprecated">getDOMNode() is deprecated</h3>

<p>In ES6 React classes <code>getDOMNode()</code> is not present so you'll need to refactor all calls to <code>MyComponent.getDOMNode()</code> to <code>React.findDOMNode(MyComponent)</code> instead. The docs also mention <a href="https://facebook.github.io/react/docs/component-api.html#getdomnode">it's deprecated</a> so it might be removed completely in the future.</p>

<h2 id="summary">Summary</h2>

<p>There's quite a bit of work in making the conversion depending on how big your code-base is and depending on how much use of ES6 you're making already.</p>

<p>A lot of the new features in ES6 are making things much easier for developers so I'd definitely say it's a direction worth moving in assuming you're comfortable with all the aspects of transpilation. Webpack + babel makes this pretty straightforward. If you're already using babel for JSX (or some other similar loader for JSX) then you're already most of the way there. </p>

<p><em>FWIW: if you're not using babel, switching to it is now an <a href="https://facebook.github.io/react/blog/2015/06/12/deprecating-jstransform-and-react-tools.html">official recommendation</a>.</em></p>

<p>I'm very impressed with the currently ecosystem around JS e.g. tools like babel and webpack alongside forward thinking libs like React + Redux. All of these things sit well with each other and allow projects like ours to be able to step into the future today.</p>

<p>Now we've just got to get used to all the new syntax and start using more of it!</p>

<h2 id="furtherreading">Further reading</h2>

<ul>
<li><a href="https://facebook.github.io/react/docs/reusable-components.html#es6-classes">React docs on ES6 classes</a></li>
<li><a href="https://facebook.github.io/react/docs/component-api.html">Component API docs</a> - has lots of info on what parts of the API are different for ES6 classes</li>
<li><a href="http://babeljs.io/blog/2015/06/07/react-on-es6-plus/">Babel blog post on using ES6+</a> - useful blog post with old and new code examples.</li>
</ul>

<h2 id="credits">Credits</h2>

<ul>
<li><em>Image By Terabass (Own work) <a href="http://creativecommons.org/licenses/by-sa/4.0">CC BY-SA 4.0</a>, via Wikimedia Commons</em></li>
</ul>]]></content:encoded></item><item><title><![CDATA[Running tests on Sauce Labs via Travis]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/07/saucelabs-logo.png" alt=""></p>

<p>For the Payments Team's front-end projects we've just landed support for running the front-end unit tests using <a href="https://saucelabs.com/">Sauce Labs</a>.</p>

<h2 id="aboutsaucelabs">About Sauce Labs</h2>

<p>In case you've never heard of Sauce Labs (unlikely!) they provide access to a <a href="https://saucelabs.com/platforms/">multitude of browser/platform combinations</a> via vms so you can run your automated test</p>]]></description><link>https://muffinresearch.co.uk/running-sauce-labs-via-travis/</link><guid isPermaLink="false">3f29161f-8093-4a84-b95e-b41d210f9a2e</guid><category><![CDATA[mozilla]]></category><category><![CDATA[testing]]></category><category><![CDATA[karma]]></category><category><![CDATA[travis]]></category><category><![CDATA[sauce labs]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Fri, 10 Jul 2015 18:30:59 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/07/saucelabs-logo.png" alt=""></p>

<p>For the Payments Team's front-end projects we've just landed support for running the front-end unit tests using <a href="https://saucelabs.com/">Sauce Labs</a>.</p>

<h2 id="aboutsaucelabs">About Sauce Labs</h2>

<p>In case you've never heard of Sauce Labs (unlikely!) they provide access to a <a href="https://saucelabs.com/platforms/">multitude of browser/platform combinations</a> via vms so you can run your automated test suite (or do manual testing) and get comprehensive cross browser coverage fairly easily.</p>

<p>Open source projects can get an 'Open Sauce' account for free. You can <a href="https://saucelabs.com/opensauce/">find out more on the 'Open Sauce' account here</a>. Once you sign-up you will have a username and access key that are used to get access to the service.</p>

<h2 id="settingupthetestrunner">Setting up the test runner</h2>

<p>We're already using the excellent <a href="http://karma-runner.github.io/">Karma</a> as our test runner. Karma is essentially a test runner which browsers connect to in order to run a suite of unit tests. </p>

<p>As we're using <a href="https://facebook.github.io/react/">React</a> we're tending to use unit tests a lot more than before. This is because unit testing in React is really straightforward and it saves us having to worry about end-to-end (E2E) testing up front like we did before with Casper and PhantomJS etc. (We're still planning some integration tests but they can come later). Putting more effort into unit testing feels like the right thing to do. The tests are much more self-contained and therefore less brittle than E2E tests.</p>

<p>To get our existing Karma tests running with sauce labs we used the <a href="https://github.com/karma-runner/karma-sauce-launcher">karma-sauce-loader</a> which  handles the setup of a tunnel and all the connections from each Sauce labs browser into the karma test runner.</p>

<p>To DRY things up we have a shared karma config which is just a module exporting the main options object. This is then used by a simple karma config <code>karma.conf.js</code> which just runs tests on Firefox and the sauce labs karma config file <code>karma.conf.sauce.js</code>.</p>

<p><img src="https://muffinresearch.co.uk/content/images/2015/07/sauce-tests.png" alt=""></p>

<h2 id="handlingprsconditionally">Handling PRs conditionally</h2>

<p>The access key and username are used via env vars in our karma config in order to allow our automated tests to run on Sauce labs.</p>

<p>Using TravisCI as our CI you can encrypt the <code>SAUCE_ACCESS_KEY</code> and <code>SAUCE_USERNAME</code> env vars so you don't publically expose them (Which would otherwise anyone to run tests on your account). See this doc for more details: <a href="http://docs.travis-ci.com/user/encryption-keys">Encryption Keys (docs.travis-ci.com)</a>.</p>

<p>But, if you do that, when you propose a PR from your fork of the project it won't be able to run the tests on Sauce Labs as encrypted secrets aren't exposed to pull requests that <em>aren't</em> made from branches on the main repo.</p>

<p>To work around this we can run the tests conditionally by looking at the <code>TRAVIS_SECURE_ENV_VARS</code> env var like so:</p>

<pre><code class="language-javascript">// Conditionally run saucelabs tests if we have the
// secure vars or a normal test run if not.
grunt.registerTask('test-ci', function() {  
  if (process.env.TRAVIS_SECURE_ENV_VARS === 'true') {
    grunt.log.writeln('Running full SauceLabs test suite');
    grunt.task.run('test-sauce');
  } else {
    grunt.log.writeln('Running limited test suite');
    grunt.task.run('test');
  }
});
</code></pre>

<p>If it's a PR from a fork we just run the standard tests on Firefox on Travis (because <code>TRAVIS_SECURE_ENV_VARS</code> is 'false'). </p>

<p>Otherwise if the PR is from a branch on the main repo <em>or</em> a commit on master, the tests will be run by our pre-defined set of browsers on Sauce Labs.</p>

<p>Some projects just commit their public access keys but I feel it's not a good idea to propagate a bad practice like that. This workaround feels like a fair compromise. </p>

<p>If any of the team end up working on something that warrants extra testing before landing we can always push the branch to the main repo first and make a PR from that.</p>

<h2 id="sharingthebrowserconfig">Sharing the browser config</h2>

<p>To make it easier to share the browser config (which tells Sauce labs which browser versions and platform combinations we want) we have a <a href="https://github.com/mozilla/payments-saucelabs-browsers">node package</a> which contains a simple config object. This module can be shared across all the projects that need to run tests on the same set of browsers. </p>

<p>For now we're testing the last two versions of Firefox, Chrome, Safari and IE but we can tweak this as we move forward.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Using Sauce labs makes running your existing testsuite on a broad set of platform and browser combinations really straight-forward for a minimal investment in setup time.</p>

<p>In our case <code>karma-sauce-launcher</code> made it really easy.</p>]]></content:encoded></item><item><title><![CDATA[SVG credit-card provider icons]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/07/card-icons.png" alt=""></p>

<p>Recently I've been working on a <a href="https://github.com/mozilla/payments-ui">UI for credit-card payments</a>. As part of this we needed some credit-card icons to show the card type as the user types in the number to the input field.</p>

<p>In looking for existing iconography I either couldn't find exactly what I was looking for,</p>]]></description><link>https://muffinresearch.co.uk/svg-credit-card-icons/</link><guid isPermaLink="false">b9913bc9-e6a0-43b2-af0c-d8334ae419a1</guid><category><![CDATA[github]]></category><category><![CDATA[mozilla]]></category><category><![CDATA[svg]]></category><category><![CDATA[open source]]></category><category><![CDATA[graph]]></category><category><![CDATA[ux]]></category><category><![CDATA[payments]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Wed, 08 Jul 2015 13:24:09 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/07/card-icons.png" alt=""></p>

<p>Recently I've been working on a <a href="https://github.com/mozilla/payments-ui">UI for credit-card payments</a>. As part of this we needed some credit-card icons to show the card type as the user types in the number to the input field.</p>

<p>In looking for existing iconography I either couldn't find exactly what I was looking for, or the license terms were unknown. In the end I built up a small set of icons using a mix of Sketch and InkScape and provided them as svg on github.</p>

<p>You can see a <a href="http://muffinresear.ch/payment-icons/">preview of all the current icons here</a>.</p>

<p>The repository is at <a href="https://github.com/muffinresearch/payment-icons">https://github.com/muffinresearch/payment-icons</a> (MPL 2.0).</p>

<h2 id="contributions">Contributions</h2>

<p>If you want to contribute updates or improvements ti these icons, please feel free to submit a pull request with any changes.</p>

<p>If you have new icons you want to be included then please follow the examples given and add your icon for each of the existing styles and make a pull request on the github repo.</p>]]></content:encoded></item><item><title><![CDATA[Tips for building a dev-env with docker]]></title><description><![CDATA[There's a few gotchas when using docker to run your development environment. This post provides tips on overcoming the biggest hurdles you might face.]]></description><link>https://muffinresearch.co.uk/tips-for-building-a-dev-env-with-docker/</link><guid isPermaLink="false">3e55d524-4d39-421d-a872-dc2afb6832fe</guid><category><![CDATA[docker]]></category><category><![CDATA[mozilla]]></category><category><![CDATA[docker-compose]]></category><category><![CDATA[fig]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Fri, 05 Jun 2015 20:49:00 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2014/Aug/large_h-trans.png" alt="The docker logo"></p>

<p>Using <a href="https://www.docker.com/">docker</a> and <a href="https://docs.docker.com/compose/">docker-compose</a> to run a development environment can be a good way to have all your services connected and running together. </p>

<p>I'm going to assume you've got a basic understanding of docker and how it works if not there's a good <a href="https://www.docker.com/whatisdocker/">overview of what docker is here</a>. </p>

<p>We're currently using docker-compose alongside docker to tie together several services for the <a href="https://github.com/mozilla/payments-env/">Mozilla payments development environment</a>.</p>

<p>Having used docker-compose (née fig) on the marketplace development environment. We learnt a lot about what did and didn't work.</p>

<p>Two of the biggest issues we hit were:</p>

<ul>
<li>Dependencies and dep updates</li>
<li>Front-end tools</li>
</ul>

<h2 id="handlingdepsoffline">Handling deps offline</h2>

<p><em>Note: I've written about this problem before in detail: <a href="https://muffinresearch.co.uk/docker-and-dependencies/">Docker and dependencies</a></em></p>

<p>If you're running a development environment it's likely you'll be running pip or npm in the Dockerfile. The problem here is that installing all those deps is one layer of the cache. As soon as you update the requirements.txt or package.json that step needs to run again - if you're running the build yourself that can be painful.</p>

<p><img src="https://muffinresearch.co.uk/content/images/2015/06/mal-uh-whut.gif" alt=""></p>

<p>I think there's still room for a better solution, but the best way to avoid deps becoming a problem, is to use the hub to build your docker images from a branch in github. </p>

<p>This way you can just pull new images to update your entire environment and they have the latest deps. If you need a new dep, you can just manually install it on the running container (see docker-exec) and when you commit the deps file update the newly built image will have your new dep in it.</p>

<h2 id="frontendtoolchain">Front end toolchain</h2>

<p>The next problem that was a big one for us was performance of front-end tooling in a docker container. If you're running anything other than Linux then you'll likely be running boot2docker in virtualbox. The problem with Virtualbox is that you're probably sharing the code into the vm with vboxfs. Unfortunately this doesn't provide the low-level file-change notifications into the vm from the host. So things that we typically use for front-end to watch for file-changes tend to work very slowly and cause virtualbox to eat CPU. From my experience NFS is better from a perf point of view, but still not great.</p>

<p>The trick to solving this one is again to leverage building images on the docker hub. Most of your front-end code is going to just be creating static files. So from your dev-env's perspective you just need to provide the files and serve them from your favorite web server e.g. nginx. The other neat thing is, if you do this right, you're not going to need to remember to commit built files to your tree. \o/</p>

<p><img src="https://muffinresearch.co.uk/content/images/2015/06/anchormanlsc.jpg" alt=""></p>

<p>The way we do this is with a <a href="https://docs.docker.com/userguide/dockervolumes/#creating-and-mounting-a-data-volume-container">data volume container</a> (or data-only container) that just contains the files. For developing locally we do a switcheroo and point that volume to our local source code in the docker-compose.yml.</p>

<p>All the file-watching tools (grunt/gulp and friends) and npm deps are installed and run on the host <em>not</em> in a container.</p>

<p>To have the docker env still work out of the box, we set-up hooks on travis to publish the built files (when the tests have successfully passed) to a different branch and the docker hub builds the image from that.</p>

<h2 id="insummary">In summary</h2>

<p>When things don't work you have to go back to the drawing board. Sometimes if you feel like you're fighting a tool then you're probably <em>doing it wrong</em> ™. </p>

<p>In our case leveraging the docker hub has made a real difference, Thanks to <a href="https://twitter.com/andymckay">@AndyMckay</a> for pushing us in that direction.</p>

<p>All in all I think we're starting to think more like we would for using docker in production. Which is not a bad thing, and it would mean that going from having a working development environment to something that could be running in prod would be less of a leap.</p>

<p>I've glossed over a lot of details - so if you'd like to know more take a look at the <a href="https://github.com/mozilla/?utf8=%E2%9C%93&amp;query=payments">payments repos</a> or let me know in the comments.</p>]]></content:encoded></item><item><title><![CDATA[JS: Creating instances without new]]></title><description><![CDATA[<p>During a code review recently I was looking at some code that was using the <code>new</code> keyword to create an instance e.g:</p>

<pre><code>var inst = new MyConstructor();
</code></pre>

<h2 id="thecontextobjectwhennewisntused">The context object when <code>new</code> isn't used</h2>

<p>The code contained a safeguard to bail if the new keyword wasn't used. Which is a</p>]]></description><link>https://muffinresearch.co.uk/js-create-instances-without-new/</link><guid isPermaLink="false">cc7b4280-0f69-4a75-b155-c9625dfcfb0d</guid><category><![CDATA[mozilla]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Fri, 13 Mar 2015 14:40:38 GMT</pubDate><content:encoded><![CDATA[<p>During a code review recently I was looking at some code that was using the <code>new</code> keyword to create an instance e.g:</p>

<pre><code>var inst = new MyConstructor();
</code></pre>

<h2 id="thecontextobjectwhennewisntused">The context object when <code>new</code> isn't used</h2>

<p>The code contained a safeguard to bail if the new keyword wasn't used. Which is a good idea because if the the <code>new</code> keyword is omitted, the context will be <code>window</code>. </p>

<script src="https://gist.github.com/muffinresearch/a8299e0708b22154ab64.js"></script>

<p>This outputs:</p>

<pre><code>"[object Window]"
"[object Object]"
</code></pre>

<h2 id="makingaflexibleconstructor">Making a flexible constructor</h2>

<p>To move away from the need to require <code>new</code> we ended up changing the constructor to allow instance creation both <em>with</em> and <em>without</em> <code>new</code>. This meant that we could create our objects more directly. In our case the code was passing the objects as args so getting rid of <code>new</code> simplified things quite a bit.</p>

<script src="https://gist.github.com/muffinresearch/3bf28ab2b1dcfa25d1e2.js"></script>

<p>This outputs:</p>

<pre><code>"foo1"
"foo2"
</code></pre>

<p>So now:</p>

<pre><code>var inst = MyConstructor();
</code></pre>

<p>and </p>

<pre><code>var inst = new MyConstructor();
</code></pre>

<p>Are equivalent. At least if you forget the <code>new</code> keyword you're not going to get burned by having the context object be <code>window</code>.</p>

<h2 id="usingargumentstodryupthesignature">Using <code>arguments</code> to DRY up the signature</h2>

<p>One issue that my colleague <a href="http://farmdev.com/">Kumar</a> raised with this approach is it means you need to update the signature in two places when it changes. Not a huge deal but it would be nice to get away from that.</p>

<p>Immediately I thought of <code>arguments</code>. But you can't use <code>apply</code> and <code>new</code> together to create an instance. </p>

<p>So here's an alternative that deals with that:</p>

<script src="https://gist.github.com/muffinresearch/f056dd4698b4a908b141.js"></script>

<p>Here we create an object with the MyConstructor prototype and then call the constructor using that object as the context. As <code>arguments</code> is used you avoid having 2 places to update the signature.</p>

<p>Here's the output:</p>

<pre><code>["foo1", "bar1"]
["foo2", "bar2"]
["whatever", "bar1"]
["foo2", "bar2"]
true
true
</code></pre>

<p><a href="http://jsbin.com/toguro/2/embed?js,console">Here's that example on JSBin</a> so you can see it in action.</p>

<h2 id="overtoyou">Over to you</h2>

<p>Found a better, more elegant way to do this? Leave a comment with a code example.</p>]]></content:encoded></item><item><title><![CDATA[Taming SlimerJS]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/02/glouton-homeOmbre.png" alt=""></p>

<p>We've been using <a href="http://casperjs.readthedocs.org/en/latest/">CasperJS</a> for <acronym title="End to End">E2E</acronym> testing on Marketplace projects for quite some time. Run alongside unittests, E2E testing allows us to provide coverage for specific UI details and to make sure that users flows operate as expected. It also can be used for writing regression tests for complex interactions.</p>]]></description><link>https://muffinresearch.co.uk/taming-slimerjs/</link><guid isPermaLink="false">0881980c-25c4-4bd4-8203-ce8302515763</guid><category><![CDATA[mozilla]]></category><category><![CDATA[slimerjs]]></category><category><![CDATA[casperjs]]></category><category><![CDATA[phantomjs]]></category><category><![CDATA[testing]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Wed, 18 Feb 2015 13:04:13 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/02/glouton-homeOmbre.png" alt=""></p>

<p>We've been using <a href="http://casperjs.readthedocs.org/en/latest/">CasperJS</a> for <acronym title="End to End">E2E</acronym> testing on Marketplace projects for quite some time. Run alongside unittests, E2E testing allows us to provide coverage for specific UI details and to make sure that users flows operate as expected. It also can be used for writing regression tests for complex interactions.</p>

<p>By default CasperJS uses PhantomJS (headless webkit) as the browser engine that loads the site under test.</p>

<p>Given the audience for the Firefox Marketplace is (by a huge majority) mainly Gecko browsers, we've wanted to add SlimerJS as an engine to our CasperJS test runs for a while.</p>

<p>In theory it's as simple as defining an environment var to say which Firefox you want to use, and then setting a flag to tell casper to use slimer as the engine. However, in practice retrofitting Slimer into our existing Casper/Phantom setup was much more involved and I'm now the proud owner of several Yak hair jumpers as a result of the process to get it working.</p>

<p>In this article I'll list out some of the gotchas we faced along with how we solved them in-case it helps anyone else trying to do the same thing.</p>

<h2 id="requirepathsandglobals">Require Paths and globals</h2>

<p>There's a handy list of the things you need to know about modules in the <a href="http://docs.slimerjs.org/current/differences-with-phantomjs.html#in-the-api">slimer docs</a>.</p>

<p>Here's the list they include:</p>

<ul>
<li>global variables declared in the main script are not accessible in modules loaded with <code>require</code></li>
<li>Modules are completely impervious. They are executed in a truly javascript sandbox</li>
<li>Modules must be files, not folders. node_modules folders are not searched specially (SlimerJS provides <code>require.paths</code>).</li>
</ul>

<p>We had used this pattern throughout our casperJS tests at the top of each test file:</p>

<pre><code class="language-js">var helpers = require('../helpers');  
</code></pre>

<p>The problem that you instantly face using Slimer is that requires need an absolute path. I tried a number of ways to work around it without success. In the end the best solution was to create a helpers-shim to iron out the differences. This is a file that gets injected into the test file. To do this we used the <a href="http://casperjs.readthedocs.org/en/latest/testing.html#options">includes function</a> via <a href="https://github.com/iamchrismiller/grunt-casper#includes">grunt-casper</a>.</p>

<p>An additional problem was that modules are run in a sandbox and have their own context. In order to provider the <code>helpers</code> module with the <code>casper</code> object it was necessary to add it to <code>require.globals</code>.</p>

<p>Our shim looks like this:</p>

<pre><code class="language-js">var v;  
if (require.globals) {  
  // SlimerJS
  require.globals.casper = casper;
  casper.echo('Running under SlimerJS', 'WARN');
  v = slimer.version;
  casper.isSlimer = true;
} else {
  // PhantomJS
  casper.echo('Running under PhantomJS', 'WARN');
  v = phantom.version;
}
casper.echo('Version: ' + v.major + '.' + v.minor + '.' + v.patch);  
/* exported helpers */
var helpers = require(require('fs').absolute('tests/helpers'));  
</code></pre>

<p>One happy benefit of this is that every test now has helpers on it by default. Which saves a bunch of repetition \o/.</p>

<p>Similarly, in our helpers file we had requires for config. We needed to workaround those with more branching. Here's what we needed at the top of helpers.js. You'll see we deal with some config merging manually to get the config we need, thus avoiding the need to workaround requires in the config file too!</p>

<pre><code class="language-js">if (require.globals) {  
  // SlimerJS setup required to workaround require path issues.
  var fs = require('fs');
  require.paths.push(fs.absolute(fs.workingDirectory + '/config/'));
  var _ = require(fs.absolute('node_modules/underscore/underscore'));
  var config = require('default');
  var testConf = require('test');
  _.extend(config, testConf || {});
} else {
  // PhantomJS setup.
  var config = require('../config');
  var _ = require('underscore');
}
</code></pre>

<h2 id="eventorderdifferences">Event order differences</h2>

<p>Previously for phantom tests we used the <code>load.finished</code> event to carry out modifications to the page before the JS loaded. </p>

<p>In Slimer this event fires later than it does in phantomjs. As a result the JS (in the document) was already executing before the setup occured which meant the test setup didn't happen before the code that needed those changes ran.</p>

<p>To fix this I tried alot of the other events to find something that would do the job for both Slimer and Phantom. In the end I used a hack which was to do it when the resource for the main JS file was seen as received.</p>

<p>Using that hook I fired used a custom event in Casper like so:</p>

<pre><code class="language-JS">casper.on('resource.received', function(requestData) {  
 if (requestData.url.indexOf('main.min.js') &gt; -1) {
   casper.emit('mainjs.received');
 }
});
</code></pre>

<p>Hopefully in time the events will have more parity between the two engines so hacks like these aren't necessary.</p>

<h2 id="passingobjectsbetweentheclientandthetest">Passing objects between the client and the test</h2>

<p>We had some tests that setup spys via <a href="http://sinonjs.org/">SinonJS</a> which passed the spy objects from the client context via <code>casper.evaluate</code> (browser) into the test context (node). These spys were then introspected to see if they'd been called.</p>

<p>Under phantom this worked fine. In Slimer it seemed that the movement of objects between contexts made the tests break. In the end these tests were refactored so all the evaluation of the spys occurs in the client context. This resolved that problem.</p>

<h2 id="addinganenvchecktothegruntfile">Adding an env check to the Gruntfile</h2>

<p>As we use grunt it's handy to add a check to make sure the <code>SLIMERJSLAUNCHER</code> env var for slimer is set.</p>

<pre><code class="language-JS">if (!process.env.SLIMERJSLAUNCHER) {  
    grunt.warn('You need to set the env var SLIMERJSLAUNCHER to point ' +
               'at the version of Firefox you want to use\n See http://' +
               'docs.slimerjs.org/current/installation.html#configuring-s' +
               'limerjs for more details\n\n');
}
</code></pre>

<h2 id="sendinganenterkey">Sending an enter key</h2>

<p>Using the following under slimer didn't work for us:</p>

<pre><code class="language-JS">this.sendKeys('.pinbox', casper.page.event.key.Enter);  
</code></pre>

<p>So instead we use a helper function to do a synthetic event with jQuery like so:</p>

<pre><code>function sendEnterKey(selector) {  
  casper.evaluate(function(selector) {
    /*global $ */
    var e = $.Event('keypress');
    e.which = 13;
    e.keyCode = 13;
    $(selector).trigger(e);
  }, selector || 'body');
}
</code></pre>

<p><em>Update: Thursday 19th Feb 2015</em></p>

<p>I received this info:</p>

<blockquote class="twitter-tweet" lang="en"><p><a href="https://twitter.com/muffinresearch">@muffinresearch</a> about your blog post: for key event, use key.Return, not key.Enter, which is a deprecated key code in DOM</p>&mdash; SlimerJS (@slimerjs) <a href="https://twitter.com/slimerjs/status/568315429153869824">February 19, 2015</a></blockquote>  

<p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br></p>

<h2 id="usingcasperbackcausedteststohang">Using casper.back() caused tests to hang.</h2>

<p>For unknown reasons using <code>casper.back()</code> caused tests to hang. To fix this I had to do a hacky <code>casper.open()</code> on the url back would have gone to. There's an open issue about this here: <a href="https://github.com/laurentj/slimerjs/issues/199">casper.back() not working script appears to hang</a>.</p>

<h2 id="exitcodeisalways0">Exit code is always 0</h2>

<p>An eagle-eyed colleagure spotted that the exit code was always 0 via casper when setting SlimerJS up for the marketplace frontend tests. Fortunately the patch for this is coming soon in <a href="https://github.com/laurentj/slimerjs/commit/6c9537b06b625edf539bcf13e85147eb908b2462">0.10</a>. The workaround for this today is to use the <a href="http://download.slimerjs.org/nightlies/latest-slimerjs-master/slimerjs-0.10.0pre.zip">0.10pre version</a>. Hattip <a href="https://twitter.com/markstrmr">@markstrmr</a></p>

<h2 id="thetravisyml">The travis.yml</h2>

<p>Getting this running under travis was quite simple. Here's what our file looks like (Note: Using env vars for versions makes doing updates much easier in the future):</p>

<p><script src="https://gist.github.com/muffinresearch/b41d8413c1624de2ebd0.js"></script><br></p>

<p>Yes that is Firefox 18! Gecko18 is the oldest version we still support as FFOS 1.x was based on Gecko 18. As such it's a good Canary for making sure we don't use features that are too new for that Gecko version.</p>

<p>In time I'd like to look at using the env setting in travis and expanding our testing to cover multiple gecko versions for even greater coverage.</p>]]></content:encoded></item><item><title><![CDATA[Tips for getting the most out of irc]]></title><description><![CDATA[<p>Having been remoting for the best part of 5 years I've come to use <a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat">irc</a> alot as a primary means of communication for work.</p>

<p>Along the way I've learnt a few things that made a difference to how I use irc and allowed me to get the most out of</p>]]></description><link>https://muffinresearch.co.uk/tips-for-getting-the-most-out-of-irc/</link><guid isPermaLink="false">32d2197a-2f58-4516-9a38-dde3ad6f4e23</guid><category><![CDATA[mozilla]]></category><category><![CDATA[irc]]></category><category><![CDATA[productivity]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Wed, 11 Feb 2015 10:33:49 GMT</pubDate><content:encoded><![CDATA[<p>Having been remoting for the best part of 5 years I've come to use <a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat">irc</a> alot as a primary means of communication for work.</p>

<p>Along the way I've learnt a few things that made a difference to how I use irc and allowed me to get the most out of it.</p>

<h2 id="beonircifitsapartoftheculture">Be on irc if it's a part of the culture</h2>

<p>If your role is non-technical it can be easy to not take part in irc e.g. I've heard in the past people dismiss as "just for geeks" :). However, if irc is a big part of how the company communicates, it's important for everyone to get involved. Especially if remoties form any part of the work force they'll appreciate you being there.</p>

<p>irc is easy to learn and people will generally be very happy to show new people the ropes. </p>

<p>Here's a great wiki page with a ton of information on how to <a href="https://wiki.mozilla.org/IRC#Getting_Startedhttps://wiki.mozilla.org/IRC#Getting_Started">get started with irc</a>.</p>

<h2 id="stayconnectedwhilstoffline">Stay connected whilst offline</h2>

<p>If you're working with people that span timezones chances are there are going to be times when you need to talk to them and they're not awake and vice versa. </p>

<p>When you shutdown or put your computer to sleep you're not available on irc the moment your typical irc client disconnects from the server.</p>

<p>This means that if someone wants to tell you something they've got to wait till you're online or drop you an email.</p>

<p>An irc <a href="http://en.wikipedia.org/wiki/BNC_%28software%29">bouncer</a> or server-based client allows you to stay connected permanently regardless of when you are offline.</p>

<p>Typically this means that when you reconnect the next day the backlog from when you were offline is replayed, thus any questions or messages people are sending you you'll see.</p>

<p>If you're not a developer and you don't want to run your own bouncer then you could always look at a hosted solution like <a href="https://www.irccloud.com/">irccloud</a> which is a web client it costs a minimal amount per-month and you might even find your company can cover the cost.</p>

<p>If you're a developer then take a look at something like <a href="https://wiki.linaro.org/Resources/HowTo/BIP">this bip howto</a> or checkout this <a href="http://en.wikipedia.org/wiki/BNC_%28software%29">list of bouncers</a>.</p>

<h2 id="registeryournickname">Register your nickname</h2>

<p>It's always a good idea to register your nick to stop someone coming along and taking your name. Especially if you want to be reliably available using a specific nickname. <a href="https://wiki.mozilla.org/IRC#Register_your_nickname">See this howto for how to set it up</a>.</p>

<h2 id="highlightpeopleyouretalkingto">Highlight people you're talking to</h2>

<p>If you know who you expect to get an answer to a question from it's a good idea to highlight them when talking to them.</p>

<p>So instead of:</p>

<pre><code>[02:00:39] &lt;Yondu&gt; I can't seem to reproduce bug 123456
</code></pre>

<p>try this:</p>

<pre><code>[02:00:39] &lt;Yondu&gt; muffinresearch: I can't seem to reproduce bug 123456
</code></pre>

<p>In this example because I've been mentioned by name I'll get notified of the question. This will also work if I'm replaying a bouncer backlog.</p>

<p>Most irc clients have auto completion for irc nicknames. This will also tell you if that person is connected. If they're not on the channel they won't be able to ever get the message (apart from looking at channel logs (unlikely)).</p>

<h2 id="configureadditionalhighlights">Configure additional highlights</h2>

<p>Most clients have an option to allow you to be highlighted for more than just your nick. I tend to add things like my username for bugzilla so if someone links a bug and a bot displays the bug and I'm assigned I'll get highlighted.</p>

<p>As always choose carefully and don't have highlight set up for any words that will come up often or it will drive you crazy!</p>

<h2 id="askquestionsatthestart">Ask questions at the start</h2>

<p>Sometimes people will do this kind of thing on irc:</p>

<pre><code>[02:00:39] &lt;Yondu&gt; muffinresearch: ping
...
[09:01:21] &lt;muffinresearch&gt; Yondu: pong
</code></pre>

<p>And now I have to wait for the question.</p>

<p>Here's a much better way</p>

<pre><code>[02:00:39] &lt;Yondu&gt; muffinresearch: ping, how do I do x,y and z.
...
[09:01:21] &lt;muffinresearch&gt; Yondu: pong - ah you just need to do this, that and the other.
</code></pre>

<p>Now when Yondu's next online the answer is already waiting. You might find asking questions to people in this way is not the best fit for irc which brings us onto the next point.</p>

<h2 id="useprivatemessagesonlywhenneeded">Use private messages only when needed</h2>

<p><a href="https://wiki.mozilla.org/IRC#Start_a_private_message">Private messages</a> are handy if you need to speak to someone in private (outside of a channel). However if you're asking someone a question PM'ing them is not the best solution unless it's something that you don't want in a public channel.</p>

<p>If you have a question it's best to ask out in the open. This way everyone gets to see the question and hopefully an answer too. </p>

<p>A trick you can use if on the receiving end of someone using PMs for something that should be public is reply to it from a relevant channel to pull the conversation into a public place. (Hattip <a href="https://twitter.com/beuno">@beuno</a> for this one)</p>

<h2 id="knowwhenircisntthebestmedium">Know when irc isn't the best medium</h2>

<p>If you want to ask a question and don't need a reply immediately then using email can be a better solution - I'd generally take irc to be a more reliable form of communication than relying on using irc for an async conversation.</p>

<p>Another aspect to this is being mindful of interrupting a developer. For an example <a href="http://heeris.id.au/2013/this-is-why-you-shouldnt-interrupt-a-programmer/">see this brilliant comic by Jason Heeris</a>. Personally I'm OK with being interupted as long as it's not something that if someone had spent two seconds to search for they would have found it for themselves. A culture where people are afraid to ask questions is not what you want so tread lightly on this point.</p>

<h2 id="markyourselfasawayifyouare">Mark yourself as away if you are</h2>

<p>If you're not at your desk you can use away to tell people you're not around like so:</p>

<pre><code>/away lunch
</code></pre>

<p>Good clients will usually indicate away status. </p>

<p>Sometime people change their nicks to show they're away. This is OK, but it does create noise in the channel due to the notification that the user has changed their nick. So most people prefer the use of away.</p>

<p>Remember, if you set an away status you'll want to clear it when you're back.</p>

<pre><code>/away 
</code></pre>

<p>Is enough to do that. This is especially important when using a bouncer. You want other people to be able to highlight you when you're away but you also want to set expectations so they know you're not around.</p>

<p>I personally do something else at the start and end of each day. I always say good morning when I start. And I always end the day with</p>

<pre><code>/me eods
</code></pre>

<p>This does 2 things. It tells people I'm gone for the day and a side benefit is I can always search logs and work out what hours I'm keeping by looking for the "eods" alongside my nick.</p>

<h2 id="setuplogging">Setup logging</h2>

<p>If you're using irc make sure you enable logs. They can be really useful if you need to recall a previous conversation.</p>

<h2 id="dontjudgepeoplebytheirircpersona">Don't judge people by their irc persona.</h2>

<p>If you've only talked to someone on irc, it's important to note that how they come across on irc may not be representative of who they are. I've worked with people before who seemed very terse on irc. I sometimes wondered if it was just me. Then when meeting them face to face it all made sense it was part of their character and we actually got on brilliantly. </p>

<p>This is why for remote people getting together face to face from time to time is worth it's weight in gold.</p>

<h2 id="usenontextbasedcomms">Use non text-based comms</h2>

<p>irc is a great tool. It can also be a difficult medium to use if you're trying to convey lots of information.</p>

<p>All the companies I've worked at remotely tended to have a solution to this problem by providing either audio or video chat solutions. Personally I like using video chats for some face to face communication, this way you can probably convey far more information.</p>

<h2 id="usepastebins">Use pastebins</h2>

<p>If you need to show someone a traceback of a snippet of code. Never copy it directly into irc. A large chunk of text will tie up the channel for a while as it gets added line by line.</p>

<p>Instead use a pastebin service like <a href="https://dpaste.de/">dpaste.de</a> and drop the link in the channel.</p>

<p>It's always a good idea to check that you're not posting sensitive content before you save it.</p>

<h2 id="staysafe">Stay safe</h2>

<p>As above - don't paste sensitive things into irc. Be aware if the channel you're conversing in is private or public. Generally if you always assume you're speaking in a public channel you won't go far wrong.</p>

<p>If you do accidentally paste something like a password into a channel be sure to change it!</p>

<p>Always use secure connections to irc services where available.</p>

<h2 id="turnoffautomaticimagedisplay">Turn off automatic image display</h2>

<p>My irc client supports automatically showing images. I thought this was brilliant until someone started dropping really unsavoury images into a public channel. Even if this hasn't yet happened to you I'd recommend turning it off before you get a nasty surprise.</p>

<h2 id="overtoyou">Over to you</h2>

<p>What other tips do you have?</p>]]></content:encoded></item><item><title><![CDATA[Firefox sees Charles Proxy CA certificate as expired]]></title><description><![CDATA[<p><strong>Update: This is no longer relevant the issue has been fixed with a Charles update.</strong></p>

<p>Using current versions of Firefox with <a href="http://www.charlesproxy.com/">Charles Proxy</a> you might run into a problem where Firefox see Charles' own CA certificate as expired when you try to install it.</p>

<p>After talking to some colleagues at</p>]]></description><link>https://muffinresearch.co.uk/firefox-sees-charles-proxy-ca-certificate-as-expired/</link><guid isPermaLink="false">e3cdd27c-a5ad-408e-8d3c-681f23fd7c5e</guid><category><![CDATA[mozilla]]></category><category><![CDATA[Firefox]]></category><category><![CDATA[Charles Proxy]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Fri, 06 Feb 2015 11:23:22 GMT</pubDate><content:encoded><![CDATA[<p><strong>Update: This is no longer relevant the issue has been fixed with a Charles update.</strong></p>

<p>Using current versions of Firefox with <a href="http://www.charlesproxy.com/">Charles Proxy</a> you might run into a problem where Firefox see Charles' own CA certificate as expired when you try to install it.</p>

<p>After talking to some colleagues at Mozilla the cause is due to the way that Firefox validates certs. The more recent versions of Firefox only allow certs with start dates after the unix epoch (1st January 1970). As the Charles CA cert has a start year of 1899 it's seen as expired when you try to import it.</p>

<p>The easiest way to workaround it is to <a href="https://muffinresearch.co.uk/proxying-connections-from-ffos/#generateyourowncacertforcharles">generate your own CA certificate</a> and use that instead.</p>

<p>I've already filed a bug report with the author of Charles and will update this post with any updates in due course.</p>]]></content:encoded></item><item><title><![CDATA[Proxying SSL connections using Firefox Android]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/Feb/firefox_logo-only_RGB-sm.jpg" alt=""></p>

<p>Having dealt with <a href="https://muffinresearch.co.uk/proxying-connections-from-ffos/">enabling Proxying on FFOS devices</a> I recently needed to proxy code for Firefox for Android too. I'd recommend reading that post for all the background info.</p>

<p>Fortunately the process for adding the CA cert your proxy uses to the certs db on Firefox Android is identical to</p>]]></description><link>https://muffinresearch.co.uk/proxying-ssl-connections-using-ff-android/</link><guid isPermaLink="false">ff9ff27b-749a-4fb8-90bb-a8d7753f09e1</guid><category><![CDATA[mozilla]]></category><category><![CDATA[Charles Proxy]]></category><category><![CDATA[Firefox Android]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Thu, 05 Feb 2015 19:58:45 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2015/Feb/firefox_logo-only_RGB-sm.jpg" alt=""></p>

<p>Having dealt with <a href="https://muffinresearch.co.uk/proxying-connections-from-ffos/">enabling Proxying on FFOS devices</a> I recently needed to proxy code for Firefox for Android too. I'd recommend reading that post for all the background info.</p>

<p>Fortunately the process for adding the CA cert your proxy uses to the certs db on Firefox Android is identical to how you do it for FFOS.</p>

<p><em>Note: As always take care and carry out these steps at your own risk</em></p>

<h2 id="why">Why?</h2>

<p>Proxying SSL connections is really useful for debugging and development. I often use proxying to rewrite JS with my own built JS files so I can test a bugfix with real data. This can be especially helpful on devices where pointing at local development environments can take time.</p>

<p>SSL proxying is needed otherwise you can't de-crypt the request to do something useful with it.</p>

<p>Once you have the necessary rewrite rules setup in <a href="http://www.charlesproxy.com/">Charles</a> and as long as you can use the proxy on your user-agent (Phone/Desktop browser etc), switching out dev/stage/prod JS with your own is trivial.</p>

<p>For more info on a Charles Proxy specific setup to rewrite files see: <a href="https://muffinresearch.co.uk/using-charles-proxy-to-debug-live-code/">Using Charles proxy to debug live code</a></p>

<h2 id="requirements">Requirements</h2>

<p>The pre-requisite steps are as follows:</p>

<ul>
<li>You've got adb installed </li>
<li>You know how to set-up the proxy settings for your android phone.</li>
<li>You have a rooted phone android phone with Firefox Android installed.</li>
<li>You've generated a cert for your proxy. (<a href="https://muffinresearch.co.uk/proxying-connections-from-ffos/#generateyourowncacertforcharles">If not you can read how to do that here</a>)</li>
<li>You've got <code>certutil</code> installed from <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Sources_Building_Testing">nss</a>. Be careful if you use homebrew to install it. <a href="https://muffinresearch.co.uk/firefox-fixing-sync-encountered-an-error-on-osx/">This can break sync</a>.</li>
</ul>

<h2 id="findingtheprofile">Finding the profile</h2>

<p>First I use <code>adb shell</code> to get a shell and then type <code>su</code> to get root. </p>

<pre><code>adb shell
shell@m0:/ $ su
root@m0:/ #
</code></pre>

<p>Now to modify the db you need to find your profile.</p>

<p>For FF Android Nightly this will be:</p>

<pre><code>/data/data/org.mozilla.fennec/files/mozilla
</code></pre>

<p>and for FF Android it will be in:</p>

<pre><code>/data/data/org.mozilla.firefox/files/mozilla
</code></pre>

<p>And you'll be looking for a file that ends with <code>.default</code></p>

<h2 id="movingthecertfiles">Moving the cert files</h2>

<p>Once you have the paths. You'll want to move the <code>cert9.db</code> and <code>key4.db</code> onto the sdcard so you can more easily pull them onto your machine.</p>

<p>e.g:</p>

<pre><code>cp /data/data/org.mozilla.fennec/files/mozilla/fkhfkjsh.default/cert9.db /sdcard/cert/cert9.db
cp /data/data/org.mozilla.fennec/files/mozilla/fkhfkjsh.default/key4.db /sdcard/cert/key4.db
</code></pre>

<p>Now you can grab them from another terminal tab:</p>

<pre><code>mkdir ffa-certs &amp;&amp; cd ffa-certs
adb pull /sdcard/certs/cert9.db
adb pull /sdcard/certs/key4.db
</code></pre>

<p>Now back them up in-case you want to restore them or something goes awry.</p>

<pre><code>cp cert9.db{,.bck}
cp key4.db{,.bck}
</code></pre>

<h2 id="addingyourcatothecertdb">Adding your CA to the cert db</h2>

<p>Finally add your cert. I'm using the same CA cert I generated for Charles. So that's the following:</p>

<pre><code># Hit enter to remove the password
certutil -W -d sql:. 
# Add the cert
certutil -A -n 'Charles Custom Cert' -i /usr/local/CharlesCA/certs/ca_cert.pem -t 'TC,,' -d sql:.
# Check it validates
certutil -V -u 'V' -n 'Charles Custom Cert' -d sql:. 
</code></pre>

<h2 id="pushingcertsontothedevice">Pushing certs onto the device</h2>

<p>Now lets throw the certs db back on the device:</p>

<pre><code> adb push cert9.db /sdcard/certs/cert9.db
 adb push key4.db /sdcard/certs/key4.db
</code></pre>

<p>And then back on your root adb shell you had earlier:</p>

<pre><code>cp /sdcard/cert/cert9.db /data/data/org.mozilla.fennec/files/mozilla/fkhfkjsh.default/cert9.db 
cp /sdcard/cert/key4.db /data/data/org.mozilla.fennec/files/mozilla/fkhfkjsh.default/key4.db
</code></pre>

<p>Assuming you've pointed your network (wifi) connection at the proxy you should be good to go.</p>

<p>As always don't forget to turn off the proxy when you're not using it.</p>]]></content:encoded></item><item><title><![CDATA[Docker and dependencies]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2014/Aug/large_h-trans.png" alt=""></p>

<p>Last week I posed this question on Twitter:</p>

<blockquote class="twitter-tweet" lang="en"><p>Docker experts. How do you deal with non-os deps e.g. pip/npm/bower and avoiding cache-busting the dep install layer on dep changes? <a href="https://twitter.com/hashtag/docker?src=hash">#docker</a></p>&mdash; Stuart Colville (@muffinresearch) <a href="https://twitter.com/muffinresearch/status/561221632925396992">January 30, 2015</a></blockquote>

<p>Unfortunately Twitter isn't the best medium to provide the necessary</p>]]></description><link>https://muffinresearch.co.uk/docker-and-dependencies/</link><guid isPermaLink="false">514249f9-66ed-4eea-bcf5-bcb1b9c33543</guid><category><![CDATA[docker]]></category><category><![CDATA[mozilla]]></category><category><![CDATA[marketplace]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Mon, 02 Feb 2015 10:42:59 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2014/Aug/large_h-trans.png" alt=""></p>

<p>Last week I posed this question on Twitter:</p>

<blockquote class="twitter-tweet" lang="en"><p>Docker experts. How do you deal with non-os deps e.g. pip/npm/bower and avoiding cache-busting the dep install layer on dep changes? <a href="https://twitter.com/hashtag/docker?src=hash">#docker</a></p>&mdash; Stuart Colville (@muffinresearch) <a href="https://twitter.com/muffinresearch/status/561221632925396992">January 30, 2015</a></blockquote>

<p>Unfortunately Twitter isn't the best medium to provide the necessary context so here's a bit more info on what I meant.</p>

<p>One of the problems we've seen using <a href="https://www.docker.com">docker</a> to build out a development environment is that it's required a lot of working around limitations of the environment.  Dependencies aren't the only problem but they're proven to be something of a pain.</p>

<h2 id="theproblem">The problem</h2>

<p><strong><em>Dep changes require the dependency installation to be run from scratch.</em></strong></p>

<p>The FFOS marketplace as an app comprises lots of services that are loosely coupled. This means we can run separate containers and use links to tie things together. We also have a lot of modular code and libs that are not OS packages. </p>

<p>We specify our non-OS packaged deps using requirements.txt files for Python and package.json for nodejs modules. We then add those files via the Dockerfile using an <code>ADD</code> instruction e.g:</p>

<pre><code>ADD requirements /pip/requirements
</code></pre>

<p>Next the deps are installed:</p>

<pre><code>RUN pip install -r /pip/requirements/dev.txt
</code></pre>

<p>Now due to how the <acronym title="Another Union File System"><a href="https://en.wikipedia.org/wiki/Aufs">AUFS</a></acronym> works the <code>ADD</code> is cached so if the requirements.txt file stays the same re-building that part is a no-op. Great! </p>

<p>But, when we do bump a package version or add a new dependency the cache is invalidated and the entire installation of deps is re-run from scratch.</p>

<p>As we have quite a large collection of deps this can a) take a long time and b) can break if the package repository is busy/down/having a bad day.</p>

<h2 id="thegoal">The goal</h2>

<p>We'd like a new dep or a dep change to not require all the network access and time it takes to re-install all the dependencies from scratch.</p>

<p>After-all this is a development environment and having to build the world after some dep changes/version bumps gets in the way.</p>

<h2 id="alternatives">Alternatives</h2>

<p>I've been thinking about some alternatives but nothing yet has seemed particularly attractive.</p>

<h3 id="proxyingnpmpypietc">Proxying npm/pypi etc</h3>

<p>One possibility would be to use a proxy to cache the package downloads to minimise the network overhead. This would help but there's a few nits. It's another moving part. You still need to pull the packages and install them. So this would alleviate the network part of the problem but that's really only half the problem.</p>

<h3 id="cachingthedepsonthefilesystem">Caching the deps on the filesystem</h3>

<p>I looked to see if caching the deps would make a difference. Unfortunately persistent storage via volumes isn't any use at build time. As volumes are only added at run-time you can't utilise the cache when the deps installation is re-run.</p>

<h3 id="externalizingthedeps">Externalizing the deps</h3>

<p>One more recent thoughts I had was whether we could move the non-OS packaged deps out of the build-step and into run-time. This way we could use a data-only container for the deps and if the deps change you'll only pull in what's changed.</p>

<p>The downside is that this feels like it's starting to defeat the point of a container-based approach.</p>

<h3 id="offlinebuilds">Offline builds</h3>

<p><a href="http://mckay.pub">Andy Mckay</a> has been trying out using automated hub builds as the trees are updated. This works quite well but there's still a few nits. Bumps in deps require downloading new layers to images. Larger files instead of lots of packages is a step in the right direction but it still feels like it gets in the way. We also need a good way to keep builds aligned with the src revision otherwise you might have the wrong deps for the branches src revision.</p>

<h2 id="whatseveryoneelsedoing">What's everyone else doing?</h2>

<p>I'm sure we're not the only people trying to do this. How do you overcome these issues in your use of Docker? Or do you just accept the hit in terms of builds taking a long time? Have you found some clever way to manage deps so devs can get up to date quickly without getting buried in a ton of docker-shaped yaks?</p>

<h2 id="coulddockersolvethis">Could Docker solve this?</h2>

<p>Maybe there could be a way to allow certain paths to not be cache-busted? E.g. could we have a way to allow the pip cache to remain intact so that it can be used when the deps installation is run when the requirements.txt changes?</p>]]></content:encoded></item><item><title><![CDATA[Proxying connections from FFOS with Charles]]></title><description><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2014/Nov/charles-sm-1.png" alt=""></p>

<p>After my post on <a href="https://muffinresearch.co.uk/using-charles-proxy-to-debug-live-code/">Live debugging with Charles</a>, <a href="http://nickdesaulniers.github.io/">Nick Desaulniers</a> asked if I knew if it was possible to proxy device traffic via Charles. I didn't, but I did know that if it was possible it was sure to come in handy.</p>

<p><em>10 freshly shaved yaks later…</em></p>

<p>This post details</p>]]></description><link>https://muffinresearch.co.uk/proxying-connections-from-ffos/</link><guid isPermaLink="false">a7e56de0-ae49-4479-9b22-7543f54bd7d6</guid><category><![CDATA[firefoxos]]></category><category><![CDATA[FFOS]]></category><category><![CDATA[SSL]]></category><category><![CDATA[mozilla]]></category><category><![CDATA[Firefox]]></category><category><![CDATA[Charles Proxy]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Thu, 13 Nov 2014 19:37:04 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://muffinresearch.co.uk/content/images/2014/Nov/charles-sm-1.png" alt=""></p>

<p>After my post on <a href="https://muffinresearch.co.uk/using-charles-proxy-to-debug-live-code/">Live debugging with Charles</a>, <a href="http://nickdesaulniers.github.io/">Nick Desaulniers</a> asked if I knew if it was possible to proxy device traffic via Charles. I didn't, but I did know that if it was possible it was sure to come in handy.</p>

<p><em>10 freshly shaved yaks later…</em></p>

<p>This post details getting FFOS (I'm using a flame with FFOS 2.1) to use <a href="http://www.charlesproxy.com/">Charles Proxy</a> for all requests so we can debug requests on the phone. I'm using OSX for the rest of the commands etc, but this should work similarly on Linux just be prepared to changes a few paths here and there as required. You'll need the usual <code>adb</code> etc before you start.</p>

<p><strong>As always, respect the yaks and run these steps at your own risk.</strong></p>

<h2 id="settingupffostouseaproxy">Setting up FFOS to use a proxy</h2>

<p>First you need to know your local network ip address. You'll typically be running all this on wifi. The expectation is that your phone and computer are running on the same wifi network.</p>

<p>This command should give you the primary interface (but will depend on that being the only interface try <code>en1</code> if that doesn't provide what you expect.)</p>

<pre><code>ipconfig getifaddr en0 
</code></pre>

<p>If in doubt you can always check network prefs via your system settings for your OS.</p>

<p>Once you know that you can set up the prefs file for your firefox OS device.</p>

<p>The proxy prefs are as follows (It goes without saying you'll need to replace <code>192.168.0.2</code> with whatever your local ip is. Change the ports if your charles port is not <code>8888</code>.</p>

<pre><code>pref("network.proxy.backup.ftp", "192.168.0.2");
pref("network.proxy.backup.ftp_port", 8888);
pref("network.proxy.backup.socks", "192.168.0.2");
pref("network.proxy.backup.socks_port", 8888);
pref("network.proxy.backup.ssl", "192.168.0.2");
pref("network.proxy.backup.ssl_port", 8888);
pref("network.proxy.ftp", "192.168.0.2");
pref("network.proxy.ftp_port", 8888);
pref("network.proxy.http", "192.168.0.2");
pref("network.proxy.http_port", 8888);
pref("network.proxy.no_proxies_on", "");
pref("network.proxy.share_proxy_settings", true);
pref("network.proxy.socks", "192.168.0.2");
pref("network.proxy.socks_port", 8888);
pref("network.proxy.ssl", "192.168.0.2");
pref("network.proxy.ssl_port", 8888);
pref("network.proxy.type", 1);
</code></pre>

<p>If you're already using your own user prefs then append these lines to the file. If not create a file called <code>custom-prefs.js</code> and then push it onto your device:</p>

<pre><code>adb push custom-prefs.js /data/local/user.js
</code></pre>

<p>Now restart:</p>

<pre><code>adb reboot
</code></pre>

<p>This should get the device talking to charles. However at this point, anything that uses SSL you won't be able to see the requests for.</p>

<p>Before you can do that, first you're going to need to generate your own cert for charles. It seems that recent Firefox versions see charles' CA cert as expired which can be a big red-herring to getting this working. </p>

<p><em>Update 29th November 2014</em></p>

<p><em>After talking to some colleagues the cause of the expired certificate is due to the way that Firefox validates certs. The more recent versions of Firefox only allow certs with start dates after the unix epoch (1st Jan 1970). As the Charles CA cert has a start year of 1899 it's seen as expired.</em></p>

<h2 id="generateyourowncacertforcharles">Generate your own CA cert for charles</h2>

<p>It's a good idea to make your own CA cert for Charles - so this step isn't so bad in the long run. As long as you keep your cert and keys safe no-one can abuse it.</p>

<p>There's an excellent post with both the rationale and the low-down on how to generate your own cert here: <a href="http://0x74696d.com/posts/CharlesSSL">Securing Charles Proxy with a Personal CA</a> </p>

<p>Note: This post assumes openssl.conf is under <code>/opt/local/etc/openssl</code> which it will be if you've installed openssl with homebrew e.g <code>brew install openssl</code>.</p>

<p>I'll reproduce the broad strokes here to keep all the instructions relevant to this post in one place:</p>

<pre><code># Setup a directory to hold this info.
mkdir -p /usr/local/CharlesCA
cd /usr/local/CharlesCA
mkdir certs private newcerts
echo 01 &gt; serial
touch index.txt

# Next create the CA cert
openssl req -new -x509 -days 3650 -extensions v3_ca \
-keyout private/ca_key.pem -out certs/ca_cert.pem \
-config /opt/local/etc/openssl/openssl.cnf
</code></pre>

<p>At this point you'll need to set a passphrase and enter some basic info. Charles will ask for this passphrase when it needs to.</p>

<p>Next we are going to run a command to generate the PKCS12 format that charles expects.</p>

<pre><code>openssl pkcs12 -export -out ca_cert.pfx -inkey \
private/ca_key.pem -in certs/ca_cert.pem
</code></pre>

<p>So the files we get from this process are:</p>

<ul>
<li>ca_cert.pfx - this is what we need to point charles at.</li>
<li>ca_cert.pem - this is the ca certificate to add to clients</li>
<li>ca_key.pem - this is the key (keep this safe).</li>
</ul>

<p>Now we have this we need to point charles at the <code>ca_cert.pfx</code> ca cert we just generated. When we do this Charles will ask for the passphrase. </p>

<p><img src="https://muffinresearch.co.uk/content/images/2014/Nov/Proxy_Settings-1.png" alt=""></p>

<p>Next it's a good idea to test out running Firefox with charles and makes sure SSL proxying is working. To make that happen you'll need to enable SSL proxying for a host of your choice. See above for an example.</p>

<p>To make firefox work with Charles we'll need to add the <code>ca_cert.pem</code> into firefox. I just use the <code>Firefox -&gt; Preferences -&gt; Advances -&gt; Certificates</code> and the click <code>View certificates</code> and then <code>import</code>. Find the <code>ca_cert.pem</code> generated before and import that and check <code>This certificate can identify websites</code>.</p>

<p>Next try and view a site using the ssl host you set up. You should be able to look at responses.</p>

<h2 id="addingthecustomcatoffos">Adding the custom CA to FFOS</h2>

<p>Assuming that went well we're ready to add the custom cert to FFOS. There's an interface under the device's wifi settings that allows the import of certs (if they're pushed to /sdcard/downloads first) but this didn't seem to work for me. It might just be that you can't set trust correctly (there's no interface for that) via this route,  which stops it working.</p>

<p>To add our own cert we'll need to use the <code>nss</code> tools. In particular <code>certutil</code> is the command we'll use to add a cert to your device.</p>

<p>You can install the nss-tools on OSX with <code>brew install nss</code> however be aware this might cause havoc with Firefox sync <a href="https://muffinresearch.co.uk/firefox-fixing-sync-encountered-an-error-on-osx/">see my post on this issue</a>. If that's the case you can build the nss tools yourself (I'll leave that as a yak to shave for the reader).</p>

<p>First we'll run some commands to get the existing <code>cert9.db</code> and <code>key4.db</code> off the device.</p>

<p>Here's a little script that will pull the certs into the same dir (or you can just run the commands one at a time if you prefer).</p>

<pre><code>#!/usr/bin/env bash

adb wait-for-device
PROF_DIR=$(adb shell echo /data/b2g/mozilla/*.default | tr -d '\r')

echo $PROF_DIR

echo Copying ${PROF_DIR}/cert9.db
adb pull ${PROF_DIR}/cert9.db .

echo Copying ${PROF_DIR}/key4.db
adb pull ${PROF_DIR}/key4.db .
</code></pre>

<p>To back them up the first time you can run:</p>

<pre><code>cp cert9.db{,.bck}
cp key4.db{,.bck}
</code></pre>

<p>This will give you a backup just in-case.</p>

<p>Next we need to clear the existing password, so we don't get errors trying to add our CA cert.</p>

<pre><code>certutil -W -d sql:.
</code></pre>

<p>When the prompts appear just hit enter twice.</p>

<p>Now let's add our <code>ca_cert.pem</code> file.</p>

<pre><code>certutil -A -n 'Charles Custom Cert' -i /usr/local/CharlesCA/certs/ca_cert.pem -t 'TC,,' -d sql:.
</code></pre>

<p>This assumes the cert file is in the location as per the custom CA generation steps above.</p>

<p>Now the next step is to validate that the cert added is good for our purposes:</p>

<pre><code>certutil -V -u 'V' -n 'Charles Custom Cert' -d sql:. 
</code></pre>

<p>You're looking for output like so:</p>

<pre><code>certutil: certificate is valid
</code></pre>

<p>If that's good then you're all set.</p>

<p>The final step is to push back the files:</p>

<p>Assuming you're in the same terminal session you can use the following commands. </p>

<pre><code>adb push cert9.db ${PROF_DIR}
adb push key4.db ${PROF_DIR}
adb reboot
</code></pre>

<p>If not run this again first and then re-run the push commands above:</p>

<pre><code>adb wait-for-device
PROF_DIR=$(adb shell echo /data/b2g/mozilla/*.default | tr -d '\r')
</code></pre>

<p>Next try hitting the same URL you verified that SSL proxying worked for with Firefox and you should see that FFOS is now both using the proxy <em>and</em> SSL proxying is taking place on the host you specified.</p>

<p>The traffic should show up with the files under the host like so:</p>

<p><img src="https://muffinresearch.co.uk/content/images/2014/Nov/Charles_3_9_3_-_Session_1__.png" alt=""></p>

<h2 id="turningofftheproxy">Turning off the proxy</h2>

<p>When you're done with the proxy remember to remove the prefs. Hopefully at some point they'll be a way to turn this on or off from the device settings.</p>

<h2 id="notesandreferences">Notes and references</h2>

<p><code>mozTCPSocket</code> requests don't seem to work via the proxy if they require SSL. You'll see bad_certificate in charles. I don't know of a workaround for this presently (so I'd suggest avoiding proxying hosts that use that).</p>

<p>This post wouldn't have been possible without the following - my thanks goes to the authors for sharing their wisdom:</p>

<ul>
<li><a href="http://wiki.mozfr.org/Adding_CA_to_FirefoxOS">Adding CA to FirefoxOS</a></li>
<li><a href="http://0x74696d.com/posts/CharlesSSL/">Securing Charles Proxy with a Personal CA</a></li>
<li><a href="https://developer.mozilla.org/en-US/Firefox_OS/Debugging/Intercepting_traffic_using_a_proxy">Intercepting Firefox OS traffic using a proxy</a></li>
</ul>

<h2 id="overtoyou">Over to you</h2>

<p>It's likely the steps to do this might get shorter in due course or short-cuts will be found. If you find a better way to do any of this or have extra OS specific notes or additional useful references please let me know in the comments.</p>

<p>Also if you manage to shave all the yaks and get this working based on these instructions please let me know too.</p>]]></content:encoded></item><item><title><![CDATA[Firefox: Fixing "sync encountered an error…" on OSX]]></title><description><![CDATA[<p>I was trying to get sync up and running between multiple FF versions I kept getting a message saying: </p>

<pre><code>sync encountered an error while syncing: Unknown error.
</code></pre>

<p>Sync has logs in <a href="about:sync-log">about:sync-log</a></p>

<p>I was seeing this:</p>

<pre><code>Crypto check failed: [Exception... "PK11_GenrateRandom failed"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location:</code></pre>]]></description><link>https://muffinresearch.co.uk/firefox-fixing-sync-encountered-an-error-on-osx/</link><guid isPermaLink="false">15c460c3-a0f6-4699-9911-c6d61d42e745</guid><category><![CDATA[mozilla]]></category><category><![CDATA[Firefox]]></category><category><![CDATA[nss]]></category><category><![CDATA[sync]]></category><dc:creator><![CDATA[Stuart Colville]]></dc:creator><pubDate>Wed, 12 Nov 2014 12:30:40 GMT</pubDate><content:encoded><![CDATA[<p>I was trying to get sync up and running between multiple FF versions I kept getting a message saying: </p>

<pre><code>sync encountered an error while syncing: Unknown error.
</code></pre>

<p>Sync has logs in <a href="about:sync-log">about:sync-log</a></p>

<p>I was seeing this:</p>

<pre><code>Crypto check failed: [Exception... "PK11_GenrateRandom failed"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: resource://gre/modules/services-crypto/WeaveCrypto.js :: WeaveCrypto.prototype.generateRandomBytes :: line 550"  data: no]
</code></pre>

<p>Looking for a fix I found comment 33 in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1034979#c33">bug 1034979</a></p>

<blockquote>
  <p>|brew uninstall nss| and restart Fx seems to fix the problem for me.</p>
</blockquote>

<p>And sure enough removing the brew installed nss package did the trick.</p>]]></content:encoded></item></channel></rss>