DevTools/Hacking

From MozillaWiki
Jump to: navigation, search

Want to hack on Firefox Developer Tools? You've come to the right place! If you want more information about contributing, check out our guide for getting involved.

First Build

Follow the instructions on how to build Firefox, except that you will need to use:

hg clone http://hg.mozilla.org/integration/fx-team

Instead of:

hg clone http://hg.mozilla.org/mozilla-central

For your first build, running ./mach build should do the trick after you get the source code. If you are going to be building a lot, you may want to set up your .mozconfig file.

First Run

Once you have built Firefox, you can run it with

 $ ./mach run

or

 $ ./mach run -P development

What is the -P development? It is a flag telling Firefox to use a different profile, named "development" (this name can be anything you want). If it does not exist the first time you run it, Firefox will open a popup and you can create a new profile with the name you passed in. If you don't specify a profile, mach will create a temporary profile in the path <objdir>/tmp/scratch_user.

Once this command runs, you should see a new Firefox window, called "Nightly". You will want to make a couple of quick changes to the profile.

Open DevTools, and click the "Toolbox Options" gear in the top left. Make sure the following two options are checked: Enable Chrome Debugging and Enable Remote Debugging. These settings allow you to use the browser toolbox to set breakpoints inside of the DevTools code, inspect the DevTools themselves, and let you run the Scratchpad in the Browser environment.

Settings for developer tools - "Enable Chrome Debugging" and "Enable Remote Debugging"

Development workflow

Incremental Builds

Once you've already built Firefox once, and you just want to incrementally update your build with your latest devtools changes, you can run:

 $ ./mach build toolkit/devtools browser

Which is much faster than your first build or clobber builds and should only take a few seconds. You can run your build the same way you did before:

 $ ./mach run -P development

Note that whenever you pull the latest changes from fx-team into your local repository, you may need to "clobber". A "clobber" is similar to a "make clean". You'll know you need to clobber when you get a big error message telling you to do a clobber build after you tried to do an incremental build. To do a clobber build, enter these commands:

 $ ./mach clobber
 $ ./mach build

Enabling DevTools Logging

Depending on what you are working on, you may want to make some changes to your profile to enable more logging. If you type about:config in the URL bar, click through the warning page, and search for devtools you can see some of them.

Add the global "dump" function to all windows which logs strings to stdout.

 browser.dom.window.dump.enabled = true

Dumps all packets sent over the remote debugging protocol to stdout (requires browser.dom.window.dump.enabled):

 devtools.debugger.log = true

Log every event notification from the EventEmitter class (toolkit/devtools/event-emitter.js) (requires browser.dom.window.dump.enabled)

 devtools.dump.emit = true

Restart the browser to apply configuration changes.

Making and Submitting a Patch

Before you make any changes, read this section on creating a patch for someone else to check in - this will get you set up with a separate Mercurial queue for development of your patch.

If you read through the source code about something you do not know about, you may find documentation here:

  • Mozilla Developer Network has a ton of info about XUL elements, HTML, JS, DOM, Web APIs, Gecko-specific APIs, and more.
  • DXR is a source code search engine - search for symbols you want to learn about, eg. nsIDocument.
  • You should read our Coding Standards before writing code.
    • In general, try to be File Consistent. For new files, follow the standards.

We recommend adding a smart keyword search for DXR and MDN.

If you still have questions, ask us on IRC or leave a comment on the Bugzilla ticket.

Once you have a patch file, add it as an attachment to the Bugzilla ticket you are working on and add the feedback? or review? flag depending on if you just want feedback and confirmation you're doing the right thing or if you think the patch is ready to land respectively. Read more about how to submit a patch and the Bugzilla review cycle here.

Developer Tools Directories Overview

  • toolkit/devtools: Code for the devtools client and server, and all code shared between the front end and client/server. If we are using any third party libraries, or importing external repositories into our tree, those libraries generally live here (eg, toolkit/devtools/acorn).
  • browser/devtools: Front end user interfaces for our tools. Should be pretty obvious what is what based on the directory names and each panel we have in our toolbox.

