Remote Debugging Firefox OS with Weinre

NOTE: since this article was published, the Mozilla developer tools team has released the App Manager, a much more effective way to remotely debug Firefox OS apps. To find out more, read Using the App Manager on MDN.

If you’ve wanted to contribute to Gaia, or have been writing a webapp for Firefox OS, one of the pain points you probably ran into, when using either B2G desktop or testing on a device, is the lack of developer tools to inspect and debug your HTML, CSS and JavaScript.

Currently we have two tracking bugs, go ahead an vote on them to bump their priority, to track the work going into developing a native remote inspector and style editor for Firefox OS but, I have some pretty exciting news. You can have access to a remote debugger today.

And how is this possible I hear you ask? Well, one word: Weinre. Weinre is a project of the Apache Foundation and stands for WEb INspector REmote and is exactly what it’s name suggests, a tool in the same vein as Firebug or Webinspector but, able to run and debug web pages remotely. So, if you have used tools such as the Firefox Developer Tools or Chrome Dev Tools, using Weinre will be second nature. But enough talk, let’s get this up and running.

Setting Up Weinre

As Weinre runs on top of Node.js your first port of call would be to install Node.js. Node.js comes with NPM (Node Package Manager) bundled nowadays and this is then then what we are going to use to install Weinre. From a terminal run the following:

npm -g install weinre

NOTE: The -g flag is used to install Weinre as a global Node.js module for command line goodness but, on Linux and Mac, this means you most likely are going to need to run the above by prepending sudo to the above command.

Once the installation process is complete, we are ready to use Weinre to debug. But first, let’s make absolutely sure that Weinre was indeed installed successfully. In your terminal, run the following:

$ weinre --boundHost 127.0.0.1 --httpPort 9090
2013-01-28T10:42:40.498Z weinre: starting server at http://127.0.0.1:9090

If you see a line similar to the last line above, your installation was a success and the Weinre server us up and running. With that, fire up a browser (NOTE: The UI for Weinre is built specifically for Webkit based browsers so, while it might work to some degree in other browsers, I would suggest you use Chrome) and point it to http://127.0.0.1:9090

Above then is the landing page for the Weinre server giving you access to the documentation, some other trinkets, as well as the Weinre client, the page we really want to head to so, go ahead and click on the debug client link.

From the above you can see that we have one connected client, this is the current instance of the web inspector, some general properties of our server but, no targets. Let’s get our target set-up.

NOTE: If the UI of winery looks very familiar that’s because Winery uses the same UI code as the web inspector in Chrome and Safari.

Setting Up A Weinre Target

In Weinre targets are the web pages or apps that you want to debug, and in order for the target to be able to connect, we need to add a one liner to the relevant file of our app. For this post, let’s inspect the Calendar app. Go ahead and open up gaia -> apps -> calendar -> index.html and scroll right to the bottom. Just before the closing body tag, insert the following line:

<script src="http://127.0.0.1:9090/target/target-script-min.js#anonymous"></script>

Before we can launch B2G Desktop and try this out however, there is one more step. Gaia uses a Content Security Policy and as part of that scripts are said to only be allowed to load, if from the same origin as the application. So, if we were to try and load the Calendar now, the script from above would be blocked as it is not being loaded from the specified origin.

To overcome this, we need to temporarily disable CSP. To do this, open up gaia -> build -> preferences.js and add the following line, around line 24:

prefs.push(["security.csp.enable", false]);

Debugging Using Weinre and B2G Desktop

Now we are ready to test Weinre. If you are not already inside the Gaia root directory, change into it now and execute:

DEBUG=1 make

Once the profile is built, launch B2G desktop:

/Applications/B2G.app/Contents/MacOS/b2g-bin -profile /Users/username/mozilla/projects/gaia/profile

Once B2G launches, unlock the screen, swipe two screens to the right and click on the Calendar icon to launch the Calendar app. Once the app launches, you will see a new item appear on Weinre’s client dashboard:

As you can see, the Calendar has successfully connected and is now listed as one of our targets. Go ahead and click on the ‘Elements’ tab.

