Debugging Web Pages and PhoneGap apps on mobile devices

If you are a web developer chances are that Google Chrome Developer Tools, Safari Web Inspector, or a Firefox equivalent are your best friends when it comes to debugging web pages (check CSS styles, verify generated HTML, or debug JavaScript). Isn’t that great? I mean not so long ago we used to debug JavaScript using alert() calls.

Once you get used to these tools it is hard not to have them. And this is exactly what happens when you move to mobile web development. As you probably know there is no web inspector running on your iOS device browser.

How do you debug your web apps when running on mobile devices? The best answer to this question is using weinre (if you know a better way, please let me know).

What is weinre?

weinre is a remote Web Inspector that runs on your computer but it is connected to a browser (or a PhoneGap application) that is running on a mobile device. In terms of user interface it reuses the Web Inspector project at WebKit.

weinre consists of a debug server that runs on your computer and a user interface that also runs on your computer. The server component is able to communicate with the web page you are “debugging” (that typically runs on a mobile device) thanks to a JavaScript script that you have to inject in the page you want to debug (the script is served by the server component). And here comes the first thing you have to know: because of this architecture your mobile phone must be able to reach the server running on your computer (you can easily achieve this by connecting the computer and mobile device to the same WiFi network). If you are curious about how the web page running on the mobile device is able to communicate with the debug server, the answer is using XMLHttpRequest.

Finally, weinre is distributed either as a Java JAR file or as a Mac OS X application. This means that you can use this tool on a Windows, Mac OS X, or Linux machine.

Are there any limitations?

Unfortunately there are: you can’t debug the JavaScript code. This means you are not able to set breakpoints in your JavaScript code and introspect the variables. Unfortunate though this limitation might be, weinre is still incredibly useful because you can introspect the HTML code, see the Console output, execute JavaScript code in the console, get information about the XHR calls made by your page, and even select DOM elements.

How can you use it?

Here is a step-by-step list that explains how you can use weinre to “debug” a web page that is running on your mobile phone:

1. Download the weinre debug server application

First download the weinre application (this will be basically the debug server). I will use the Mac OS X application instead of the JAR file and I will point out what is different if you use the JAR file.

2. Connect the computer and mobile device to the same WiFi network

After you download the weinre file it is time to connect your computer and mobile device to the same WiFi network. Once the computer is connected, it is time to find out what IP address it is using. On my case the IP address is 42.1.2.250.

3. Configure the weinre debug server application

Now, it is time to configure the weinre debug server. Because I am using the Mac OS application, all I have to do is to create a server.properties file in the following location: ~/.weinre/server.properties

Next, open the server.properties file and add these two lines (for boundHost you have to introduce the IP address of your computer and for httpPort you can use any port number you want that doesn’t conflict with other web servers that might be running on your computer):

boundHost: 42.1.2.250
httpPort:  8080

Make sure you save the file.

If you use the JAR file, then you can set the options either using the server.properties file or adding them as options to the command line when invoking the JAR file.

4. Start the weinre debug server

For the Mac OS X app all you have to do is start the weinre application. If you use the JAR file then you should start the application using the command line.

5. Inject the JavaScript file in the web page you want to debug

With the debug server running it is time to inject the JavaScript file that makes all the parts to communicate. To do so, open the HTML page you want to “debug” and add this line:

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

Please note that the IP address and port number must match the values you set in the server.properties file. Make sure you save these changes.

6. Make the web page available to your mobile phone

Now, you are ready to debug the web page. However, in order to do this you have to load this page in the browser that runs on your mobile device. You will have to copy the web page and its dependencies to a web server running on your computer. In my case I’m running a MAMP instance on port 80. So what I’ve done is to copy the folder where I created the web page to the htdocs folder of the MAMP. Make sure the web server you want to use is running.

7. Load the web page on your mobile device browser

Open the browser on your mobile phone and load the page: http://42.1.2.250/weinre/index.html

Please note the IP address and port number must be your computer IP address and your web server port number (in my case I am running on the default port so there was no need to add it) and the rest of the URL must match the folder/file name you have.

8. Debug the page

Once your mobile browser loads the page, the weinre application should look like this:

In the picture above Targets refers to the mobile device browser (so the IP address is your mobile device IP) and Clients refers to the debug client/server.

Here is a screenshot with the weinre application when the Elements tab is used and the console is opened too. You can see that the whole body element is selected. And in the console you can see some outputs. These were dysplayed once I hit the two buttons I have created in the web page.

And here is a screenshot of the web page running on my Android phone. As you can see the body is selected – because in the weinre app the body element was selected.

Finally, the web page used in this example looks like this:

<!DOCTYPE HTML>
<html>
<head>
<meta charset=”UTF-8″>

<title>Testing</title>
<script src=”http://42.1.2.250:8080/target/target-script-min.js#anonymous”></script>
<script>
function clickBtn() {
console.log(‘clickBtn() was called!’);
}
function click2Btn() {
console.log(‘click2Btn() was called!’);
}
</script>
</head>
<body onLoad=”init()”>
<h1>A simple page</h1>
<h2>To test weinre – Web Inspector Remote</h2>
<button onClick=”clickBtn()”>Click Me</button>
<br>
<button onClick=”click2Btn()”>Click Me Too</button>
</body>
</html>

If you use the JAR file, then you should open on your computer this URL: http://42.1.2.250:8080/client/#anonymous. Again change the IP address and port number to what you configured for the weinre debug server. Here is a screenshot with the debugger client opened in my browser:

For your convenience, I captured this workflow in a short screencast:

Conclusions

Although you don’t get all the features available in the desktop Web Inspector, weinre is still a formidable asset in any developer’s toolbox. I mean without this you would have to use alert() or some other ten times more time consuming technique. Recently I was working on a web mobile application and weinre came to my rescue on a number of occasions.

4 thoughts on “Debugging Web Pages and PhoneGap apps on mobile devices

  1. Pingback: Debugging web pages remotely using a PlayBook tablet : Mihai Corlan

  2. Pingback: aTabSplitter – the web standards edition : Mihai Corlan

  3. Pingback: Introducing Adobe Shadow – a new way to debug mobile web sites and apps : Mihai Corlan

  4. I too have installed the weinre app on MAC OSX 10.8.2 and it works with browser targets but I’m having a problem with device and simulator targets. Initially I was getting an alert on the iphone app’s target web page, loaded in the simulator, saying the the WeinreServerURL needed to be set. So I set it to the server url I’ve been using and the alert went away but I still could not connect to the target. It seems that there is something else that the target lacks. Any ideas?

Leave a Reply

Your email address will not be published. Required fields are marked *