Running the Developer Tools Tests

We use three suites of tests:

  • xpcshell: More unit-test style of tests. No browser window, just a JavaScript shell. Mostly testing APIs directly.
  • mochitest-chrome: More unit-test style of tests, but with a browser window. Mostly testing APIs that interact with the DOM directly.
  • mochitest-devtools: More of an integration style of tests. Fires up a whole browser window with every test and you can test clicking on buttons, etc.

More information about the different types of tests can be found on the MDN automated testing page

To run all DevTools tests, regardless of suite type:

 $ ./mach test toolkit/devtools
 $ ./mach test browser/devtools

The following sections show more specific commands for running only a single suite or single test in a suite.

xpcshell Tests

To run all of the xpcshell tests:

 $ ./mach xpcshell-test toolkit/devtools
 $ ./mach xpcshell-test browser/devtools

To run a specific xpcshell test:

 $ ./mach xpcshell-test toolkit/devtools/path/to/the/test_you_want_to_run.js

Chrome Mochitests

To run the whole suite of chrome mochitests for devtools:

 $ ./mach mochitest-chrome toolkit/devtools
 $ ./mach mochitest-chrome browser/devtools

To run a specific chrome mochitest:

 $ ./mach mochitest-chrome toolkit/devtools/path/to/the/test_you_want_to_run.html

DevTools Mochitests

To run the whole suite of browser mochitests for devtools (sit back and relax):

 $ ./mach mochitest-devtools browser/devtools

To run a specific tool's suite of browser mochitests:

 $ ./mach mochitest-devtools browser/devtools/<tool>

For example, run all of the debugger browser mochitests:

 $ ./mach mochitest-devtools browser/devtools/debugger

To run a specific devtools mochitest:

 $ ./mach mochitest-devtools browser/devtools/path/to/the/test_you_want_to_run.js

To help with writing nice, maintainable and consistent devtools mochitests, please follow our devtools mochitests coding guide.

Note that the mochitests must to have focus while running.

Checking your code using JSHint

You don't have to use JSHint, but you may find it helpful.

There are many tools that allow you to run JSHint, for example JSHint Gutter for Sublime Text.

Here is an example jshint.rc that conforms pretty closely with our style and use:

{
  "browser": true,
  "devel": true,
  "loopfunc": true,
  "esnext": true,
  "moz": true,
  "quotmark": true,
  "undef": true,
  "unused": true,
  "maxerr": 10000,
  "globals": {
    "loader": true,
    "require": true,
    "module": true,
    "exports": true,
    "Components": false,
    "Cu": true,
    "Ci": true,
    "Cc": true,
    "Cr": true,
    "CC": true,
    "dump": false,
    "Services": false,
    "do_check_eq": false,
    "do_check_false": false,
    "do_check_true": false,
    "do_get_file": false,
    "do_get_profile": false,
    "do_print": false,
    "do_register_cleanup": false,
    "do_throw": false,
    "add_test": false,
    "add_task": false,
    "run_next_test": false,
    "EventUtils": false,
    "ok": false,
    "is": false,
    "isnot": false,
    "equal": false,
    "deepEqual": false,
    "Task": false,
    "finish": false,
    "setTimeout": false,
    "clearTimeout": false,
    "XPCOMUtils": false,
    "top": true
  }
}

Potential Pitfalls

Today there are a few techniques and conventions we use that can be confusing, especially when you first start working with the code base. We hope to improve these with time to make things easier for everyone, but for now this etherpad might be a helpful set of notes if you are having trouble. If you find new pitfalls that aren't listed there, feel free to add your own entries, so we know to address them. Also, please come talk to us in #devtools on IRC, as that might be the fastest path to solving the issue.