Listed here is the HTML of our app on the left and our CSS on the right! You can go right ahead and edit either the HTML or the CSS as you normally would and see the changes reflect live. Note that even though the CSS looks grayed out and disabled, it if fully editable. You can also add completely new styles to the current element using the empty element.style block or amending existing rules. You will also notice you have access to the computed styles as well as metrics of the current element.

Working With The Console

The next tab of interest to us is the Console tab. Here you can code away and run any JavaScript you want directly against the current app or execute code exposed by the app. To see how this works, let’s interact with the call log portion of the Dialer.

First step then is to move our script import from Calendar to Dialer. Grab the code from Calendar and then open up gaia -> apps – > communication -> dialer -> index.html and paste the code. Next rebuild your profile using ‘make’ and finally relaunch B2G desktop.

Once it is launched again, click on the Dialer icon at the bottom left of the home screen. Once loaded, confirm that the communication channels are open to Weinre by opening http://127.0.0.1:9090/client/#anonymous and confirming that the target now looks as follows:

127.0.0.1 [channel: t-7 id: anonymous] - app://communications.gaiamobile.org/dialer/index.html#keyboard-view

With the dialer open, click on the call log icon, bottom left. Currently the call log is already populated with some dummy data but, let’s create our own. Click over to the Console tab in Weinre, type the following and press enter.

RecentsDBManager.deleteAll();

If you look at the view on desktop now, it would seem that nothing has happened but wait, there is more. Type in the following and press enter:

Recents.refresh();

Aha! As you can see, our call log is empty. Next step then, is to add an entry back. To do this, we will create a dummy call entry Object and then pass this to the add function of the RecentsDBManager to store it:

// Dummy entry
var recentCall = {
    type: 'incoming-refused',
    number: '555-6677',
    date: new Date()
};
RecentsDBManager.add(recentCall);
Recents.refresh();

And as you can see now, the entry we just created has been added to storage, IndexedDB to be exact, and is visible in the call log view. As you might very well have noticed, another of the great features that comes with the console is auto-complete which will further speed up development.

The combination of features that this exposes already opens new doors and will make working on Firefox OS, or writing apps for the OS, much easier with less time spent between building profiles, tearing down and relaunching B2G. Which all makes for happier developers.

But hey wait a second, what about debugging on the device? This will work exactly the same as the above with one small difference, the IP. When you want to debug on the device you first need to know the IP address of your host computer. Then you need to start up Weinre using this IP as the buondHost and also as the IP when including the script into you target documents.

On Mac and Linux you can get this address using ifconfig and on Windows it is ipconfig. Once you have the new IP, just stop the current instance of Weinre and then do the following:

weinre --boundHost 192.168.1.1 --httpPort 9090

Then inside you target document add:

<script src="http://192.168.1.1:9090/target/target-script-min.js#anonymous"></script>

Make and push your Gaia profile to the device using:

make install-gaia

Launch your target app and you are in business!

Conclusion

While this solution is not perfect, you need to remember to undo your changes before committing anything to source control, having to manually add the script every time is not ideal and then there are also some things that do not work 100%, such as, highlighting DOM elements as you hover over the HTML source and debugging JavaScript with breakpoints and such, this does go a long way towards improving the lives of developers both working directly on Gaia as well as those writing exciting new apps for Firefox OS.

But there is already some light at the end of the tunnel with regards to managing the injection of the script manually, disabling CSP and ensuring things are cleaned up before pushing to source control. Jan Jongboom has opened a pull request against the Gaia repo that looks extremely promising and will alleviate a lot of this so, go on and give him a hand and let’s get this merged into Gaia. Happy Hacking!

An important note: None of the above would have happened if it was not for Kevin Grandon who remembered using Weinre and sent out the email that set the ball rolling. Thanks Kevin!

About Robert Nyman [Editor emeritus]

Technical Evangelist & Editor of Mozilla Hacks. Gives talks & blogs about HTML5, JavaScript & the Open Web. Robert is a strong believer in HTML5 and the Open Web and has been working since 1999 with Front End development for the web - in Sweden and in New York City. He regularly also blogs at http://robertnyman.com and loves to travel and meet people.

More articles by Robert Nyman [Editor emeritus]…


