Bug 719618 - Craft a no-outside-network mode for peptest. r=ctalbert
authorMark Cote <mcote@mozilla.com>
Tue, 14 Feb 2012 10:23:25 -0500
changeset 87215 121ada16c79304e61fb723861f8d72dd41f30c29
parent 87214 d25397e8464594b73e349c13055f5975c70aec05
child 87216 efd7b7d7f91c83d55cc36b30e8ad5326c1bcb100
push id6256
push userjmaher@mozilla.com
push dateMon, 20 Feb 2012 18:34:31 +0000
treeherdermozilla-inbound@121ada16c793 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersctalbert
bugs719618
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 719618 - Craft a no-outside-network mode for peptest. r=ctalbert
testing/peptest/peptest/extension/resource/mozmill/driver/controller.js
testing/peptest/peptest/extension/resource/mozmill/driver/mozelement.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/EventUtils.js
testing/peptest/peptest/extension/resource/pep/api.js
testing/peptest/peptest/runpeptests.py
testing/peptest/tests/firefox/examples/example_tests.ini
testing/peptest/tests/firefox/examples/test_contextMenu.js
testing/peptest/tests/firefox/examples/test_openBlankTab.js
testing/peptest/tests/firefox/examples/test_openBookmarksMenu.js
testing/peptest/tests/firefox/examples/test_openWindow.js
testing/peptest/tests/firefox/examples/test_resizeWindow.js
testing/peptest/tests/firefox/examples/test_searchGoogle.js
testing/peptest/tests/firefox/firefox_all.ini
testing/peptest/tests/firefox/server-locations.txt
testing/peptest/tests/firefox/server/index.html
testing/peptest/tests/firefox/server/mozilla.org/index.html
testing/peptest/tests/firefox/server/mozilla.org/index.html.orig
testing/peptest/tests/firefox/server/mozillians.org/index.html
testing/peptest/tests/firefox/test_contextMenu.js
testing/peptest/tests/firefox/test_openBlankTab.js
testing/peptest/tests/firefox/test_openBookmarksMenu.js
testing/peptest/tests/firefox/test_openWindow.js
testing/peptest/tests/firefox/test_resizeWindow.js
testing/peptest/tests/firefox/test_searchGoogle.js
testing/testsuite-targets.mk
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/controller.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/controller.js
@@ -62,22 +62,22 @@ waitForEvents = function() {}
 
 waitForEvents.prototype = {
   /**
    * Initialize list of events for given node
    */
   init : function waitForEvents_init(node, events) {
     if (node.getNode != undefined)
       node = node.getNode();
-  
+
     this.events = events;
     this.node = node;
     node.firedEvents = {};
     this.registry = {};
-  
+
     for each(e in events) {
       var listener = function(event) {
         this.firedEvents[event.type] = true;
       }
       this.registry[e] = listener;
       this.registry[e].result = false;
       this.node.addEventListener(e, this.registry[e], true);
     }
@@ -87,17 +87,17 @@ waitForEvents.prototype = {
    * Wait until all assigned events have been fired
    */
   wait : function waitForEvents_wait(timeout, interval)
   {
     for (var e in this.registry) {
       utils.waitFor(function() {
         return this.node.firedEvents[e] == true;
       }, "Timeout happened before event '" + ex +"' was fired.", timeout, interval);
-  
+
       this.node.removeEventListener(e, this.registry[e], true);
     }
   }
 }
 
 /**
  * Class to handle menus and context menus
  *
@@ -276,20 +276,20 @@ var MozMillController = function (window
   if ( controllerAdditions[window.document.documentElement.getAttribute('windowtype')] != undefined ) {
     this.prototype = new utils.Copy(this.prototype);
     controllerAdditions[window.document.documentElement.getAttribute('windowtype')](this);
     this.windowtype = window.document.documentElement.getAttribute('windowtype');
   }
 }
 
 // constructs a MozMillElement from the controller's window
-MozMillController.prototype.__defineGetter__("windowElement", function() {
-  if (this._windowElement == undefined) 
-    this._windowElement = new mozelement.MozMillElement(undefined, undefined, {'element': this.window});
-  return this._windowElement;
+MozMillController.prototype.__defineGetter__("rootElement", function() {
+  if (this._rootElement == undefined)
+    this._rootElement = new mozelement.MozMillElement(undefined, undefined, {'element': this.window.document.documentElement});
+  return this._rootElement;
 });
 
 MozMillController.prototype.sleep = utils.sleep;
 
 // Open the specified url in the current tab
 MozMillController.prototype.open = function(url)
 {
   switch(this.mozmillModule.Application) {
@@ -303,41 +303,41 @@ MozMillController.prototype.open = funct
       throw new Error("MozMillController.open not supported.");
   }
 
   broker.pass({'function':'Controller.open()'});
 }
 
 /**
  * Take a screenshot of specified node
- * 
+ *
  * @param {element} node
  *   the window or DOM element to capture
  * @param {string} name
  *   the name of the screenshot used in reporting and as filename
  * @param {boolean} save
  *   if true saves the screenshot as 'name.png' in tempdir, otherwise returns a dataURL
  * @param {element list} highlights
  *   a list of DOM elements to highlight by drawing a red rectangle around them
  */
 MozMillController.prototype.screenShot = function _screenShot(node, name, save, highlights) {
   if (!node) {
     throw new Error("node is undefined");
   }
-  
+
   // Unwrap the node and highlights
   if ("getNode" in node) node = node.getNode();
   if (highlights) {
     for (var i = 0; i < highlights.length; ++i) {
       if ("getNode" in highlights[i]) {
         highlights[i] = highlights[i].getNode();
       }
     }
   }
-  
+
   // If save is false, a dataURL is used
   // Include both in the report anyway to avoid confusion and make the report easier to parse
   var filepath, dataURL;
   try {
     if (save) {
       filepath = utils.takeScreenshot(node, name, highlights);
     } else {
       dataURL = utils.takeScreenshot(node, undefined, highlights);
@@ -414,31 +414,31 @@ MozMillController.prototype.startUserShu
   }
   broker.sendMessage('userShutdown', {'user': true,
                                   'restart': Boolean(restart),
                                   'next': next,
                                   'resetProfile': Boolean(resetProfile)});
   this.window.setTimeout(broker.sendMessage, timeout, 'userShutdown', 0);
 }
 
-MozMillController.prototype.restartApplication = function (next, resetProfile) 
+MozMillController.prototype.restartApplication = function (next, resetProfile)
 {
   // restart the application via the python runner
   // - next : name of the next test function to run after restart
   // - resetProfile : whether to reset the profile after restart
   broker.sendMessage('userShutdown', {'user': false,
                                   'restart': true,
                                   'next': next,
                                   'resetProfile': Boolean(resetProfile)});
   broker.sendMessage('endTest');
   broker.sendMessage('persist');
   utils.getMethodInWindows('goQuitApplication')();
 }
 
-MozMillController.prototype.stopApplication = function (resetProfile) 
+MozMillController.prototype.stopApplication = function (resetProfile)
 {
   // stop the application via the python runner
   // - resetProfile : whether to reset the profile after shutdown
   broker.sendMessage('userShutdown', {'user': false,
                                   'restart': false,
                                   'resetProfile': Boolean(resetProfile)});
   broker.sendMessage('endTest');
   broker.sendMessage('persist');
@@ -483,31 +483,31 @@ MozMillController.prototype.assertText =
   throw new Error("could not validate element " + el.getInfo()+" with text "+ text);
   return false;
 
 };
 
 //Assert that a specified node exists
 MozMillController.prototype.assertNode = function (el) {
   logDeprecatedAssert("assertNode");
-  
+
   //this.window.focus();
   var element = el.getNode();
   if (!element){
     throw new Error("could not find element " + el.getInfo());
     return false;
   }
   broker.pass({'function':'Controller.assertNode()'});
   return true;
 };
 
 // Assert that a specified node doesn't exist
 MozMillController.prototype.assertNodeNotExist = function (el) {
   logDeprecatedAssert("assertNodeNotExist");
-  
+
   //this.window.focus();
   try {
     var element = el.getNode();
   } catch(err){
     broker.pass({'function':'Controller.assertNodeNotExist()'});
     return true;
   }
 
@@ -518,17 +518,17 @@ MozMillController.prototype.assertNodeNo
     broker.pass({'function':'Controller.assertNodeNotExist()'});
     return true;
   }
 };
 
 //Assert that a form element contains the expected value
 MozMillController.prototype.assertValue = function (el, value) {
   logDeprecatedAssert("assertValue");
-  
+
   //this.window.focus();
   var n = el.getNode();
 
   if (n && n.value == value){
     broker.pass({'function':'Controller.assertValue()'});
     return true;
   }
   throw new Error("could not validate element " + el.getInfo()+" with value "+ value);
@@ -545,164 +545,164 @@ MozMillController.prototype.assert = fun
 
   broker.pass({'function': ": controller.assert('" + callback + "')"});
   return true;
 }
 
 //Assert that a provided value is selected in a select element
 MozMillController.prototype.assertSelected = function (el, value) {
   logDeprecatedAssert("assertSelected");
-  
+
   //this.window.focus();
   var n = el.getNode();
   var validator = value;
 
   if (n && n.options[n.selectedIndex].value == validator){
     broker.pass({'function':'Controller.assertSelected()'});
     return true;
     }
   throw new Error("could not assert value for element " + el.getInfo()+" with value "+ value);
   return false;
 };
 
 //Assert that a provided checkbox is checked
 MozMillController.prototype.assertChecked = function (el) {
   logDeprecatedAssert("assertChecked");
-  
+
   //this.window.focus();
   var element = el.getNode();
 
   if (element && element.checked == true){
     broker.pass({'function':'Controller.assertChecked()'});
     return true;
     }
   throw new Error("assert failed for checked element " + el.getInfo());
   return false;
 };
 
 // Assert that a provided checkbox is not checked
 MozMillController.prototype.assertNotChecked = function (el) {
   logDeprecatedAssert("assertNotChecked");
-  
+
   var element = el.getNode();
 
   if (!element) {
     throw new Error("Could not find element" + el.getInfo());
   }
 
   if (!element.hasAttribute("checked") || element.checked != true){
     broker.pass({'function':'Controller.assertNotChecked()'});
     return true;
     }
   throw new Error("assert failed for not checked element " + el.getInfo());
   return false;
 };
 
-/** 
+/**
  * Assert that an element's javascript property exists or has a particular value
  *
  * if val is undefined, will return true if the property exists.
  * if val is specified, will return true if the property exists and has the correct value
  */
 MozMillController.prototype.assertJSProperty = function(el, attrib, val) {
   logDeprecatedAssert("assertJSProperty");
-  
+
   var element = el.getNode();
   if (!element){
     throw new Error("could not find element " + el.getInfo());
     return false;
   }
   var value = element[attrib];
   var res = (value !== undefined && (val === undefined ? true : String(value) == String(val)));
   if (res) {
     broker.pass({'function':'Controller.assertJSProperty("' + el.getInfo() + '") : ' + val});
   } else {
-    throw new Error("Controller.assertJSProperty(" + el.getInfo() + ") : " + 
+    throw new Error("Controller.assertJSProperty(" + el.getInfo() + ") : " +
                      (val === undefined ? "property '" + attrib + "' doesn't exist" : val + " == " + value));
   }
   return res;
 };
 
-/** 
+/**
  * Assert that an element's javascript property doesn't exist or doesn't have a particular value
  *
  * if val is undefined, will return true if the property doesn't exist.
  * if val is specified, will return true if the property doesn't exist or doesn't have the specified value
  */
 MozMillController.prototype.assertNotJSProperty = function(el, attrib, val) {
   logDeprecatedAssert("assertNotJSProperty");
-  
+
   var element = el.getNode();
   if (!element){
     throw new Error("could not find element " + el.getInfo());
     return false;
   }
   var value = element[attrib];
   var res = (val === undefined ? value === undefined : String(value) != String(val));
   if (res) {
     broker.pass({'function':'Controller.assertNotProperty("' + el.getInfo() + '") : ' + val});
   } else {
     throw new Error("Controller.assertNotJSProperty(" + el.getInfo() + ") : " +
                      (val === undefined ? "property '" + attrib + "' exists" : val + " != " + value));
   }
   return res;
 };
 
-/** 
+/**
  * Assert that an element's dom property exists or has a particular value
  *
  * if val is undefined, will return true if the property exists.
  * if val is specified, will return true if the property exists and has the correct value
  */
 MozMillController.prototype.assertDOMProperty = function(el, attrib, val) {
   logDeprecatedAssert("assertDOMProperty");
-  
+
   var element = el.getNode();
   if (!element){
     throw new Error("could not find element " + el.getInfo());
     return false;
   }
   var value, res = element.hasAttribute(attrib);
   if (res && val !== undefined) {
     value = element.getAttribute(attrib);
     res = (String(value) == String(val));
-  }   
- 
+  }
+
   if (res) {
     broker.pass({'function':'Controller.assertDOMProperty("' + el.getInfo() + '") : ' + val});
   } else {
-    throw new Error("Controller.assertDOMProperty(" + el.getInfo() + ") : " + 
+    throw new Error("Controller.assertDOMProperty(" + el.getInfo() + ") : " +
                      (val === undefined ? "property '" + attrib + "' doesn't exist" : val + " == " + value));
   }
   return res;
 };
 
-/** 
+/**
  * Assert that an element's dom property doesn't exist or doesn't have a particular value
  *
  * if val is undefined, will return true if the property doesn't exist.
  * if val is specified, will return true if the property doesn't exist or doesn't have the specified value
  */
 MozMillController.prototype.assertNotDOMProperty = function(el, attrib, val) {
   logDeprecatedAssert("assertNotDOMProperty");
-  
+
   var element = el.getNode();
   if (!element){
     throw new Error("could not find element " + el.getInfo());
     return false;
   }
   var value, res = element.hasAttribute(attrib);
   if (res && val !== undefined) {
     value = element.getAttribute(attrib);
     res = (String(value) == String(val));
-  }   
+  }
   if (!res) {
     broker.pass({'function':'Controller.assertNotDOMProperty("' + el.getInfo() + '") : ' + val});
   } else {
-    throw new Error("Controller.assertNotDOMProperty(" + el.getInfo() + ") : " + 
+    throw new Error("Controller.assertNotDOMProperty(" + el.getInfo() + ") : " +
                      (val == undefined ? "property '" + attrib + "' exists" : val + " == " + value));
   }
   return !res;
 };
 
 // deprecated - Use assertNotJSProperty or assertNotDOMProperty instead
 MozMillController.prototype.assertProperty = function(el, attrib, val) {
   logDeprecatedAssert("assertProperty");
@@ -715,17 +715,17 @@ MozMillController.prototype.assertProper
   return this.assertNotJSProperty(el, attrib);
 };
 
 // Assert that a specified image has actually loaded
 // The Safari workaround results in additional requests
 // for broken images (in Safari only) but works reliably
 MozMillController.prototype.assertImageLoaded = function (el) {
   logDeprecatedAssert("assertImageLoaded");
-  
+
   //this.window.focus();
   var img = el.getNode();
   if (!img || img.tagName != 'IMG') {
     throw new Error('Controller.assertImageLoaded() failed.')
     return false;
   }
   var comp = img.complete;
   var ret = null; // Return value
@@ -954,26 +954,26 @@ controllerAdditions = {
 
 /**
  *  DEPRECATION WARNING
  *
  * The following methods have all been DEPRECATED as of Mozmill 2.0
  * Use the MozMillElement object instead (https://developer.mozilla.org/en/Mozmill/Mozmill_Element_Object)
  */
 MozMillController.prototype.select = function (elem, index, option, value) {
-  return elem.select(index, option, value); 
+  return elem.select(index, option, value);
 };
 
 MozMillController.prototype.keypress = function(aTarget, aKey, aModifiers, aExpectedEvent) {
-  if (aTarget == null) { aTarget = this.windowElement; }
+  if (aTarget == null) { aTarget = this.rootElement; }
   return aTarget.keypress(aKey, aModifiers, aExpectedEvent);
 }
 
 MozMillController.prototype.type = function (aTarget, aText, aExpectedEvent) {
-  if (aTarget == null) { aTarget = this.windowElement; }
+  if (aTarget == null) { aTarget = this.rootElement; }
 
   var that = this;
   var retval = true;
   Array.forEach(aText, function(letter) {
     if (!that.keypress(aTarget, letter, {}, aExpectedEvent)) {
       retval = false; }
   });
 
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/mozelement.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/mozelement.js
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-var EXPORTED_SYMBOLS = ["Elem", "Selector", "ID", "Link", "XPath", "Name", "Lookup", 
+var EXPORTED_SYMBOLS = ["Elem", "Selector", "ID", "Link", "XPath", "Name", "Lookup",
                         "MozMillElement", "MozMillCheckBox", "MozMillRadio", "MozMillDropList",
                         "MozMillTextBox", "subclasses",
                        ];
 
 var EventUtils = {};  Components.utils.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
 var utils = {};       Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
 var elementslib = {}; Components.utils.import('resource://mozmill/driver/elementslib.js', elementslib);
 var broker = {};      Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
@@ -50,55 +50,56 @@ var broker = {};      Components.utils.i
 var subclasses = [MozMillCheckBox, MozMillRadio, MozMillDropList, MozMillTextBox];
 
 /**
  * createInstance()
  *
  * Returns an new instance of a MozMillElement
  * The type of the element is automatically determined
  */
-function createInstance(locatorType, locator, elem) {
+function createInstance(locatorType, locator, elem, document) {
   if (elem) {
-    var args = {"element":elem};
+    var args = { "element": elem,
+                 "document": document };
     for (var i = 0; i < subclasses.length; ++i) {
       if (subclasses[i].isType(elem)) {
         return new subclasses[i](locatorType, locator, args);
       }
     }
     if (MozMillElement.isType(elem)) return new MozMillElement(locatorType, locator, args);
   }
   throw new Error("could not find element " + locatorType + ": " + locator);
 };
 
 var Elem = function(node) {
   return createInstance("Elem", node, node);
 };
 
-var Selector = function(_document, selector, index) {
-  return createInstance("Selector", selector, elementslib.Selector(_document, selector, index));
+var Selector = function(document, selector, index) {
+  return createInstance("Selector", selector, elementslib.Selector(document, selector, index), document);
 };
 
-var ID = function(_document, nodeID) {
-  return createInstance("ID", nodeID, elementslib.ID(_document, nodeID));
+var ID = function(document, nodeID) {
+  return createInstance("ID", nodeID, elementslib.ID(document, nodeID), document);
 };
 
-var Link = function(_document, linkName) {
-  return createInstance("Link", linkName, elementslib.Link(_document, linkName));
+var Link = function(document, linkName) {
+  return createInstance("Link", linkName, elementslib.Link(document, linkName), document);
 };
 
-var XPath = function(_document, expr) {
-  return createInstance("XPath", expr, elementslib.XPath(_document, expr));
+var XPath = function(document, expr) {
+  return createInstance("XPath", expr, elementslib.XPath(document, expr), document);
 };
 
-var Name = function(_document, nName) {
-  return createInstance("Name", nName, elementslib.Name(_document, nName));
+var Name = function(document, nName) {
+  return createInstance("Name", nName, elementslib.Name(document, nName), document);
 };
 
-var Lookup = function(_document, expression) {
-  return createInstance("Lookup", expression, elementslib.Lookup(_document, expression));
+var Lookup = function(document, expression) {
+  return createInstance("Lookup", expression, elementslib.Lookup(document, expression), document);
 };
 
 
 /**
  * MozMillElement
  * The base class for all mozmill elements
  */
 function MozMillElement(locatorType, locator, args) {
@@ -116,17 +117,17 @@ function MozMillElement(locatorType, loc
 MozMillElement.isType = function(node) {
   return true;
 };
 
 // This getter is the magic behind lazy loading (note distinction between _element and element)
 MozMillElement.prototype.__defineGetter__("element", function() {
   if (this._element == undefined) {
     if (elementslib[this._locatorType]) {
-      this._element = elementslib[this._locatorType](this._document, this._locator); 
+      this._element = elementslib[this._locatorType](this._document, this._locator);
     } else if (this._locatorType == "Elem") {
       this._element = this._locator;
     } else {
       throw new Error("Unknown locator type: " + this._locatorType);
     }
   }
   return this._element;
 });
@@ -474,25 +475,25 @@ MozMillRadio.isType = function(node) {
  *
  * index - Specifies which radio button in the group to select (only applicable to radiogroup elements)
  *         Defaults to the first radio button in the group
  */
 MozMillRadio.prototype.select = function(index) {
   if (!this.element) {
     throw new Error("could not find element " + this.getInfo());
   }
-  
+
   if (this.element.localName.toLowerCase() == "radiogroup") {
     var element = this.element.getElementsByTagName("radio")[index || 0];
     new MozMillRadio("Elem", element).click();
   } else {
     var element = this.element;
     this.click();
   }
-  
+
   utils.waitFor(function() {
     // If we have a XUL element, unwrap its XPCNativeWrapper
     if (element.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
       element = utils.unwrapNode(element);
       return element.selected == true;
     }
     return element.checked == true;
   }, "Radio button " + this.getInfo() + " could not be selected", 500);
@@ -576,17 +577,17 @@ MozMillDropList.prototype.select = funct
   }
   //if we have a xul menupopup select accordingly
   else if (this.element.namespaceURI.toLowerCase() == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
     var ownerDoc = this.element.ownerDocument;
     // Unwrap the XUL element's XPCNativeWrapper
     this.element = utils.unwrapNode(this.element);
     // Get the list of menuitems
     menuitems = this.element.getElementsByTagName("menupopup")[0].getElementsByTagName("menuitem");
-    
+
     var item = null;
 
     if (indx != undefined) {
       if (indx == -1) {
         this.dispatchEvent('focus', false);
         this.element.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild = null;
         this.dispatchEvent('change', true);
 
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/EventUtils.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/EventUtils.js
@@ -693,17 +693,17 @@ function synthesizeText(aEvent, aWindow)
  * @param aWindow  Optional (If null, current |window| will be used)
  * @return         An nsIQueryContentEventResult object.  If this failed,
  *                 the result might be null.
  */
 function synthesizeQuerySelectedText(aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
-    return nsnull;
+    return null;
   }
   return utils.sendQueryContentEvent(utils.QUERY_SELECTED_TEXT, 0, 0, 0, 0);
 }
 
 /**
  * Synthesize a query text content event.
  *
  * @param aOffset  The character offset.  0 means the first character in the
@@ -713,17 +713,17 @@ function synthesizeQuerySelectedText(aWi
  * @param aWindow  Optional (If null, current |window| will be used)
  * @return         An nsIQueryContentEventResult object.  If this failed,
  *                 the result might be null.
  */
 function synthesizeQueryTextContent(aOffset, aLength, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
-    return nsnull;
+    return null;
   }
   return utils.sendQueryContentEvent(utils.QUERY_TEXT_CONTENT,
                                      aOffset, aLength, 0, 0);
 }
 
 /**
  * Synthesize a query caret rect event.
  *
@@ -732,17 +732,17 @@ function synthesizeQueryTextContent(aOff
  * @param aWindow  Optional (If null, current |window| will be used)
  * @return         An nsIQueryContentEventResult object.  If this failed,
  *                 the result might be null.
  */
 function synthesizeQueryCaretRect(aOffset, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
-    return nsnull;
+    return null;
   }
   return utils.sendQueryContentEvent(utils.QUERY_CARET_RECT,
                                      aOffset, 0, 0, 0);
 }
 
 /**
  * Synthesize a query text rect event.
  *
@@ -753,51 +753,51 @@ function synthesizeQueryCaretRect(aOffse
  * @param aWindow  Optional (If null, current |window| will be used)
  * @return         An nsIQueryContentEventResult object.  If this failed,
  *                 the result might be null.
  */
 function synthesizeQueryTextRect(aOffset, aLength, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
-    return nsnull;
+    return null;
   }
   return utils.sendQueryContentEvent(utils.QUERY_TEXT_RECT,
                                      aOffset, aLength, 0, 0);
 }
 
 /**
  * Synthesize a query editor rect event.
  *
  * @param aWindow  Optional (If null, current |window| will be used)
  * @return         An nsIQueryContentEventResult object.  If this failed,
  *                 the result might be null.
  */
 function synthesizeQueryEditorRect(aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
-    return nsnull;
+    return null;
   }
   return utils.sendQueryContentEvent(utils.QUERY_EDITOR_RECT, 0, 0, 0, 0);
 }
 
 /**
  * Synthesize a character at point event.
  *
  * @param aX, aY   The offset in the client area of the DOM window.
  * @param aWindow  Optional (If null, current |window| will be used)
  * @return         An nsIQueryContentEventResult object.  If this failed,
  *                 the result might be null.
  */
 function synthesizeCharAtPoint(aX, aY, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
-    return nsnull;
+    return null;
   }
   return utils.sendQueryContentEvent(utils.QUERY_CHARACTER_AT_POINT,
                                      0, 0, aX, aY);
 }
 
 /**
  * Synthesize a selection set event.
  *
--- a/testing/peptest/peptest/extension/resource/pep/api.js
+++ b/testing/peptest/peptest/extension/resource/pep/api.js
@@ -32,48 +32,92 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  ***** END LICENSE BLOCK ***** */
 
 var EXPORTED_SYMBOLS = ['PepAPI'];
 var results = {}; Components.utils.import('resource://pep/results.js', results);
-var log = {}; Components.utils.import('resource://pep/logger.js', log);
-var utils = {}; Components.utils.import('resource://pep/utils.js', utils);
+var log = {};     Components.utils.import('resource://pep/logger.js', log);
+var utils = {};   Components.utils.import('resource://pep/utils.js', utils);
+var mozmill = {}; Components.utils.import('resource://mozmill/driver/mozmill.js', mozmill);
+var securableModule = {};
+Components.utils.import('resource://mozmill/stdlib/securable-module.js', securableModule);
 
 const wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                            .getService(Components.interfaces.nsIWindowMediator);
+                     .getService(Components.interfaces.nsIWindowMediator);
+const ios = Components.classes["@mozilla.org/network/io-service;1"]
+                      .getService(Components.interfaces.nsIIOService);
 
 /**
  * This is the API exposed to tests
- * Any properties of this object will be directly injected into test scope
+ * Any properties of this object will be injected into test scope
+ * under the 'pep' namespace.
  */
 function PepAPI(test) {
   this.test = test;
   this.log = new Log(this.test.name);
   this.resultHandler = new results.ResultHandler(this.test.name);
+
+  this.file = Components.classes["@mozilla.org/file/local;1"]
+                        .createInstance(Components.interfaces.nsILocalFile);
+  this.file.initWithPath(this.test.path);
 }
+/**
+ * Performs an action during which responsiveness is measured
+ */
 PepAPI.prototype.performAction = function(actionName, func) {
   this.resultHandler.startAction(actionName);
   func();
   this.resultHandler.endAction();
 };
+/**
+ * Returns the most recently used window of windowType
+ */
 PepAPI.prototype.getWindow = function(windowType) {
   if (windowType === undefined) {
     windowType = "navigator:browser";
   }
-
   return wm.getMostRecentWindow(windowType);
 };
+/**
+ * Load a file on the local filesystem
+ * module - path on the local file of the module to load (no extension)
+ */
+PepAPI.prototype.require = function(module) {
+  let loader = new securableModule.Loader({
+    rootPaths: [ios.newFileURI(this.file.parent).spec],
+    defaultPrincipal: "system",
+    globals: { Cc: Components.classes,
+               Ci: Components.interfaces,
+               Cr: Components.results,
+               Cu: Components.utils,
+               // mozmill scopes for compatibility with mozmill shared libraries
+               // https://developer.mozilla.org/en/Mozmill_Tests/Shared_Modules
+               mozmill: mozmill,
+               // quick hack to keep backwards compatibility with mozmill 1.5.x
+               elementslib: mozmill.findElement,
+               findElement: mozmill.findElement,
+               persisted: {},
+             },
+  });
+  return loader.require(module);
+};
+
+/**
+ * Sleep for a number of milliseconds
+ */
 PepAPI.prototype.sleep = function(milliseconds) {
   utils.sleep(milliseconds);
 };
 
-// Logging wrapper for tests
+/**
+ * Logging wrapper for tests
+ */
 function Log(testName) {
   this.testName = testName;
 }
 Log.prototype.debug = function(msg) {
   log.debug(this.testName + ' | ' + msg);
 };
 Log.prototype.info = function(msg) {
   log.info(this.testName + ' | ' + msg);
--- a/testing/peptest/peptest/runpeptests.py
+++ b/testing/peptest/peptest/runpeptests.py
@@ -31,16 +31,17 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 from optparse import OptionParser
 from mozprofile import FirefoxProfile, ThunderbirdProfile, Profile
+from mozprofile.permissions import ServerLocations
 from mozrunner import FirefoxRunner, ThunderbirdRunner, Runner
 from mozhttpd import MozHttpd
 from manifestparser import TestManifest
 from pepprocess import PepProcess
 from pepresults import Results
 
 import peputils as utils
 import traceback
@@ -63,18 +64,32 @@ class Peptest():
     runner_class = Runner
 
     def __init__(self, options, **kwargs):
         self.options = options
         self.server = None
         self.logger = mozlog.getLogger('PEP')
 
         # create the profile
+        enable_proxy = False
+        locations = ServerLocations()
+        if self.options.proxyLocations:
+            if not self.options.serverPath:
+                self.logger.warning('Can\'t set up proxy without server path')
+            else:
+                enable_proxy = True
+                locations.read(self.options.proxyLocations, False)
+                locations.add_host(host='127.0.0.1',
+                                   port=self.options.serverPort,
+                                   options='primary,privileged')
+
         self.profile = self.profile_class(profile=self.options.profilePath,
-                                          addons=[os.path.join(here, 'extension')])
+                                          addons=[os.path.join(here, 'extension')],
+                                          locations=locations,
+                                          proxy=enable_proxy)
 
         # fork a server to serve the test related files
         if self.options.serverPath:
             self.runServer()
 
         tests = []
         # TODO is there a better way of doing this?
         if self.options.testPath.endswith('.js'):
@@ -138,17 +153,18 @@ class Peptest():
         Start a basic HTML server to host
         test related files.
         """
         if not self.options.serverPath:
             self.logger.warning('Can\'t start HTTP server, --server-path not specified')
             return
         self.logger.debug('Starting server on port ' + str(self.options.serverPort))
         self.server = MozHttpd(port=self.options.serverPort,
-                               docroot=self.options.serverPath)
+                               docroot=self.options.serverPath,
+                               proxy_host_dirs=self.options.proxyHostDirs)
         self.server.start(block=False)
 
     def stop(self):
         """Kill the app"""
         # stop the runner
         if self.runner is not None:
             self.runner.stop()
 
@@ -297,16 +313,30 @@ class PeptestOptions(OptionParser):
                              "(requires a debug build to be effective)")
 
         self.add_option("-p", "--profile-path", action="store",
                         type="string", dest="profilePath",
                         default=None,
                         help="path to the profile to use. "
                              "If none specified, a temporary profile is created")
 
+        self.add_option("--proxy",
+                        action="store", type="string", dest="proxyLocations",
+                        default=None,
+                        help="path to a server-location file specifying "
+                             "domains to proxy. --server-path must also be "
+                             "specified.")
+
+        self.add_option("--proxy-host-dirs",
+                        action="store_true", dest="proxyHostDirs",
+                        default=False,
+                        help="proxied requests are served from directories "
+                             "named by requested host. --proxy must also be "
+                             "specified.")
+
         self.add_option("--server-port",
                         action="store", type="int", dest="serverPort",
                         default=8888,
                         help="The port to host test related files on")
 
         self.add_option("--server-path",
                         action="store", type="string", dest="serverPath",
                         default=None,
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/example_tests.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[test_contextMenu.js]
-[test_openBlankTab.js]
-[test_openBookmarksMenu.js]
-failThreshold = 40
-[test_searchGoogle.js]
-[test_openWindow.js]
-[test_resizeWindow.js]
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/test_contextMenu.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is peptest.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Andrew Halberstadt <halbersa@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-/**
- * This test is designed to test responsiveness while performing actions
- * on various context menus in both content and chrome.
- */
-
-// Import mozmill and initialize a controller
-Components.utils.import("resource://mozmill/driver/mozmill.js");
-let c = getBrowserController();
-
-// Open mozilla.org and wait for the page to load
-c.open("http://mozilla.org");
-c.waitForPageLoad();
-
-// Grab reference to element on page (this is the <body> element in this case)
-let page = findElement.ID(c.tabs.activeTab, 'header');
-// Perform our first action, reload.
-// It is very important to only place things that we
-// are interested in testing inside of a performAction call
-pep.performAction('content_reload', function() {
-  page.rightClick();
-  page.keypress('r');
-});
-c.waitForPageLoad();
-
-c.open("http://google.com");
-c.waitForPageLoad();
-
-page = findElement.ID(c.tabs.activeTab, 'main');
-// Perform our second action, go back
-pep.performAction('content_back', function() {
-  page.rightClick();
-  page.keypress('b');
-});
-// Bug 699400 - waitForPageLoad times out when pressing back button
-c.sleep(100);
-
-page = findElement.ID(c.tabs.activeTab, 'home');
-// Perform our third action, scroll through context menu
-pep.performAction('content_scroll', function() {
-  page.rightClick();
-  for (let i = 0; i < 15; ++i) {
-    page.keypress('VK_DOWN');
-    // Sleep to better emulate a user
-    c.sleep(10);
-  }
-});
-
-// Now test context menus in chrome
-let bar = findElement.ID(c.window.document, "appmenu-toolbar-button");
-bar.click();
-pep.performAction('chrome_menu', function() {
-  bar.rightClick();
-  bar.keypress('m');
-});
-
-pep.performAction('chrome_addon', function() {
-  bar.rightClick();
-  bar.keypress('a');
-});
-
-pep.performAction('chrome_scroll', function() {
-  bar.rightClick();
-  for (let i = 0; i < 15; ++i) {
-    page.keypress('VK_DOWN');
-    // Sleep to better emulate a user
-    c.sleep(10);
-  }
-});
-
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/test_openBlankTab.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is peptest.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Andrew Halberstadt <halbersa@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Initialize mozmill
-Components.utils.import('resource://mozmill/driver/mozmill.js');
-let c = getBrowserController();
-
-c.open('http://mozilla.org');
-c.waitForPageLoad();
-
-// Only put things you want to test for responsiveness inside a perfom action call
-let page = findElement.ID(c.tabs.activeTab, "home");
-pep.performAction('open_blank_tab', function() {
-  page.keypress('t', {'ctrlKey': true});
-});
-
-pep.performAction('close_blank_tab', function() {
-  page.keypress('w', {'ctrlKey': true});
-});
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/test_openBookmarksMenu.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is peptest.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Andrew Halberstadt <halbersa@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Import mozmill and initialize a controller
-Components.utils.import('resource://mozmill/driver/mozmill.js');
-let c = getBrowserController();
-
-c.open('http://mozilla.org');
-c.waitForPageLoad();
-
-let bookmark = findElement.ID(c.window.document, "bookmarksMenu");
-pep.performAction('scroll_bookmarks', function() {
-  bookmark.click();
-  for (let i = 0; i < 15; ++i) {
-    bookmark.keypress('VK_DOWN');
-    // Sleep to better emulate a user
-    c.sleep(10);
-  }
-});
-
-let showall = findElement.ID(c.window.document, "bookmarksShowAll");
-pep.performAction('show_all_bookmarks', function() {
-  showall.click();
-});
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/test_openWindow.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is peptest.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Andrew Halberstadt <halbersa@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Import mozmill and initialize a controller
-Components.utils.import("resource://mozmill/driver/mozmill.js");
-let controller = getBrowserController();
-
-let win = findElement.ID(controller.window.document, 'main-window');
-pep.performAction("open_window", function() {
-  win.keypress("n", {"ctrlKey":true});
-});
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/test_resizeWindow.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is peptest.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Andrew Halberstadt <halbersa@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Most of the other example tests use Mozmill to perform various
-// automation. Note that this is not necessary.
-//
-// This test will check responsiveness while resizing the window
-
-let window = pep.getWindow();
-let width = window.outerWidth;
-let height = window.outerHeight;
-
-pep.performAction('resize_by', function() {
-  window.resizeBy(100, 100);
-});
-
-pep.performAction('resize_to', function() {
-  window.resizeTo(800, 600);
-});
-
-// Tests should clean up after themselves
-window.resizeTo(width, height);
deleted file mode 100644
--- a/testing/peptest/tests/firefox/examples/test_searchGoogle.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is peptest.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Andrew Halberstadt <halbersa@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Import mozmill and initialize a controller
-Components.utils.import("resource://mozmill/driver/mozmill.js");
-let controller = getBrowserController();
-
-controller.open("http://google.ca");
-controller.waitForPageLoad();
-
-let textbox = findElement.ID(controller.tabs.activeTab, 'lst-ib');
-let button = findElement.Name(controller.tabs.activeTab, 'btnK');
-pep.performAction('enterText', function() {
-  textbox.sendKeys('foobar');
-  button.click();
-});
--- a/testing/peptest/tests/firefox/firefox_all.ini
+++ b/testing/peptest/tests/firefox/firefox_all.ini
@@ -1,2 +1,6 @@
-# All Firefox tests - include other manifests here
-[include:examples/example_tests.ini]
+[test_contextMenu.js]
+[test_openBlankTab.js]
+[test_openBookmarksMenu.js]
+failThreshold = 40
+[test_openWindow.js]
+[test_resizeWindow.js]
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/server-locations.txt
@@ -0,0 +1,3 @@
+http://mozilla.org	privileged
+http://mozillians.org	privileged
+
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/server/index.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+This is a big test!
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/server/mozilla.org/index.html
@@ -0,0 +1,6 @@
+<html>
+<body id="home">
+Test mozilla home page.
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/server/mozilla.org/index.html.orig
@@ -0,0 +1,8 @@
+<html>
+<body id="home">
+<div id="header">
+Test mozilla home page.
+</div>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/server/mozillians.org/index.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+Test mozillians home page.
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/test_contextMenu.js
@@ -0,0 +1,106 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is peptest.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andrew Halberstadt <halbersa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This test is designed to test responsiveness while performing actions
+ * on various context menus in both content and chrome.
+ */
+
+Components.utils.import("resource://mozmill/driver/mozmill.js");
+let c = getBrowserController();
+
+// Open mozilla.org and wait for the page to load
+c.open("http://mozilla.org");
+c.waitForPageLoad();
+
+// Perform our first action, reload.
+// It is very important to only place things that we
+// are interested in testing inside of a performAction call
+pep.performAction('content_reload', function() {
+  // controller.rootElement is the global window object
+  // wrapped inside of a MozMillElement
+  c.rootElement.rightClick();
+  c.rootElement.keypress('r');
+});
+c.waitForPageLoad();
+
+c.open("http://mozillians.org");
+c.waitForPageLoad();
+
+// Perform our second action, go back
+pep.performAction('content_back', function() {
+  c.rootElement.rightClick();
+  c.rootElement.keypress('b');
+});
+// Bug 699400 - waitForPageLoad times out when pressing back button
+c.sleep(500);
+
+// get a reference to the element with id 'home'
+page = findElement.ID(c.tabs.activeTab, 'home');
+// Perform our third action, scroll through context menu
+pep.performAction('content_scroll', function() {
+  page.rightClick();
+  for (let i = 0; i < 15; ++i) {
+    page.keypress('VK_DOWN');
+    // Sleep to better emulate a user
+    c.sleep(10);
+  }
+});
+
+// Now test context menus in chrome
+let bar = findElement.ID(c.window.document, "appmenu-toolbar-button");
+bar.click();
+pep.performAction('chrome_menu', function() {
+  bar.rightClick();
+  bar.keypress('m');
+});
+
+pep.performAction('chrome_addon', function() {
+  bar.rightClick();
+  bar.keypress('a');
+});
+
+pep.performAction('chrome_scroll', function() {
+  bar.rightClick();
+  for (let i = 0; i < 15; ++i) {
+    page.keypress('VK_DOWN');
+    // Sleep to better emulate a user
+    c.sleep(10);
+  }
+});
+
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/test_openBlankTab.js
@@ -0,0 +1,52 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is peptest.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andrew Halberstadt <halbersa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Initialize mozmill
+Components.utils.import('resource://mozmill/driver/mozmill.js');
+let c = getBrowserController();
+
+c.open('http://mozilla.org');
+c.waitForPageLoad();
+
+// Only put things you want to test for responsiveness inside a perfom action call
+pep.performAction('open_blank_tab', function() {
+  c.rootElement.keypress('t', {'ctrlKey': true});
+});
+
+pep.performAction('close_blank_tab', function() {
+  c.rootElement.keypress('w', {'ctrlKey': true});
+});
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/test_openBookmarksMenu.js
@@ -0,0 +1,58 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is peptest.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andrew Halberstadt <halbersa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Import mozmill and initialize a controller
+Components.utils.import('resource://mozmill/driver/mozmill.js');
+let c = getBrowserController();
+
+c.open('http://mozilla.org');
+c.waitForPageLoad();
+
+let bookmark = findElement.ID(c.window.document, "bookmarksMenu");
+pep.performAction('scroll_bookmarks', function() {
+  bookmark.click();
+  for (let i = 0; i < 15; ++i) {
+    bookmark.keypress('VK_DOWN');
+    // Sleep to better emulate a user
+    c.sleep(10);
+  }
+});
+
+let showall = findElement.ID(c.window.document, "bookmarksShowAll");
+pep.performAction('show_all_bookmarks', function() {
+  showall.click();
+});
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/test_openWindow.js
@@ -0,0 +1,44 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is peptest.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andrew Halberstadt <halbersa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://mozmill/driver/mozmill.js");
+let controller = getBrowserController();
+
+let win = findElement.ID(controller.window.document, 'main-window');
+pep.performAction("open_window", function() {
+  win.keypress("n", {"ctrlKey":true});
+});
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/test_resizeWindow.js
@@ -0,0 +1,56 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is peptest.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andrew Halberstadt <halbersa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Most of the other example tests use Mozmill to perform various
+// automation. Note that this is not necessary.
+//
+// This test will check responsiveness while resizing the window
+
+let window = pep.getWindow();
+let width = window.outerWidth;
+let height = window.outerHeight;
+
+pep.performAction('resize_by', function() {
+  window.resizeBy(100, 100);
+});
+
+pep.performAction('resize_to', function() {
+  window.resizeTo(800, 600);
+});
+
+// Tests should clean up after themselves
+window.resizeTo(width, height);
new file mode 100644
--- /dev/null
+++ b/testing/peptest/tests/firefox/test_searchGoogle.js
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is peptest.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andrew Halberstadt <halbersa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Import mozmill and initialize a controller
+Components.utils.import("resource://mozmill/driver/mozmill.js");
+let controller = getBrowserController();
+
+controller.open("http://google.com");
+controller.waitForPageLoad();
+
+let textbox = findElement.ID(controller.tabs.activeTab, 'lst-ib');
+let button = findElement.Name(controller.tabs.activeTab, 'btnK');
+pep.performAction('enter_text', function() {
+  textbox.sendKeys('foobar');
+  button.click();
+});
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -266,18 +266,22 @@ xpcshell-tests-remote:
           then $(call REMOTE_XPCSHELL); $(CHECK_TEST_ERROR); \
         else \
           echo "please prepare your host with environment variables for TEST_DEVICE"; \
         fi
 
 # Runs peptest, for usage see: https://developer.mozilla.org/en/Peptest#Running_Tests
 RUN_PEPTEST = \
 	rm -f ./$@.log && \
-	$(PYTHON) _tests/peptest/runtests.py --binary=$(browser_path) $(PEPTEST_PATH_ARG) \
-	  --log-file=./$@.log $(SYMBOLS_PATH) $(EXTRA_TEST_ARGS)
+	$(PYTHON) _tests/peptest/runtests.py --binary=$(browser_path) \
+          $(PEPTEST_PATH_ARG) \
+	  --proxy=_tests/peptest/tests/firefox/server-locations.txt \
+          --proxy-host-dirs \
+          --server-path=_tests/peptest/tests/firefox/server \
+          --log-file=./$@.log $(SYMBOLS_PATH) $(EXTRA_TEST_ARGS)
 
 peptest:
 	$(RUN_PEPTEST)
 	$(CHECK_TEST_ERROR)
 
 # Package up the tests and test harnesses
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk