Simulator Walkthrough (4.0)

DRAFT: work in progress (to be completed for the new upcoming simulator release)

In this page we'll debug a very simple (but very buggy!) web app using the Firefox OS Simulator.

The walkthrough is structured into six parts: each part uses a different diagnostic/debugging tool, specifically, manifest validation, the Web Console, the JavaScript Debugger, the Network Monitor, the Style Editor and the Test Receipts.

It's intended that each part should be self-contained, so it should be possible to read only that part and have it make sense.

Using manifest validation

If you want to follow along, the various revisions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-1 version of the app.

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

The walkthrough assumes that you've installed the Simulator and opened the Dashboard.

First we'll add the app to the Dashboard by clicking "Add Directory" and selecting the manifest. We'll see this:



Clicking on "(2 errors and 0 warnings)"  we see this:


This error message is pretty clear, and if we look at "manifest.webapp", we can see that it's missing a "name":

{
  "description": "A simple web app",
  "launch_path": "/index.html",
  "icons": {
    "128": "/style/icons/earth.png"
  }
}


Add the "name" field to the manifest file, save it, and click "Refresh" in the Dashboard:

{
  "name": "Where am I?",
  "description": "A simple web app",
  "launch_path": "/index.html",
  "icons": {
    "128": "/style/icons/earth.png"
  }
}


This time the Dashboard should tell us that we have no errors, and should run the app:

But when you click the button, nothing happens. In the next section, we'll try using the WebConsole to diagnose this problem.

Using the WebConsole

If you haven't followed along from the start of this walkthrough:

In this section we'll debug a very simple (but very buggy!) web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-2 version.

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

But in this version, when we click the button nothing happens. In this section of the walkthrough, we'll use the WebConsole to try to diagnose the problem.

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

Over in the Dashboard, you have to click the button labeled "Connect":