16 comments

  1. aL3xa

    Debugging FirefoxOS with webkit native devtools?!? Blasphemy!!!

    January 31st, 2013 at 08:45

    1. Schalk Neethling

      Hey aL3xa, you might be right ;), but while the dev tools people finish up their work on the native tools, this is much better than having nothing. So for now, this will make developer’s lives easier on a day to day basis.

      January 31st, 2013 at 08:55

      1. aL3xa

        Sure, I can’t agree with you more, and I tend to forget to put the smiley in messages like this. =)
        To be frank, I use Chrome myself (for development) on daily basis.
        Its devtools are faster than Firebug, have more features (event breakpoints, source maps), are native, etc. I really hope that the guys working on devtools are gonna speed up the development and/or that Firebug will become faster. I reckon that the first one is more likely. =)

        January 31st, 2013 at 09:42

        1. Robert Nyman [Editor]

          On that topic: it would be interesting if you tested the Developer Tools in Firefox Nightly and let us know what you think!

          January 31st, 2013 at 10:08

          1. aL3xa

            Robert, I’m running Nightly for a while now, and I’ve seen the devtools, as well as Paul Roget’s JS Term (dunno why that one doesn’t come by default), but I’m really frustrated by lack of some, IMO, must-have features like autocompletion. It’s available in web-console, as well as in JS-term, but not in scratchpad, and CSS doesn’t provide autocompletion, which is frustrating. DOM breakpoints cannot be set, etc. etc. Firebug is by far better solution, if only it weren’t that slow… =/

            January 31st, 2013 at 13:07

          2. aL3xa

            Okay, let’s sum it up, the things I really miss in there are:

            – autocompletion (JS + CSS)
            – source maps/(de)minifier – yes, I know there’s jsb in developer console, but it’s not the same
            – event/DOM breakpoints
            – user/eye-friendly output in Net panel – more Firebug-like, with preview and stuff like that
            – make JSTerm native, it’s really awesome!

            January 31st, 2013 at 15:15

          3. Robert Nyman [Editor]

            Thanks for the feedback!

            February 1st, 2013 at 04:15

        2. Schalk Neethling

          As Rob says, the native dev tools in Firefox has come a long way and is definitely worth your time, and once they go remote, it’s gonna be all kinds of awesome.

          January 31st, 2013 at 10:13

          1. aL3xa

            I’m really looking forward to it! =)

            January 31st, 2013 at 13:08

  2. Holger Hussmann

    Great thing, and many thanks and credits to Jan Jongboom @janjongboom who came up with this great idea, and figured out the details.

    See also: http://www.youtube.com/watch?v=UiZSEkdAKAA

    January 31st, 2013 at 12:24

  3. Jeff Griffiths

    The thing is, you can debug B2G desktop using Frefox’s native debugger, I demo’d this at Mozcamp Asia and again this past weekend at Vancouver’s App Hack Day. As you mention, you cannot inspect remotely or edit css currently but that is coming, and will involve fewer hoops to jump through than with Weinre.

    January 31st, 2013 at 21:10

    1. Schalk Neethling

      Hey Jeff,

      I am definitely looking forward to the native tools but, at the moment, Weinre fills a gap in the development tool chain when it comes to FirefoxOS.

      Do you perhaps have slides or a blog post you can link up here with regards to using the native debugger with B2G desktop?

      February 1st, 2013 at 00:44

  4. Fawad Hassan

    Thanks for sharing this tip!
    Well I think it’s better to first write code that doesn’t use Firefox OS APIs and thoroughly test it using Firefox native developer tools or Firebug then make use of APIs and test them via remote debugger :)

    February 1st, 2013 at 02:16

    1. Robert Nyman [Editor]

      Absolutely, that’s one approach. But very often you want to test it in the context that it will be run in.
      Additionally, for testing APIs etc on your desktop, I suggest using the Firefox OS Simulator.

      February 1st, 2013 at 04:18

      1. Fawad Hassan

        Yes you are right so I am already using Firefox OS Simulator for that :)

        February 1st, 2013 at 05:03

        1. Robert Nyman [Editor]

          Great! :-)

          February 1st, 2013 at 06:38

Comments are closed for this article.