This is an archived page. It's not actively maintained.

Using The Driver

The goal of this article is to teach you how to isolate Mozmill's driver from Mozmill's test harness, and drop it into your own extension allowing you to perform automation.

Mozmill is very feature rich. It can automate mostly any part of Firefox's UI which makes it an invaluable tool for anyone looking into Firefox automation. Unfortunately, Mozmill's test harness side is very bloated and unwieldy. The browser gets restarted between each test, plus a lot of other setup and teardown happens as well, which means that disguising a Mozmill test as a means to drive Firefox is not a very good or pleasant experience. Fortunately, it is possible to ignore all of the test harness bits and use only Mozmill's driver, which is lightweight and pure javascript (no python).

Isolating the Driver

Luckily some work has been done to make this pretty easy, though there is still a fair amount of work to be done to make this process even easier.

  1. Clone the Mozmill repo at somewhere on your file system.
  2. Create a Mozmill resource directory (in your extension's root folder, create a 'resource/mozmill' folder).
  3. Copy and paste the 'driver' and 'stdlib' folders from the 'path_to_mozmill_repo/mozmill/mozmill/extension/resource' directory into your 'resource/mozmill' directory.
  4. Edit your extension's chrome.manifest file and add the line 'resource mozmill resource/mozmill/' (don't forget the trailing slash)
  5. Mozmill's driver is now ready to be imported and used by any chrome scoped JS in your extension.

Listening for Messages

Now that you can use Mozmill's driver, it's time to register a listener for Mozmill events. These events will tell your extension whether the various Mozmill actions pass or fail, as well as pass along other information such as screen shot info. Place this code anywhere in your extension (preferably before you start calling Mozmill functions):

let broker = {}; Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
let mozmillListener = {
  'pass': function(obj) { dump('PASS ' + obj + '\n'); },
  'fail': function(obj) { dump('FAIL ' + obj + '\n'); },
  'log': function(obj) { dump('LOG ' + obj + '\n'); },
// Note: You can also add event listener individually with broker.addListener(eventType, listener).
//       Of course, each eventType can also have as many listeners as you wish.

Other Event Types

Pass, fail and log are the most common event types, but other ones exist too. Many of these others are specific to the Mozmill test harness and probably won't be relevant to your extension, but the full list is:

EventType Obj Fired When

Varies, but often:

{ 'function': function_name }

An action in Mozmill passes
fail Varies An action in Mozmill fails
log Varies Misc. log message
persist None ???
endTest None Test is finished (i.e stopApplication or restartApplication was called)
  'user': boolean,
  'restart': boolean,
  'next': next_test_to_run,
  'resetProfile': boolean
Once when userShutdown() is initiated, once again when timeout for shutdown occurs or shutdown occurs.

  'filename': filename,
  'method': method,
  'args': args,
  'kwargs': kwargs,

Python callback is invoked
  'filepath': filepath,
  'dataURL': dataURL,
  'name': name,
  'timestamp': timestamp,
controller.screenShot() is called

Using the Driver

Now that your listener is setup, here is an example of how your extension might actually use Mozmill's driver.

// Import mozmill and initialize a controller object
let controller = getBrowserController();

// Open google'');

// Type in the search box
let textbox = findElement.ID(controller.tabs.activeTab, 'lst-ib');
let button = findElement.Name(controller.tabs.activeTab, 'btnK');

For more information regarding using Mozmill's driver, see the Mozmill Reference Desk