A Simulator window will open automatically and run the app (if it's not already), and the WebConsole should appear into the Simulator Dashboard tab.

In the console output you might see a few errors, warnings, and messages, but the last one in particular looks relevant:



This is obviously a problem in our app's script, "whereami.js". Here are the first few lines of the script:

var whereami = document.getElementById('whereami');
whereami.onclick = function() {
  navigator.geolocation.getCurrentPosition(getMap, error);
};


Comparing this with our app's "index.html", the problem's obvious:

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <script src="http://open.mapquestap.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  </head>
  <body>
    <button id ="where-am-i">Where am I?</button>
    <div id="map"></div>
    <script src="scripts/whereami.js"></script>
    <link media="all" href="style/style.css" type="text/css" rel="stylesheet">
  </body>
</html>


In the HTML, the button is assigned an ID of "where-am-i", but in the JavaScript, we're trying to use "whereami". So let's fix that:

var whereami = document.getElementById('where-am-i');
whereami.onclick = function() {
  navigator.geolocation.getCurrentPosition(getMap, error);
};

Now the app starts up without any errors, but when we click the button, the map doesn't appear, and we get a new message in the WebConsole:

This message is logged by our "whereami.js" script, and indicates that the geolocation API has returned an error - but it unhelpfully doesn't tell us what the error was. We can use the JavaScript Debugger to figure that out.

Using the JavaScript Debugger

If you haven't followed along from the start of this walkthrough:

In this section we'll debug a very simple (but very buggy!) web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-3 version.

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

But in this version, when we click the button the Geolocation API returns an error. In this section of the walkthrough, we'll use the JavaScript Debugger to figure out exactly which error is returned.

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

In the WebConsole connected to the app, click the link on the right of the geolocation error log:


Clicking on the "whereami.js:8" link, the JavaScript Debugger will be automatically loaded and pointed to the related file and line number.

According to the Geolocation API reference, the specific error is given by the code property of the error object that's passed into the error handler error(). So set a breakpoint inside error() by clicking to the left of line 8:

In the app, click "Where am I?". Execution should stop at the breakpoint:

Click where it says "Add watch expression" and type "error.code", and you'll immediately see its value, "1":


According to the Geolocation API documentation, "1" means "Permission denied". This is an error web apps get if they have not requested the geolocation permission, or if the permission wasn't granted by the user.

Looking at the "manifest.webapp" file, we'll see that we didn't ask for the permission:

{
  "name": "Where am I?",
  "description": "A simple web app",
  "launch_path": "/index.html",
  "icons": {
    "128": "/style/icons/earth.png"
  }
}


Let's fix that:

{
  "name": "Where am I?",
  "description": "A simple web app",
  "launch_path": "/index.html",
  "icons": {
    "128": "/style/icons/earth.png"
  },
  "permissions": {
    "geolocation": {
      "description": "Needed to tell the user where they are"
      }
  }
}


Save "manifest.webapp", and click "Refresh" in the Dashboard one more time. Remember to resume the Debugger as it is still at the breakpoint. This time the app runs, and when you click "Where am I?" it asks you to share your location, and if you allow it, the map doesn't appear and we get a new message in the WebConsole:

This message indicates that the MapQuest API, which we have included into our app using a tag script, is not loaded correctly. We can use the Network Monitor to figure that out.

Using the Network Monitor

If you haven't followed along from the start of this walkthrough:

In this section we'll inspect network request from a very simple (but very buggy!) web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-4 version.

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

But in this version, when we click the button the WebConsole shows a "MQA is not defined" error. In this section of the walkthrough, we'll use the Network Monitor to figure out exactly why the MapQuest API is not loaded.

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

In the Developer Tools panel connected to the app, click the Network tab and the following panel will be presented to you, where you see that requests for the "mqa.toolkit.js" resource from the "open.mapquestap.com" domain are never completed successfully:

Successful requests are green colored, if we click on one of the requests to the "open.mapquestap.com" domain (dark grey colored) and select the Timings detail panel, we can figure out that the request never reached the Connecting status, because DNS resolution did not succeed.

Looking at the "index.html" file, we'll see that the script tag points to the wrong domain.

Let's fix this bug, changing the script tag to use the correct domain: open.mapquestapi.com (add the missing 'i' to the domain name):

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <script src="http://open.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  </head>
  <body>
    <button id ="where-am-i">Where am I?</button>
    <div id="map"></div>
    <script src="scripts/whereami.js"></script>
    <link media="all" href="style/style.css" type="text/css" rel="stylesheet">
  </body>
</html>

Save "index.html", and click "Refresh" in the Dashboard one more time. This time the app runs, and when you click "Where am I?" it asks you to share your location, and if you allow it, the app finally displays the map:

Using the Style Editor

If you haven't followed along from the start of this walkthrough:

In this section we'll customizing the app stylesheets using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the version whereami-5.

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

In this version all the previous bugs are already fixed, and we're going to use the Style Editor to change the style real time on the running app and save it back when we're satisfied.

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

In the Developer Tools connected to the app, click the Style Editor tab and the following panel will be presented to you:

Select "style/style.css" from the style sheets list on the left and make some changes to the CSS rules. The new rules will be applied to the connected app immediately:

Now you can click on the "Save" link just below "style/style.css" in the style sheets list to save it back into the project.

Using the Test Receipts

If you haven't followed along from the start of this walkthrough:

In this section we'll add payment receipt validation code to a web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-6 version.

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

In this version we're going to change it to became a paid web app.

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

Now that your app is bug-free and properly styled, you can add payment receipt validation to ensure that users of your app have purchased it.

Mozilla has released a small JavaScript library which will help an app check its receipts: http://github.com/mozilla/receiptverifier

Let's add receiptverifier to the app, e.g. adding a new script tag to its "index.html" file:

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <script src="https://raw.github.com/mozilla/receiptverifier/master/receiptverifier.js"></script>
    <script src="http://open.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  </head>
  <body>
    <button id ="where-am-i">Where am I?</button>
    <div id="map"></div>
    <script src="scripts/whereami.js"></script>
    <link media="all" href="style/style.css" type="text/css" rel="stylesheet">
  </body>
</html>

and check the receipts in the "scripts/whereami.js" using the "mozmarket.receipts.Verifier" API (e.g. checking the receipts on the button click or on the app loading):

...
var verifier = new mozmarket.receipts.Verifier({
  installs_allowed_from: '*',
  typsAllowed: 'test-receipt',
  logLevel: mozmarket.receipts.Verifier.levels.DEBUG,
  onlog: mozmarket.receipts.Verifier.consoleLogger
});
verifier.clearCache();
function verifyPaymentReceipts(cb) {
  verifier.verify(function (verifier) {
    if (verifier.state instanceof verifier.states.OK) {
      cb(null); // valid payment
    } else {
      cb("invalid-payment"); // invalid payment
    }
  });
  setTimeout(function checkNoReceipts() {
    if (verifier.state instanceof verifier.states.NoReceipts) {
      cb("no-receipts");
    }
  }, 2000);
}
whereami.onclick = function() {
  verifyPaymentReceipts(function (err) {
    if (err) {
      alert("Invalid Payment Receipt.");
    } else {
      navigator.geolocation.getCurrentPosition(getMap, error);
    }
  });
};

Receipts are cryptographically signed (by the Marketplace and the Payment services), but you can use the Simulator to install your app with a test receipt by selecting the type of receipt to install (which defaults to "None") using the "Receipts" menu in the app entry:

Now you can test how the app will behave with "Valid", "Invalid", and "Refunded" receipts (or when there isn't any receipt) and observe the results by looking at the logs produced by the receiptverifier library in the Web Console:

 

Note: You can get the completed app from the whereami-7 version.

 

Document Tags and Contributors

 Contributors to this page: chrisdavidmills, MykMelez, lgreco
 Last updated by: chrisdavidmills,