Merge m-c to b2g-inbound.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 30 Sep 2013 16:30:26 -0400
changeset 149363 1b8d32bf6058be3cd3c3ad60df78b76f8750fb61
parent 149362 70398298d61089c96e38e5a6627a2878052a6fe7 (current diff)
parent 149333 77148d144fcf973a689a8c5dc46cdee926d8b63b (diff)
child 149364 e0994d28e8b301a3e9c2688b05cbe23d251aa86b
child 149414 d71579c316c17b0ca7aa1130075dc9d70d3ff5b3
child 149418 2fa72efe5bd3579e65bd452c6bee8aa41c47743a
child 149429 e4a15d3f895d65b669d29de3cdeb41ed2f87bbb8
child 155863 9ec16c9a71d334ca5d24799691529952da83870b
push id34529
push userryanvm@gmail.com
push dateMon, 30 Sep 2013 20:51:13 +0000
treeherdermozilla-inbound@e0994d28e8b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.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
Merge m-c to b2g-inbound.
build/docs/mozbuild/frontend.rst
dom/ipc/ContentParent.cpp
hal/android/AndroidHal.cpp
ipc/glue/MessagePump.cpp
mobile/android/base/UpdateService.java
mobile/android/base/UpdateServiceHelper.java
toolkit/modules/tests/xpcshell/test_phase.js
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -26,16 +26,17 @@
 #include "nsILineIterator.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPlaintextEditor.h"
 #include "nsIScrollableFrame.h"
 #include "nsIServiceManager.h"
 #include "nsTextFragment.h"
 #include "mozilla/Selection.h"
+#include "mozilla/MathAlgorithms.h"
 #include "gfxSkipChars.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // HyperTextAccessible
@@ -190,17 +191,17 @@ HyperTextAccessible::GetBoundsForString(
     NS_ENSURE_SUCCESS(rv, nsIntRect());
 
     // Use the point for the end offset to calculate the width
     nsPoint frameTextEndPoint;
     rv = frame->GetPointFromOffset(startContentOffset + frameSubStringLength, &frameTextEndPoint);
     NS_ENSURE_SUCCESS(rv, nsIntRect());
 
     frameScreenRect.x += std::min(frameTextStartPoint.x, frameTextEndPoint.x);
-    frameScreenRect.width = std::abs(frameTextStartPoint.x - frameTextEndPoint.x);
+    frameScreenRect.width = mozilla::Abs(frameTextStartPoint.x - frameTextEndPoint.x);
 
     screenRect.UnionRect(frameScreenRect, screenRect);
 
     // Get ready to loop back for next frame continuation
     startContentOffset += frameSubStringLength;
     startContentOffsetInFrame = 0;
     frame = frame->GetNextContinuation();
   }
--- a/accessible/tests/mochitest/actions/Makefile.in
+++ b/accessible/tests/mochitest/actions/Makefile.in
@@ -1,19 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_anchors.html \
-		test_aria.html \
-		test_general.html \
-		test_general.xul \
-		test_controls.html \
-		test_keys_menu.xul \
-		test_keys.html \
-		test_link.html \
-		test_media.html \
-		test_select.html \
-		test_tree.xul \
-		test_treegrid.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/actions/a11y.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+
+[test_anchors.html]
+[test_aria.html]
+[test_controls.html]
+[test_general.html]
+[test_general.xul]
+[test_keys.html]
+[test_keys_menu.xul]
+[test_link.html]
+[test_media.html]
+[test_select.html]
+[test_tree.xul]
+[test_treegrid.xul]
--- a/accessible/tests/mochitest/actions/moz.build
+++ b/accessible/tests/mochitest/actions/moz.build
@@ -1,5 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/attributes/Makefile.in
+++ b/accessible/tests/mochitest/attributes/Makefile.in
@@ -1,15 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_obj.html \
-		test_obj_css.html \
-		test_obj_css.xul \
-		test_obj_group.html \
-		test_obj_group.xul \
-		test_obj_group_tree.xul \
-		test_tag.html \
-		test_xml-roles.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/attributes/a11y.ini
@@ -0,0 +1,10 @@
+[DEFAULT]
+
+[test_obj.html]
+[test_obj_css.html]
+[test_obj_css.xul]
+[test_obj_group.html]
+[test_obj_group.xul]
+[test_obj_group_tree.xul]
+[test_tag.html]
+[test_xml-roles.html]
--- a/accessible/tests/mochitest/attributes/moz.build
+++ b/accessible/tests/mochitest/attributes/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/bounds/Makefile.in
+++ b/accessible/tests/mochitest/bounds/Makefile.in
@@ -1,11 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_list.html \
-		test_select.html \
-		test_zoom_text.html \
-		test_zoom.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/bounds/a11y.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+
+[test_list.html]
+[test_select.html]
+[test_zoom.html]
+[test_zoom_text.html]
--- a/accessible/tests/mochitest/bounds/moz.build
+++ b/accessible/tests/mochitest/bounds/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/editabletext/Makefile.in
+++ b/accessible/tests/mochitest/editabletext/Makefile.in
@@ -1,10 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		editabletext.js \
-		test_1.html \
-		test_2.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/editabletext/a11y.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+support-files = editabletext.js
+
+[test_1.html]
+[test_2.html]
--- a/accessible/tests/mochitest/editabletext/moz.build
+++ b/accessible/tests/mochitest/editabletext/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/elm/Makefile.in
+++ b/accessible/tests/mochitest/elm/Makefile.in
@@ -1,12 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_figure.html \
-		test_HTMLSpec.html \
-		test_listbox.xul \
-		test_nsApplicationAcc.html \
-		test_plugin.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/elm/a11y.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+
+[test_HTMLSpec.html]
+[test_figure.html]
+[test_listbox.xul]
+[test_nsApplicationAcc.html]
+[test_plugin.html]
--- a/accessible/tests/mochitest/elm/moz.build
+++ b/accessible/tests/mochitest/elm/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -1,61 +1,11 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		docload_wnd.html \
-		focus.html \
-		scroll.html \
-		test_aria_alert.html \
-		test_aria_menu.html \
-		test_aria_objattr.html \
-		test_aria_statechange.html \
-		test_attrs.html \
-		test_caretmove.html \
-		test_caretmove.xul \
-		test_coalescence.html \
-		test_contextmenu.html \
-		test_docload_aria.html \
-		test_docload.html \
-		test_docload.xul \
-		test_dragndrop.html \
-		test_flush.html \
-		test_focus_aria_activedescendant.html \
-		test_focus_browserui.xul \
-		test_focus_canvas.html \
-		test_focus_contextmenu.xul \
-		test_focus_controls.html \
-		test_focus_dialog.html \
-		test_focus_doc.html \
-		test_focus_general.html \
-		test_focus_general.xul \
-		test_focus_listcontrols.xul \
-		test_focus_menu.xul \
-		test_focus_name.html \
-		test_focus_selects.html \
-		test_focus_tabbox.xul \
-		test_focus_tree.xul \
-		test_fromUserInput.html \
-		test_label.xul \
-		test_menu.xul \
-		test_mutation.html \
-		test_mutation.xhtml \
-		test_scroll.xul \
-		test_selection_aria.html \
-		test_selection.html \
-		test_selection.xul \
-		test_statechange.html \
-		test_text_alg.html \
-		test_text.html \
-		test_textattrchange.html \
-		test_tree.xul \
-		test_valuechange.html \
-		$(NULL)
-
 # Disabled on Linux and Windows due to frequent failures - bug 695019, bug 890795
 ifeq (,$(filter Linux WINNT,$(OS_ARCH)))
 MOCHITEST_A11Y_FILES += \
 		test_focus_autocomplete.xul \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/events/a11y.ini
@@ -0,0 +1,50 @@
+[DEFAULT]
+support-files =
+  docload_wnd.html
+  focus.html
+  scroll.html
+
+[test_aria_alert.html]
+[test_aria_menu.html]
+[test_aria_objattr.html]
+[test_aria_statechange.html]
+[test_attrs.html]
+[test_caretmove.html]
+[test_caretmove.xul]
+[test_coalescence.html]
+[test_contextmenu.html]
+[test_docload.html]
+[test_docload.xul]
+[test_docload_aria.html]
+[test_dragndrop.html]
+[test_flush.html]
+[test_focus_aria_activedescendant.html]
+[test_focus_browserui.xul]
+[test_focus_canvas.html]
+[test_focus_contextmenu.xul]
+[test_focus_controls.html]
+[test_focus_dialog.html]
+[test_focus_doc.html]
+[test_focus_general.html]
+[test_focus_general.xul]
+[test_focus_listcontrols.xul]
+[test_focus_menu.xul]
+[test_focus_name.html]
+[test_focus_selects.html]
+[test_focus_tabbox.xul]
+[test_focus_tree.xul]
+[test_fromUserInput.html]
+[test_label.xul]
+[test_menu.xul]
+[test_mutation.html]
+[test_mutation.xhtml]
+[test_scroll.xul]
+[test_selection.html]
+[test_selection.xul]
+[test_selection_aria.html]
+[test_statechange.html]
+[test_text.html]
+[test_text_alg.html]
+[test_textattrchange.html]
+[test_tree.xul]
+[test_valuechange.html]
--- a/accessible/tests/mochitest/events/moz.build
+++ b/accessible/tests/mochitest/events/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/focus/Makefile.in
+++ b/accessible/tests/mochitest/focus/Makefile.in
@@ -1,10 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_focusedChild.html \
-		test_takeFocus.html \
-		test_takeFocus.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/focus/a11y.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+
+[test_focusedChild.html]
+[test_takeFocus.html]
+[test_takeFocus.xul]
--- a/accessible/tests/mochitest/focus/moz.build
+++ b/accessible/tests/mochitest/focus/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/hittest/Makefile.in
+++ b/accessible/tests/mochitest/hittest/Makefile.in
@@ -1,14 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		test_browser.html \
-		test_general.html \
-		test_menu.xul \
-		test_zoom_text.html \
-		test_zoom_tree.xul \
-		test_zoom.html \
-		zoom_tree.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hittest/a11y.ini
@@ -0,0 +1,9 @@
+[DEFAULT]
+support-files = zoom_tree.xul
+
+[test_browser.html]
+[test_general.html]
+[test_menu.xul]
+[test_zoom.html]
+[test_zoom_text.html]
+[test_zoom_tree.xul]
--- a/accessible/tests/mochitest/hittest/moz.build
+++ b/accessible/tests/mochitest/hittest/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/hyperlink/Makefile.in
+++ b/accessible/tests/mochitest/hyperlink/Makefile.in
@@ -1,10 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		hyperlink.js \
-		test_general.html \
-		test_general.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hyperlink/a11y.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+support-files = hyperlink.js
+
+[test_general.html]
+[test_general.xul]
--- a/accessible/tests/mochitest/hyperlink/moz.build
+++ b/accessible/tests/mochitest/hyperlink/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/hypertext/Makefile.in
+++ b/accessible/tests/mochitest/hypertext/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		test_general.html \
-		test_update.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hypertext/a11y.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_general.html]
+[test_update.html]
--- a/accessible/tests/mochitest/hypertext/moz.build
+++ b/accessible/tests/mochitest/hypertext/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/jsat/Makefile.in
+++ b/accessible/tests/mochitest/jsat/Makefile.in
@@ -1,16 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-jsatcommon.js \
-output.js \
-test_alive.html \
-test_braille.html \
-test_explicit_names.html \
-test_landmarks.html \
-test_live_regions.html \
-test_tables.html \
-test_utterance_order.html \
-$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/jsat/a11y.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+support-files =
+  jsatcommon.js
+  output.js
+
+[test_alive.html]
+[test_braille.html]
+[test_explicit_names.html]
+[test_landmarks.html]
+[test_live_regions.html]
+[test_tables.html]
+[test_utterance_order.html]
--- a/accessible/tests/mochitest/jsat/moz.build
+++ b/accessible/tests/mochitest/jsat/moz.build
@@ -1,4 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
\ No newline at end of file
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/name/Makefile.in
+++ b/accessible/tests/mochitest/name/Makefile.in
@@ -1,19 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		general.css \
-		general.xbl \
-		markup.js \
-		test_general.html \
-		test_general.xul \
-		test_link.html \
-		test_list.html \
-		test_markup.html \
-		test_svg.html \
-		test_tree.xul \
-		test_browserui.xul \
-		markuprules.xml \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/name/a11y.ini
@@ -0,0 +1,15 @@
+[DEFAULT]
+support-files =
+  general.css
+  general.xbl
+  markup.js
+  markuprules.xml
+
+[test_browserui.xul]
+[test_general.html]
+[test_general.xul]
+[test_link.html]
+[test_list.html]
+[test_markup.html]
+[test_svg.html]
+[test_tree.xul]
--- a/accessible/tests/mochitest/name/moz.build
+++ b/accessible/tests/mochitest/name/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/pivot/Makefile.in
+++ b/accessible/tests/mochitest/pivot/Makefile.in
@@ -1,11 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		doc_virtualcursor.html \
-		doc_virtualcursor_text.html \
-		test_virtualcursor.html \
-		test_virtualcursor_text.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/pivot/a11y.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+support-files =
+  doc_virtualcursor.html
+  doc_virtualcursor_text.html
+
+[test_virtualcursor.html]
+[test_virtualcursor_text.html]
--- a/accessible/tests/mochitest/pivot/moz.build
+++ b/accessible/tests/mochitest/pivot/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/relations/Makefile.in
+++ b/accessible/tests/mochitest/relations/Makefile.in
@@ -1,15 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_bindings.xhtml \
-		test_embeds.xul \
-		test_general.html \
-		test_general.xul \
-		test_tabbrowser.xul \
-		test_tree.xul \
-		test_ui_modalprompt.html \
-		test_update.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/relations/a11y.ini
@@ -0,0 +1,10 @@
+[DEFAULT]
+
+[test_bindings.xhtml]
+[test_embeds.xul]
+[test_general.html]
+[test_general.xul]
+[test_tabbrowser.xul]
+[test_tree.xul]
+[test_ui_modalprompt.html]
+[test_update.html]
--- a/accessible/tests/mochitest/relations/moz.build
+++ b/accessible/tests/mochitest/relations/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/role/Makefile.in
+++ b/accessible/tests/mochitest/role/Makefile.in
@@ -1,11 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_aria.html \
-		test_aria.xul \
-		test_general.html \
-		test_general.xul \
-		test_svg.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/role/a11y.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+
+[test_aria.html]
+[test_aria.xul]
+[test_general.html]
+[test_general.xul]
+[test_svg.html]
--- a/accessible/tests/mochitest/role/moz.build
+++ b/accessible/tests/mochitest/role/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/scroll/Makefile.in
+++ b/accessible/tests/mochitest/scroll/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_zoom_text.html \
-		test_zoom.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/scroll/a11y.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_zoom.html]
+[test_zoom_text.html]
--- a/accessible/tests/mochitest/scroll/moz.build
+++ b/accessible/tests/mochitest/scroll/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/selectable/Makefile.in
+++ b/accessible/tests/mochitest/selectable/Makefile.in
@@ -1,13 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_aria.html \
-		test_listbox.xul \
-		test_menu.xul \
-		test_menulist.xul \
-		test_select.html \
-		test_tree.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/selectable/a11y.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+
+[test_aria.html]
+[test_listbox.xul]
+[test_menu.xul]
+[test_menulist.xul]
+[test_select.html]
+[test_tree.xul]
--- a/accessible/tests/mochitest/selectable/moz.build
+++ b/accessible/tests/mochitest/selectable/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -1,34 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_aria.html \
-		test_aria_imgmap.html \
-		test_aria_widgetitems.html \
-		test_buttons.html \
-		test_controls.html \
-		test_controls.xul \
-		test_doc.html \
-		test_doc_busy.html \
-		test_docarticle.html \
-		test_editablebody.html \
-		test_expandable.xul \
-		test_frames.html \
-		test_inputs.html \
-		test_link.html \
-		test_popup.xul \
-		test_selects.html \
-		test_stale.html \
-		test_textbox.xul \
-		test_tabs.xul \
-		test_tree.xul \
-		test_visibility.html \
-		test_visibility.xul \
-		z_frames.html \
-		z_frames_article.html \
-		z_frames_checkbox.html \
-		z_frames_textbox.html \
-		z_frames_update.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/states/a11y.ini
@@ -0,0 +1,30 @@
+[DEFAULT]
+support-files =
+  z_frames.html
+  z_frames_article.html
+  z_frames_checkbox.html
+  z_frames_textbox.html
+  z_frames_update.html
+
+[test_aria.html]
+[test_aria_imgmap.html]
+[test_aria_widgetitems.html]
+[test_buttons.html]
+[test_controls.html]
+[test_controls.xul]
+[test_doc.html]
+[test_doc_busy.html]
+[test_docarticle.html]
+[test_editablebody.html]
+[test_expandable.xul]
+[test_frames.html]
+[test_inputs.html]
+[test_link.html]
+[test_popup.xul]
+[test_selects.html]
+[test_stale.html]
+[test_tabs.xul]
+[test_textbox.xul]
+[test_tree.xul]
+[test_visibility.html]
+[test_visibility.xul]
--- a/accessible/tests/mochitest/states/moz.build
+++ b/accessible/tests/mochitest/states/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/table/Makefile.in
+++ b/accessible/tests/mochitest/table/Makefile.in
@@ -1,27 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		test_headers_ariagrid.html \
-		test_headers_listbox.xul \
-		test_headers_table.html \
-		test_headers_tree.xul \
-		test_indexes_ariagrid.html \
-		test_indexes_listbox.xul \
-		test_indexes_table.html \
-		test_indexes_tree.xul \
-		test_layoutguess.html \
-		test_sels_ariagrid.html \
-		test_sels_listbox.xul \
-		test_sels_table.html \
-		test_sels_tree.xul \
-		test_struct_ariagrid.html \
-		test_struct_ariatreegrid.html \
-		test_struct_listbox.xul \
-		test_struct_table.html \
-		test_struct_tree.xul \
-		test_table_1.html \
-		test_table_2.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/table/a11y.ini
@@ -0,0 +1,22 @@
+[DEFAULT]
+
+[test_headers_ariagrid.html]
+[test_headers_listbox.xul]
+[test_headers_table.html]
+[test_headers_tree.xul]
+[test_indexes_ariagrid.html]
+[test_indexes_listbox.xul]
+[test_indexes_table.html]
+[test_indexes_tree.xul]
+[test_layoutguess.html]
+[test_sels_ariagrid.html]
+[test_sels_listbox.xul]
+[test_sels_table.html]
+[test_sels_tree.xul]
+[test_struct_ariagrid.html]
+[test_struct_ariatreegrid.html]
+[test_struct_listbox.xul]
+[test_struct_table.html]
+[test_struct_tree.xul]
+[test_table_1.html]
+[test_table_2.html]
--- a/accessible/tests/mochitest/table/moz.build
+++ b/accessible/tests/mochitest/table/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/text/Makefile.in
+++ b/accessible/tests/mochitest/text/Makefile.in
@@ -1,19 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		doc.html \
-		test_atcaretoffset.html \
-		test_charboundary.html \
-		test_doc.html \
-		test_general.xul \
-		test_gettext.html \
-		test_hypertext.html \
-		test_lineboundary.html \
-		test_passwords.html \
-		test_selection.html \
-		test_wordboundary.html \
-		test_words.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/text/a11y.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+support-files = doc.html
+
+[test_atcaretoffset.html]
+[test_charboundary.html]
+[test_doc.html]
+[test_general.xul]
+[test_gettext.html]
+[test_hypertext.html]
+[test_lineboundary.html]
+[test_passwords.html]
+[test_selection.html]
+[test_wordboundary.html]
+[test_words.html]
--- a/accessible/tests/mochitest/text/moz.build
+++ b/accessible/tests/mochitest/text/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/textattrs/Makefile.in
+++ b/accessible/tests/mochitest/textattrs/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_general.html \
-		test_invalid.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textattrs/a11y.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_general.html]
+[test_invalid.html]
--- a/accessible/tests/mochitest/textattrs/moz.build
+++ b/accessible/tests/mochitest/textattrs/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/textcaret/Makefile.in
+++ b/accessible/tests/mochitest/textcaret/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		test_browserui.xul \
-		test_general.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textcaret/a11y.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_browserui.xul]
+[test_general.html]
--- a/accessible/tests/mochitest/textcaret/moz.build
+++ b/accessible/tests/mochitest/textcaret/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/textselection/Makefile.in
+++ b/accessible/tests/mochitest/textselection/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES = \
-		test_general.html \
-		test_userinput.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textselection/a11y.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_general.html]
+[test_userinput.html]
--- a/accessible/tests/mochitest/textselection/moz.build
+++ b/accessible/tests/mochitest/textselection/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/treeupdate/Makefile.in
+++ b/accessible/tests/mochitest/treeupdate/Makefile.in
@@ -1,29 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_ariadialog.html \
-		test_canvas.html \
-		test_colorpicker.xul \
-		test_cssoverflow.html \
-		test_contextmenu.xul \
-		test_deck.xul \
-		test_doc.html \
-		test_gencontent.html \
-		test_hidden.html \
-		test_imagemap.html \
-		test_list_editabledoc.html \
-		test_list.html \
-		test_listbox.xul \
-		test_menu.xul \
-		test_menubutton.xul \
-	test_optgroup.html \
-		test_recreation.html \
-		test_select.html \
-		test_bug852150.xhtml \
-		test_textleaf.html \
-		test_visibility.html \
-		test_whitespace.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/treeupdate/a11y.ini
@@ -0,0 +1,24 @@
+[DEFAULT]
+
+[test_ariadialog.html]
+[test_bug852150.xhtml]
+[test_canvas.html]
+[test_colorpicker.xul]
+[test_contextmenu.xul]
+[test_cssoverflow.html]
+[test_deck.xul]
+[test_doc.html]
+[test_gencontent.html]
+[test_hidden.html]
+[test_imagemap.html]
+[test_list.html]
+[test_list_editabledoc.html]
+[test_listbox.xul]
+[test_menu.xul]
+[test_menubutton.xul]
+[test_optgroup.html]
+[test_recreation.html]
+[test_select.html]
+[test_textleaf.html]
+[test_visibility.html]
+[test_whitespace.html]
--- a/accessible/tests/mochitest/treeupdate/moz.build
+++ b/accessible/tests/mochitest/treeupdate/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/accessible/tests/mochitest/value/Makefile.in
+++ b/accessible/tests/mochitest/value/Makefile.in
@@ -1,11 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_A11Y_FILES =\
-		test_general.html \
-		test_progress.html \
-		test_progress.xul \
-		test_range.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/value/a11y.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+
+[test_general.html]
+[test_progress.html]
+[test_progress.xul]
+[test_range.html]
--- a/accessible/tests/mochitest/value/moz.build
+++ b/accessible/tests/mochitest/value/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+A11Y_MANIFESTS += ['a11y.ini']
+
--- a/browser/base/content/test/chrome/Makefile.in
+++ b/browser/base/content/test/chrome/Makefile.in
@@ -1,7 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_CHROME_FILES = \
-  test_aboutCrashed.xul \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/chrome/chrome.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[test_aboutCrashed.xul]
--- a/browser/base/content/test/chrome/moz.build
+++ b/browser/base/content/test/chrome/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/browser/base/content/test/general/Makefile.in
+++ b/browser/base/content/test/general/Makefile.in
@@ -1,41 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-        head_plain.js \
-        bug364677-data.xml \
-        bug364677-data.xml^headers^ \
-        bug395533-data.txt \
-        ctxmenu-image.png \
-        feed_discovery.html \
-        gZipOfflineChild.cacheManifest \
-        gZipOfflineChild.cacheManifest^headers^ \
-        gZipOfflineChild.html \
-        gZipOfflineChild.html^headers^ \
-        offlineChild.cacheManifest \
-        offlineChild.cacheManifest^headers^ \
-        offlineChild.html \
-        offlineChild2.cacheManifest \
-        offlineChild2.cacheManifest^headers^ \
-        offlineChild2.html \
-        offlineEvent.cacheManifest \
-        offlineEvent.cacheManifest^headers^ \
-        offlineEvent.html \
-        test_bug364677.html \
-        test_bug395533.html \
-        test_feed_discovery.html \
-        test_offline_gzip.html \
-        test_offlineNotification.html \
-        video.ogg \
-        offlineByDefault.js \
-        $(NULL)
-
 # test_contextmenu.html and test_contextmenu_input are disabled on Linux due to bug 513558
 ifndef MOZ_WIDGET_GTK
 MOCHITEST_FILES += \
         audio.ogg \
         privateBrowsingMode.js \
         subtst_contextmenu.html \
         contextmenu_common.js \
         test_contextmenu.html \
@@ -50,300 +21,16 @@ endif
 # browser_sanitizeDialog_treeView.js is disabled until the tree view is added
 # back to the clear recent history dialog (sanitize.xul), if it ever is (bug
 # 480169)
 
 # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
 
 # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
 
-MOCHITEST_BROWSER_FILES = \
-                 head.js \
-                 alltabslistener.html \
-                 app_bug575561.html \
-                 app_subframe_bug575561.html \
-                 authenticate.sjs \
-                 blockNoPlugins.xml \
-                 blockPluginHard.xml \
-                 blockPluginVulnerableNoUpdate.xml \
-                 blockPluginVulnerableUpdatable.xml \
-                 browser_aboutHealthReport.js \
-                 browser_aboutHome.js \
-                 browser_aboutSyncProgress.js \
-                 browser_addKeywordSearch.js \
-                 browser_addon_bar_aomlistener.js \
-                 browser_addon_bar_close_button.js \
-                 browser_addon_bar_shortcut.js \
-                 browser_alltabslistener.js \
-                 browser_blob-channelname.js \
-                 browser_bug304198.js \
-                 browser_bug329212.js \
-                 browser_bug356571.js \
-                 browser_bug380960.js \
-                 browser_bug386835.js \
-                 browser_bug405137.js \
-                 browser_bug406216.js \
-                 browser_bug409481.js \
-                 browser_bug409624.js \
-                 browser_bug413915.js \
-                 browser_bug416661.js \
-                 browser_bug417483.js \
-                 browser_bug419612.js \
-                 browser_bug422590.js \
-                 browser_bug424101.js \
-                 browser_bug427559.js \
-                 browser_bug432599.js \
-                 browser_bug435035.js \
-                 browser_bug435325.js \
-                 browser_bug441778.js \
-                 browser_bug455852.js \
-                 browser_bug460146.js \
-                 browser_bug462673.js \
-                 browser_bug477014.js \
-                 browser_bug479408_sample.html \
-                 browser_bug479408.js \
-                 browser_bug481560.js \
-                 browser_bug484315.js \
-                 browser_bug491431.js \
-                 browser_bug495058.js \
-                 browser_bug517902.js \
-                 browser_bug519216.js \
-                 browser_bug520538.js \
-                 browser_bug521216.js \
-                 browser_bug533232.js \
-                 browser_bug537013.js \
-                 browser_bug537474.js \
-                 browser_bug550565.js \
-                 browser_bug553455.js \
-                 browser_bug555224.js \
-                 browser_bug555767.js \
-                 browser_bug556061.js \
-                 browser_bug559991.js \
-                 browser_bug561623.js \
-                 browser_bug561636.js \
-                 browser_bug562649.js \
-                 browser_bug563588.js \
-                 browser_bug565575.js \
-                 browser_bug567306.js \
-                 browser_bug575561.js \
-                 browser_bug575830.js \
-                 browser_bug577121.js \
-                 browser_bug578534.js \
-                 browser_bug579872.js \
-                 browser_bug580638.js \
-                 browser_bug580956.js \
-                 browser_bug581242.js \
-                 browser_bug581253.js \
-                 browser_bug581947.js \
-                 browser_bug585558.js \
-                 browser_bug585785.js \
-                 browser_bug585830.js \
-                 browser_bug590206.js \
-                 browser_bug592338.js \
-                 browser_bug594131.js \
-                 browser_bug595507.js \
-                 browser_bug596687.js \
-                 browser_bug597218.js \
-                 browser_bug598923.js \
-                 browser_bug599325.js \
-                 browser_bug609700.js \
-                 browser_bug616836.js \
-                 browser_bug623155.js \
-                 browser_bug623893.js \
-                 browser_bug624734.js \
-                 browser_bug647886.js \
-                 browser_bug655584.js \
-                 browser_bug664672.js \
-                 browser_bug676619.js \
-                 browser_bug678392-1.html \
-                 browser_bug678392-2.html \
-                 browser_bug678392.js \
-                 browser_bug710878.js \
-                 browser_bug719271.js \
-                 browser_bug724239.js \
-                 browser_bug734076.js \
-                 browser_bug735471.js \
-                 browser_bug743421.js \
-                 browser_bug744745.js \
-                 browser_bug749738.js \
-                 browser_bug752516.js \
-                 browser_bug763468_perwindowpb.js \
-                 browser_bug767836_perwindowpb.js \
-                 browser_bug771331.js \
-                 browser_bug783614.js \
-                 browser_bug787619.js \
-                 browser_bug797677.js \
-                 browser_bug812562.js \
-                 browser_bug816527.js \
-                 browser_bug817947.js \
-                 browser_bug818118.js \
-                 browser_bug820497.js \
-                 browser_bug822367.js \
-                 browser_bug902156.js \
-                 browser_bug832435.js \
-                 browser_bug839103.js \
-                 browser_bug880101.js \
-                 browser_bug882977.js \
-                 browser_bug887515.js \
-                 browser_canonizeURL.js \
-                 browser_mixedcontent_securityflags.js \
-                 browser_clearplugindata_noage.html \
-                 browser_clearplugindata.html \
-                 browser_clearplugindata.js \
-                 browser_contentAreaClick.js \
-                 browser_contextSearchTabPosition.js \
-                 browser_CTP_drag_drop.js \
-                 browser_CTP_data_urls.js \
-                 browser_CTP_nonplugins.js \
-                 browser_CTP_resize.js \
-                 browser_ctrlTab.js \
-                 browser_customize_popupNotification.js \
-                 browser_customize.js \
-                 browser_disablechrome.js \
-                 browser_discovery.js \
-                 browser_duplicateIDs.js \
-                 browser_findbarClose.js \
-                 browser_fullscreen-window-open.js \
-                 browser_gestureSupport.js \
-                 browser_getshortcutoruri.js \
-                 browser_hide_removing.js \
-                 browser_homeDrop.js \
-                 browser_identity_UI.js \
-                 browser_keywordBookmarklets.js \
-                 browser_keywordSearch_postData.js \
-                 browser_keywordSearch.js \
-                 browser_lastAccessedTab.js \
-                 browser_locationBarCommand.js \
-                 browser_locationBarExternalLoad.js \
-                 browser_middleMouse_inherit.js \
-                 browser_minimize.js \
-                 browser_offlineQuotaNotification.js \
-                 browser_overflowScroll.js \
-                 browser_page_style_menu.js \
-                 browser_pageInfo_plugins.js \
-                 browser_pageInfo.js \
-                 browser_pinnedTabs.js \
-                 browser_plainTextLinks.js \
-                 browser_pluginnotification.js \
-                 browser_pluginplaypreview.js \
-                 browser_pluginplaypreview2.js \
-                 browser_plugins_added_dynamically.js \
-                 browser_popupUI.js \
-                 browser_private_browsing_window.js \
-                 browser_private_no_prompt.js \
-                 browser_relatedTabs.js \
-                 browser_removeTabsToTheEnd.js \
-                 browser_sanitize-passwordDisabledHosts.js \
-                 browser_sanitize-sitepermissions.js \
-                 browser_sanitize-timespans.js \
-                 browser_sanitizeDialog.js \
-                 browser_save_link-perwindowpb.js \
-                 browser_save_private_link_perwindowpb.js \
-                 browser_save_video.js \
-                 browser_scope.js \
-                 browser_selectTabAtIndex.js \
-                 browser_tab_drag_drop_perwindow.js \
-                 browser_tab_dragdrop.js \
-                 browser_tab_dragdrop2_frame1.xul \
-                 browser_tab_dragdrop2.js \
-                 browser_tabDrop.js \
-                 browser_tabfocus.js \
-                 browser_tabMatchesInAwesomebar_perwindowpb.js \
-                 browser_tabopen_reflows.js \
-                 browser_tabs_isActive.js \
-                 browser_tabs_owner.js \
-                 browser_typeAheadFind.js \
-                 browser_unloaddialogs.js \
-                 browser_urlbar_search_healthreport.js \
-                 browser_urlbarAutoFillTrimURLs.js \
-                 browser_urlbarCopying.js \
-                 browser_urlbarEnter.js \
-                 browser_urlbarRevert.js \
-                 browser_URLBarSetURI.js \
-                 browser_urlbarStop.js \
-                 browser_urlbarTrimURLs.js \
-                 browser_urlHighlight.js \
-                 browser_utilityOverlay.js \
-                 browser_visibleFindSelection.js \
-                 browser_visibleTabs_bookmarkAllPages.js \
-                 browser_visibleTabs_bookmarkAllTabs.js \
-                 browser_visibleTabs_contextMenu.js \
-                 browser_visibleTabs_tabPreview.js \
-                 browser_visibleTabs.js \
-                 browser_wyciwyg_urlbarCopying.js \
-                 browser_zbug569342.js \
-                 bug564387_video1.ogv \
-                 bug564387_video1.ogv^headers^ \
-                 bug564387.html \
-                 bug592338.html \
-                 bug792517-2.html \
-                 bug792517.html \
-                 bug792517.sjs \
-                 bug839103.css \
-                 disablechrome.html \
-                 discovery.html \
-                 domplate_test.js \
-                 download_page.html \
-                 dummy_page.html \
-                 feed_tab.html \
-                 file_bug550565_favicon.ico \
-                 file_bug550565_popup.html \
-                 file_bug822367_1.html \
-                 file_bug822367_1.js \
-                 file_bug822367_2.html \
-                 file_bug822367_3.html \
-                 file_bug822367_4.html \
-                 file_bug822367_4.js \
-                 file_bug822367_4B.html \
-                 file_bug822367_5.html \
-                 file_bug822367_6.html \
-                 file_bug902156_1.html \
-                 file_bug902156_2.html \
-                 file_bug902156_3.html \
-                 file_bug902156.js \
-                 file_fullscreen-window-open.html \
-                 healthreport_testRemoteCommands.html \
-                 moz.png \
-                 offlineQuotaNotification.cacheManifest \
-                 offlineQuotaNotification.html \
-                 page_style_sample.html \
-                 plugin_add_dynamically.html \
-                 plugin_alternate_content.html \
-                 plugin_both.html \
-                 plugin_both2.html \
-                 plugin_bug744745.html \
-                 plugin_bug749455.html \
-                 plugin_bug752516.html \
-                 plugin_bug787619.html \
-                 plugin_bug797677.html \
-                 plugin_bug820497.html \
-                 plugin_clickToPlayAllow.html \
-                 plugin_clickToPlayDeny.html \
-                 plugin_hidden_to_visible.html \
-                 plugin_small.html \
-                 plugin_test.html \
-                 plugin_test2.html \
-                 plugin_test3.html \
-                 plugin_two_types.html \
-                 plugin_data_url.html \
-                 plugin_unknown.html \
-                 POSTSearchEngine.xml \
-                 print_postdata.sjs \
-                 redirect_bug623155.sjs \
-                 test_bug435035.html \
-                 test_bug462673.html \
-                 test_bug628179.html \
-                 test_bug839103.html \
-                 test_wyciwyg_copying.html \
-                 test-mixedcontent-securityerrors.html \
-                 title_test.svg \
-                 video.ogg \
-                 zoom_test.html \
-                 $(NULL)
-
 # Disable tests on Windows due to frequent failures (bugs 825739, 841341)
 ifneq (windows,$(MOZ_WIDGET_TOOLKIT))
 MOCHITEST_BROWSER_FILES += \
                  browser_bookmark_titles.js \
                  browser_popupNotification.js \
                  $(NULL)
 endif
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser.ini
@@ -0,0 +1,284 @@
+[DEFAULT]
+support-files =
+  POSTSearchEngine.xml
+  alltabslistener.html
+  app_bug575561.html
+  app_subframe_bug575561.html
+  authenticate.sjs
+  blockNoPlugins.xml
+  blockPluginHard.xml
+  blockPluginVulnerableNoUpdate.xml
+  blockPluginVulnerableUpdatable.xml
+  bug564387.html
+  bug564387_video1.ogv
+  bug564387_video1.ogv^headers^
+  bug592338.html
+  bug792517-2.html
+  bug792517.html
+  bug792517.sjs
+  bug839103.css
+  disablechrome.html
+  discovery.html
+  domplate_test.js
+  download_page.html
+  dummy_page.html
+  feed_tab.html
+  file_bug550565_favicon.ico
+  file_bug550565_popup.html
+  file_bug822367_1.html
+  file_bug822367_1.js
+  file_bug822367_2.html
+  file_bug822367_3.html
+  file_bug822367_4.html
+  file_bug822367_4.js
+  file_bug822367_4B.html
+  file_bug822367_5.html
+  file_bug822367_6.html
+  file_bug902156.js
+  file_bug902156_1.html
+  file_bug902156_2.html
+  file_bug902156_3.html
+  file_fullscreen-window-open.html
+  head.js
+  healthreport_testRemoteCommands.html
+  moz.png
+  offlineQuotaNotification.cacheManifest
+  offlineQuotaNotification.html
+  page_style_sample.html
+  plugin_add_dynamically.html
+  plugin_alternate_content.html
+  plugin_both.html
+  plugin_both2.html
+  plugin_bug744745.html
+  plugin_bug749455.html
+  plugin_bug752516.html
+  plugin_bug787619.html
+  plugin_bug797677.html
+  plugin_bug820497.html
+  plugin_clickToPlayAllow.html
+  plugin_clickToPlayDeny.html
+  plugin_data_url.html
+  plugin_hidden_to_visible.html
+  plugin_small.html
+  plugin_test.html
+  plugin_test2.html
+  plugin_test3.html
+  plugin_two_types.html
+  plugin_unknown.html
+  print_postdata.sjs
+  redirect_bug623155.sjs
+  test-mixedcontent-securityerrors.html
+  test_bug435035.html
+  test_bug462673.html
+  test_bug628179.html
+  test_bug839103.html
+  test_wyciwyg_copying.html
+  title_test.svg
+  video.ogg
+  zoom_test.html
+
+[browser_CTP_data_urls.js]
+[browser_CTP_drag_drop.js]
+[browser_CTP_nonplugins.js]
+[browser_CTP_resize.js]
+[browser_URLBarSetURI.js]
+[browser_aboutHealthReport.js]
+[browser_aboutHome.js]
+[browser_aboutSyncProgress.js]
+[browser_addKeywordSearch.js]
+[browser_addon_bar_aomlistener.js]
+[browser_addon_bar_close_button.js]
+[browser_addon_bar_shortcut.js]
+[browser_alltabslistener.js]
+[browser_blob-channelname.js]
+[browser_bug304198.js]
+[browser_bug329212.js]
+[browser_bug356571.js]
+[browser_bug380960.js]
+[browser_bug386835.js]
+[browser_bug405137.js]
+[browser_bug406216.js]
+[browser_bug409481.js]
+[browser_bug409624.js]
+[browser_bug413915.js]
+[browser_bug416661.js]
+[browser_bug417483.js]
+[browser_bug419612.js]
+[browser_bug422590.js]
+[browser_bug424101.js]
+[browser_bug427559.js]
+[browser_bug432599.js]
+[browser_bug435035.js]
+[browser_bug435325.js]
+[browser_bug441778.js]
+[browser_bug455852.js]
+[browser_bug460146.js]
+[browser_bug462673.js]
+[browser_bug477014.js]
+[browser_bug479408.js]
+[browser_bug479408_sample.html]
+[browser_bug481560.js]
+[browser_bug484315.js]
+[browser_bug491431.js]
+[browser_bug495058.js]
+[browser_bug517902.js]
+[browser_bug519216.js]
+[browser_bug520538.js]
+[browser_bug521216.js]
+[browser_bug533232.js]
+[browser_bug537013.js]
+[browser_bug537474.js]
+[browser_bug550565.js]
+[browser_bug553455.js]
+[browser_bug555224.js]
+[browser_bug555767.js]
+[browser_bug556061.js]
+[browser_bug559991.js]
+[browser_bug561623.js]
+[browser_bug561636.js]
+[browser_bug562649.js]
+[browser_bug563588.js]
+[browser_bug565575.js]
+[browser_bug567306.js]
+[browser_bug575561.js]
+[browser_bug575830.js]
+[browser_bug577121.js]
+[browser_bug578534.js]
+[browser_bug579872.js]
+[browser_bug580638.js]
+[browser_bug580956.js]
+[browser_bug581242.js]
+[browser_bug581253.js]
+[browser_bug581947.js]
+[browser_bug585558.js]
+[browser_bug585785.js]
+[browser_bug585830.js]
+[browser_bug590206.js]
+[browser_bug592338.js]
+[browser_bug594131.js]
+[browser_bug595507.js]
+[browser_bug596687.js]
+[browser_bug597218.js]
+[browser_bug598923.js]
+[browser_bug599325.js]
+[browser_bug609700.js]
+[browser_bug616836.js]
+[browser_bug623155.js]
+[browser_bug623893.js]
+[browser_bug624734.js]
+[browser_bug647886.js]
+[browser_bug655584.js]
+[browser_bug664672.js]
+[browser_bug676619.js]
+[browser_bug678392-1.html]
+[browser_bug678392-2.html]
+[browser_bug678392.js]
+[browser_bug710878.js]
+[browser_bug719271.js]
+[browser_bug724239.js]
+[browser_bug734076.js]
+[browser_bug735471.js]
+[browser_bug743421.js]
+[browser_bug744745.js]
+[browser_bug749738.js]
+[browser_bug752516.js]
+[browser_bug763468_perwindowpb.js]
+[browser_bug767836_perwindowpb.js]
+[browser_bug771331.js]
+[browser_bug783614.js]
+[browser_bug787619.js]
+[browser_bug797677.js]
+[browser_bug812562.js]
+[browser_bug816527.js]
+[browser_bug817947.js]
+[browser_bug818118.js]
+[browser_bug820497.js]
+[browser_bug822367.js]
+[browser_bug832435.js]
+[browser_bug839103.js]
+[browser_bug880101.js]
+[browser_bug882977.js]
+[browser_bug887515.js]
+[browser_bug902156.js]
+[browser_canonizeURL.js]
+[browser_clearplugindata.html]
+[browser_clearplugindata.js]
+[browser_clearplugindata_noage.html]
+[browser_contentAreaClick.js]
+[browser_contextSearchTabPosition.js]
+[browser_ctrlTab.js]
+[browser_customize.js]
+[browser_customize_popupNotification.js]
+[browser_disablechrome.js]
+[browser_discovery.js]
+[browser_duplicateIDs.js]
+[browser_findbarClose.js]
+[browser_fullscreen-window-open.js]
+[browser_gestureSupport.js]
+[browser_getshortcutoruri.js]
+[browser_hide_removing.js]
+[browser_homeDrop.js]
+[browser_identity_UI.js]
+[browser_keywordBookmarklets.js]
+[browser_keywordSearch.js]
+[browser_keywordSearch_postData.js]
+[browser_lastAccessedTab.js]
+[browser_locationBarCommand.js]
+[browser_locationBarExternalLoad.js]
+[browser_middleMouse_inherit.js]
+[browser_minimize.js]
+[browser_mixedcontent_securityflags.js]
+[browser_offlineQuotaNotification.js]
+[browser_overflowScroll.js]
+[browser_pageInfo.js]
+[browser_pageInfo_plugins.js]
+[browser_page_style_menu.js]
+[browser_pinnedTabs.js]
+[browser_plainTextLinks.js]
+[browser_pluginnotification.js]
+[browser_pluginplaypreview.js]
+[browser_pluginplaypreview2.js]
+[browser_plugins_added_dynamically.js]
+[browser_popupUI.js]
+[browser_private_browsing_window.js]
+[browser_private_no_prompt.js]
+[browser_relatedTabs.js]
+[browser_removeTabsToTheEnd.js]
+[browser_sanitize-passwordDisabledHosts.js]
+[browser_sanitize-sitepermissions.js]
+[browser_sanitize-timespans.js]
+[browser_sanitizeDialog.js]
+[browser_save_link-perwindowpb.js]
+[browser_save_private_link_perwindowpb.js]
+[browser_save_video.js]
+[browser_scope.js]
+[browser_selectTabAtIndex.js]
+[browser_tabDrop.js]
+[browser_tabMatchesInAwesomebar_perwindowpb.js]
+[browser_tab_drag_drop_perwindow.js]
+[browser_tab_dragdrop.js]
+[browser_tab_dragdrop2.js]
+[browser_tab_dragdrop2_frame1.xul]
+[browser_tabfocus.js]
+[browser_tabopen_reflows.js]
+[browser_tabs_isActive.js]
+[browser_tabs_owner.js]
+[browser_typeAheadFind.js]
+[browser_unloaddialogs.js]
+[browser_urlHighlight.js]
+[browser_urlbarAutoFillTrimURLs.js]
+[browser_urlbarCopying.js]
+[browser_urlbarEnter.js]
+[browser_urlbarRevert.js]
+[browser_urlbarStop.js]
+[browser_urlbarTrimURLs.js]
+[browser_urlbar_search_healthreport.js]
+[browser_utilityOverlay.js]
+[browser_visibleFindSelection.js]
+[browser_visibleTabs.js]
+[browser_visibleTabs_bookmarkAllPages.js]
+[browser_visibleTabs_bookmarkAllTabs.js]
+[browser_visibleTabs_contextMenu.js]
+[browser_visibleTabs_tabPreview.js]
+[browser_wyciwyg_urlbarCopying.js]
+[browser_zbug569342.js]
--- a/browser/base/content/test/general/browser_CTP_context_menu.js
+++ b/browser/base/content/test/general/browser_CTP_context_menu.js
@@ -8,27 +8,26 @@ var gPluginHost = Components.classes["@m
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
-    getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
 
   let newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_test.html");
 }
 
 function finishTest() {
   clearAllPluginPermissions();
   gTestBrowser.removeEventListener("load", pageLoad, true);
   gBrowser.removeCurrentTab();
--- a/browser/base/content/test/general/browser_CTP_data_urls.js
+++ b/browser/base/content/test/general/browser_CTP_data_urls.js
@@ -54,29 +54,27 @@ TabOpenListener.prototype = {
   }
 };
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
-    getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-    getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-  getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
 
   prepareTest(test1a, gHttpTestRoot + "plugin_data_url.html");
 }
 
 function finishTest() {
   clearAllPluginPermissions();
   gTestBrowser.removeEventListener("load", pageLoad, true);
   gBrowser.removeCurrentTab();
--- a/browser/base/content/test/general/browser_CTP_drag_drop.js
+++ b/browser/base/content/test/general/browser_CTP_drag_drop.js
@@ -8,22 +8,19 @@ let gNewWindow = null;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     Services.prefs.clearUserPref("plugins.click_to_play");
-    let plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  let plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("PluginBindingAttached", handleEvent, true, true);
   gNextTest = part1;
   gBrowser.selectedBrowser.contentDocument.location = gHttpTestRoot + "plugin_test.html";
 }
 
 function handleEvent() {
--- a/browser/base/content/test/general/browser_bug743421.js
+++ b/browser/base/content/test/general/browser_bug743421.js
@@ -5,22 +5,19 @@ var gNextTest = null;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     Services.prefs.clearUserPref("plugins.click_to_play");
-    var plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   prepareTest(test1a, gTestRoot + "plugin_add_dynamically.html");
 }
 
--- a/browser/base/content/test/general/browser_bug744745.js
+++ b/browser/base/content/test/general/browser_bug744745.js
@@ -6,26 +6,23 @@ var gTestBrowser = null;
 var gNumPluginBindingsAttached = 0;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("plugins.click_to_play");
-    var plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
     gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
     gBrowser.removeCurrentTab();
     window.focus();
   });
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
   var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
   gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug744745.html";
 }
 
--- a/browser/base/content/test/general/browser_bug752516.js
+++ b/browser/base/content/test/general/browser_bug752516.js
@@ -5,25 +5,22 @@
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var gTestBrowser = null;
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("plugins.click_to_play");
-    let plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
     gBrowser.removeCurrentTab();
     window.focus();
   });
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  let plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
   let gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
   gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug752516.html";
 
   gTestBrowser.addEventListener("load", tabLoad, true);
 }
--- a/browser/base/content/test/general/browser_bug787619.js
+++ b/browser/base/content/test/general/browser_bug787619.js
@@ -2,22 +2,19 @@ const gHttpTestRoot = getRootDirectory(g
 
 let gTestBrowser = null;
 let gWrapperClickCount = 0;
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("plugins.click_to_play");
-    let plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  let plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug787619.html";
 }
 
 function pageLoad() {
--- a/browser/base/content/test/general/browser_bug812562.js
+++ b/browser/base/content/test/general/browser_bug812562.js
@@ -3,22 +3,19 @@ var gTestBrowser = null;
 var gNextTest = null;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("plugins.click_to_play");
-    var plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml",
   function() {
     prepareTest(function() {
--- a/browser/base/content/test/general/browser_bug818118.js
+++ b/browser/base/content/test/general/browser_bug818118.js
@@ -2,24 +2,21 @@ var gHttpTestRoot = getRootDirectory(gTe
 var gTestBrowser = null;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("plugins.click_to_play");
-    var plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
     gTestBrowser.removeEventListener("load", pageLoad, true);
   });
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_both.html";
 }
 
 function pageLoad(aEvent) {
--- a/browser/base/content/test/general/browser_bug820497.js
+++ b/browser/base/content/test/general/browser_bug820497.js
@@ -6,26 +6,24 @@ var gTestBrowser = null;
 var gNumPluginBindingsAttached = 0;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     Services.prefs.clearUserPref("plugins.click_to_play");
-    getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-    getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
     gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
     gBrowser.removeCurrentTab();
     window.focus();
   });
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-  getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
 
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
   var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
   gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug820497.html";
 }
 
--- a/browser/base/content/test/general/browser_clearplugindata.js
+++ b/browser/base/content/test/general/browser_clearplugindata.js
@@ -11,17 +11,17 @@ let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
 let Sanitizer = tempScope.Sanitizer;
 
 const pluginHostIface = Ci.nsIPluginHost;
 var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
 pluginHost.QueryInterface(pluginHostIface);
 
-var pluginTag;
+var pluginTag = getTestPlugin();
 var s;
 
 function stored(needles) {
   var something = pluginHost.siteHasData(this.pluginTag, null);
   if (!needles)
     return something;
 
   if (!something)
@@ -31,27 +31,17 @@ function stored(needles) {
     if (!pluginHost.siteHasData(this.pluginTag, needles[i]))
       return false;
   }
   return true;
 }
 
 function test() {
   waitForExplicitFinish();
-
-  var tags = pluginHost.getPluginTags();
-
-  // Find the test plugin
-  for (var i = 0; i < tags.length; i++)
-  {
-    if (tags[i].name == "Test Plug-in")
-    {
-      pluginTag = tags[i];
-    }
-  }
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
 
   s = new Sanitizer();
   s.ignoreTimespan = false;
   s.prefDomain = "privacy.cpd.";
   var itemPrefs = gPrefService.getBranch(s.prefDomain);
   itemPrefs.setBoolPref("history", false);
   itemPrefs.setBoolPref("downloads", false);
   itemPrefs.setBoolPref("cache", false);
--- a/browser/base/content/test/general/browser_pageInfo_plugins.js
+++ b/browser/base/content/test/general/browser_pageInfo_plugins.js
@@ -36,27 +36,25 @@ function pageInfoObserve(win, topic, dat
   Services.obs.removeObserver(pageInfoObserve, "page-info-dialog-loaded");
   executeSoon(gNextTest);
 }
 
 function finishTest() {
   gPermissionManager.remove("127.0.0.1:8888", gTestPermissionString);
   gPermissionManager.remove("127.0.0.1:8888", gSecondTestPermissionString);
   Services.prefs.clearUserPref("plugins.click_to_play");
-  getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-  getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   gBrowser.removeCurrentTab();
   finish();
 }
 
 function test() {
   waitForExplicitFinish();
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-  getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
   gBrowser.selectedTab = gBrowser.addTab();
   gTestBrowser = gBrowser.selectedBrowser;
   gPermissionManager.remove("127.0.0.1:8888", gTestPermissionString);
   gPermissionManager.remove("127.0.0.1:8888", gSecondTestPermissionString);
   doOnPageLoad(gHttpTestRoot + "plugin_two_types.html", testPart1a);
 }
 
 // The first test plugin is CtP and the second test plugin is enabled.
--- a/browser/base/content/test/general/browser_pluginCrashCommentAndURL.js
+++ b/browser/base/content/test/general/browser_pluginCrashCommentAndURL.js
@@ -7,16 +7,17 @@ Cu.import("resource://gre/modules/Servic
 const CRASH_URL = "http://example.com/browser/browser/base/content/test/general/pluginCrashCommentAndURL.html";
 
 const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
 
 function test() {
   // Crashing the plugin takes up a lot of time, so extend the test timeout.
   requestLongerTimeout(runs.length);
   waitForExplicitFinish();
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
 
   // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
   // crash reports.  This test needs them enabled.  The test also needs a mock
   // report server, and fortunately one is already set up by toolkit/
   // crashreporter/test/Makefile.in.  Assign its URL to MOZ_CRASHREPORTER_URL,
   // which CrashSubmit.jsm uses as a server override.
   let env = Cc["@mozilla.org/process/environment;1"].
             getService(Components.interfaces.nsIEnvironment);
--- a/browser/base/content/test/general/browser_pluginnotification.js
+++ b/browser/base/content/test/general/browser_pluginnotification.js
@@ -55,23 +55,21 @@ TabOpenListener.prototype = {
 };
 
 function test() {
   waitForExplicitFinish();
   requestLongerTimeout(2);
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
-    getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-    getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
 
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   prepareTest(runAfterPluginBindingAttached(test1), gTestRoot + "plugin_unknown.html");
 }
 
--- a/browser/base/content/test/general/browser_pluginplaypreview.js
+++ b/browser/base/content/test/general/browser_pluginplaypreview.js
@@ -134,26 +134,25 @@ Components.utils.import("resource://gre/
 
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     if (gPlayPreviewRegistration)
       gPlayPreviewRegistration.unregister();
     Services.prefs.clearUserPref("plugins.click_to_play");
-    var plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
 
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
   registerPlayPreview('application/x-test', 'about:');
   prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
 }
 
 function finishTest() {
   gTestBrowser.removeEventListener("load", pageLoad, true);
   gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
   gBrowser.removeCurrentTab();
@@ -250,18 +249,17 @@ function test3() {
   var plugin = gTestBrowser.contentDocument.getElementById("test");
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(objLoadingContent.activated, "Test 3, Plugin should be activated");
 
   unregisterPlayPreview();
 
   registerPlayPreview('application/x-test', 'about:');
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
   prepareTest(test4a, gTestRoot + "plugin_test.html", 1);
 }
 
 // Test a fallback to the click-to-play
 function test4a() {
   var doc = gTestBrowser.contentDocument;
   var plugin = doc.getElementById("test");
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
--- a/browser/base/content/test/general/browser_pluginplaypreview2.js
+++ b/browser/base/content/test/general/browser_pluginplaypreview2.js
@@ -34,29 +34,26 @@ Components.utils.import("resource://gre/
 
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     if (gPlayPreviewRegistration)
       gPlayPreviewRegistration.unregister();
     Services.prefs.clearUserPref("plugins.click_to_play");
-    var plugin = getTestPlugin();
-    plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
 
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  var plugin = getTestPlugin();
-  plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   registerPlayPreview('application/x-test', 'about:');
   prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
 }
 
 function finishTest() {
   gTestBrowser.removeEventListener("load", pageLoad, true);
   gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
--- a/browser/base/content/test/general/browser_plugins_added_dynamically.js
+++ b/browser/base/content/test/general/browser_plugins_added_dynamically.js
@@ -12,22 +12,20 @@ function addPlugin(browser, type) {
   contentWindow.addPlugin(type);
 }
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     Services.prefs.clearUserPref("plugins.click_to_play");
-    getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
-    getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
   Services.prefs.setBoolPref("plugins.click_to_play", true);
-  getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-  getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Second Test Plug-in");
 
   let newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
   gTestBrowser = gBrowser.selectedBrowser;
   gTestBrowser.addEventListener("load", pageLoad, true);
   prepareTest(testActivateAddSameTypePart1, gTestRoot + "plugin_add_dynamically.html");
 }
 
--- a/browser/base/content/test/general/browser_tab_dragdrop.js
+++ b/browser/base/content/test/general/browser_tab_dragdrop.js
@@ -1,13 +1,14 @@
 function test()
 {
   var embed = '<embed type="application/x-test" allowscriptaccess="always" allowfullscreen="true" wmode="window" width="640" height="480"></embed>'
 
   waitForExplicitFinish();
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
 
   // create a few tabs
   var tabs = [
     gBrowser.tabs[0],
     gBrowser.addTab("about:blank", {skipAnimation: true}),
     gBrowser.addTab("about:blank", {skipAnimation: true}),
     gBrowser.addTab("about:blank", {skipAnimation: true}),
     gBrowser.addTab("about:blank", {skipAnimation: true})
--- a/browser/base/content/test/general/head_plain.js
+++ b/browser/base/content/test/general/head_plain.js
@@ -1,15 +1,27 @@
 
-function waitForCondition(condition, nextTest, errorMsg) {
-  var tries = 0;
-  var interval = setInterval(function() {
-    if (tries >= 30) {
-      ok(false, errorMsg);
-      moveOn();
+function getTestPlugin(pluginName) {
+  var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
+                                 .getService(SpecialPowers.Ci.nsIPluginHost);
+  var tags = ph.getPluginTags();
+  var name = pluginName || "Test Plug-in";
+  for (var tag of tags) {
+    if (tag.name == name) {
+      return tag;
     }
-    if (condition()) {
-      moveOn();
-    }
-    tries++;
-  }, 100);
-  var moveOn = function() { clearInterval(interval); nextTest(); };
+  }
+
+  ok(false, "Could not find plugin tag with plugin name '" + name + "'");
+  return null;
 }
+
+// call this to set the test plugin(s) initially expected enabled state.
+// it will automatically be reset to it's previous value after the test
+// ends
+function setTestPluginEnabledState(newEnabledState, pluginName) {
+  var plugin = getTestPlugin(pluginName);
+  var oldEnabledState = plugin.enabledState;
+  plugin.enabledState = newEnabledState;
+  SimpleTest.registerCleanupFunction(function() {
+    getTestPlugin(pluginName).enabledState = oldEnabledState;
+  });
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/mochitest.ini
@@ -0,0 +1,29 @@
+[DEFAULT]
+support-files =
+  bug364677-data.xml
+  bug364677-data.xml^headers^
+  bug395533-data.txt
+  ctxmenu-image.png
+  feed_discovery.html
+  gZipOfflineChild.cacheManifest
+  gZipOfflineChild.cacheManifest^headers^
+  gZipOfflineChild.html
+  gZipOfflineChild.html^headers^
+  head_plain.js
+  offlineByDefault.js
+  offlineChild.cacheManifest
+  offlineChild.cacheManifest^headers^
+  offlineChild.html
+  offlineChild2.cacheManifest
+  offlineChild2.cacheManifest^headers^
+  offlineChild2.html
+  offlineEvent.cacheManifest
+  offlineEvent.cacheManifest^headers^
+  offlineEvent.html
+  video.ogg
+
+[test_bug364677.html]
+[test_bug395533.html]
+[test_feed_discovery.html]
+[test_offlineNotification.html]
+[test_offline_gzip.html]
--- a/browser/base/content/test/general/moz.build
+++ b/browser/base/content/test/general/moz.build
@@ -1,6 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/base/content/test/general/test_contextmenu.html
+++ b/browser/base/content/test/general/test_contextmenu.html
@@ -1,15 +1,16 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Tests for browser context menu</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="head_plain.js"></script>
 </head>
 <body>
 Browser context menu tests.
 <p id="display"></p>
 
 <div id="content">
 </div>
 
@@ -698,24 +699,17 @@ function runTest(testNum) {
                           "context-viewbgimage",  false,
                           "context-selectall",    true,
                           "---",                  null,
                           "context-viewsource",   true,
                           "context-viewinfo",     true
                          ].concat(inspectItems));
         closeContextMenu();
         SpecialPowers.clearUserPref("plugins.click_to_play");
-        var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
-                                 .getService(SpecialPowers.Ci.nsIPluginHost);
-        var tags = ph.getPluginTags();
-        for (var tag of tags) {
-          if (tag.name == "Test Plug-in") {
-            tag.enabledState = SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED;
-          }
-        }
+        getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
         openContextMenuFor(longdesc);
         return;
 
     case 28:
         // Context menu for an image with longdesc
         checkContextMenu(["context-viewimage",            true,
                           "context-copyimage-contents",   true,
                           "context-copyimage",            true,
@@ -876,24 +870,17 @@ function waitForEvents(event)
 }
 
 const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
 
 if (isOSXMtnLion) {
   todo(false, "Mountain Lion doesn't like this test (bug 792304)");
 } else {
   SpecialPowers.setBoolPref("plugins.click_to_play", true);
-  var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
-                           .getService(SpecialPowers.Ci.nsIPluginHost);
-  var tags = ph.getPluginTags();
-  for (var tag of tags) {
-    if (tag.name == "Test Plug-in") {
-      tag.enabledState = SpecialPowers.Ci.nsIPluginTag.STATE_CLICKTOPLAY;
-    }
-  }
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
 
   var subwindow = window.open("./subtst_contextmenu.html", "contextmenu-subtext", "width=600,height=800");
   subwindow.addEventListener("MozAfterPaint", waitForEvents, false);
   subwindow.onload = waitForEvents;
 
   SimpleTest.waitForExplicitFinish();
 }
 </script>
--- a/browser/base/content/test/newtab/Makefile.in
+++ b/browser/base/content/test/newtab/Makefile.in
@@ -1,28 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-	browser_newtab_block.js \
-	browser_newtab_disable.js \
-	browser_newtab_drag_drop.js \
-	browser_newtab_drag_drop_ext.js \
-	browser_newtab_drop_preview.js \
-	browser_newtab_focus.js \
-	browser_newtab_reset.js \
-	browser_newtab_tabsync.js \
-	browser_newtab_undo.js \
-	browser_newtab_unpin.js \
-	browser_newtab_bug721442.js \
-	browser_newtab_bug722273.js \
-	browser_newtab_bug723102.js \
-	browser_newtab_bug723121.js \
-	browser_newtab_bug725996.js \
-	browser_newtab_bug734043.js \
-	browser_newtab_bug735987.js \
-	browser_newtab_bug752841.js \
-	browser_newtab_bug765628.js \
-	browser_newtab_bug876313.js \
-	browser_newtab_perwindow_private_browsing.js \
-	head.js \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/newtab/browser.ini
@@ -0,0 +1,24 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_newtab_block.js]
+[browser_newtab_bug721442.js]
+[browser_newtab_bug722273.js]
+[browser_newtab_bug723102.js]
+[browser_newtab_bug723121.js]
+[browser_newtab_bug725996.js]
+[browser_newtab_bug734043.js]
+[browser_newtab_bug735987.js]
+[browser_newtab_bug752841.js]
+[browser_newtab_bug765628.js]
+[browser_newtab_bug876313.js]
+[browser_newtab_disable.js]
+[browser_newtab_drag_drop.js]
+[browser_newtab_drag_drop_ext.js]
+[browser_newtab_drop_preview.js]
+[browser_newtab_focus.js]
+[browser_newtab_perwindow_private_browsing.js]
+[browser_newtab_reset.js]
+[browser_newtab_tabsync.js]
+[browser_newtab_undo.js]
+[browser_newtab_unpin.js]
--- a/browser/base/content/test/newtab/moz.build
+++ b/browser/base/content/test/newtab/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/base/content/test/social/Makefile.in
+++ b/browser/base/content/test/social/Makefile.in
@@ -1,41 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-                 head.js \
-		 blocklist.xml \
-		 browser_blocklist.js \
-		 browser_defaults.js \
-		 browser_addons.js \
-		 browser_chat_tearoff.js \
-                 browser_social_activation.js \
-                 browser_social_perwindowPB.js \
-                 browser_social_toolbar.js \
-                 browser_social_sidebar.js \
-                 browser_social_flyout.js \
-                 browser_social_mozSocial_API.js \
-                 browser_social_isVisible.js \
-                 browser_social_chatwindow.js \
-                 browser_social_chatwindow_resize.js \
-                 browser_social_chatwindowfocus.js \
-                 browser_social_multiprovider.js \
-                 browser_social_multiworker.js \
-                 browser_social_errorPage.js \
-                 browser_social_marks.js \
-                 browser_social_status.js \
-                 browser_social_window.js \
-                 social_activate.html \
-                 social_activate_iframe.html \
-                 browser_share.js \
-                 social_panel.html \
-                 social_mark.html \
-                 social_sidebar.html \
-                 social_chat.html \
-                 social_flyout.html \
-                 social_window.html \
-                 social_worker.js \
-                 share.html \
-                 checked.jpg \
-                 unchecked.jpg \
-                 $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/browser.ini
@@ -0,0 +1,38 @@
+[DEFAULT]
+support-files =
+  blocklist.xml
+  checked.jpg
+  head.js
+  share.html
+  social_activate.html
+  social_activate_iframe.html
+  social_chat.html
+  social_flyout.html
+  social_mark.html
+  social_panel.html
+  social_sidebar.html
+  social_window.html
+  social_worker.js
+  unchecked.jpg
+
+[browser_addons.js]
+[browser_blocklist.js]
+[browser_chat_tearoff.js]
+[browser_defaults.js]
+[browser_share.js]
+[browser_social_activation.js]
+[browser_social_chatwindow.js]
+[browser_social_chatwindow_resize.js]
+[browser_social_chatwindowfocus.js]
+[browser_social_errorPage.js]
+[browser_social_flyout.js]
+[browser_social_isVisible.js]
+[browser_social_marks.js]
+[browser_social_mozSocial_API.js]
+[browser_social_multiprovider.js]
+[browser_social_multiworker.js]
+[browser_social_perwindowPB.js]
+[browser_social_sidebar.js]
+[browser_social_status.js]
+[browser_social_toolbar.js]
+[browser_social_window.js]
--- a/browser/base/content/test/social/moz.build
+++ b/browser/base/content/test/social/moz.build
@@ -1,7 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['opengraph']
+
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/certerror/test/Makefile.in
+++ b/browser/components/certerror/test/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-  browser_bug431826.js \
-  browser_bug633691.js \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/certerror/test/browser.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[browser_bug431826.js]
+[browser_bug633691.js]
--- a/browser/components/certerror/test/moz.build
+++ b/browser/components/certerror/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/downloads/test/browser/Makefile.in
+++ b/browser/components/downloads/test/browser/Makefile.in
@@ -1,8 +1,3 @@
 # Any copyright is dedicated to the Public Domain.
 # http://creativecommons.org/publicdomain/zero/1.0/
 
-MOCHITEST_BROWSER_FILES = \
-  browser_basic_functionality.js \
-  browser_first_download_panel.js \
-  head.js \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/downloads/test/browser/browser.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_basic_functionality.js]
+[browser_first_download_panel.js]
--- a/browser/components/downloads/test/browser/moz.build
+++ b/browser/components/downloads/test/browser/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/feeds/test/Makefile.in
+++ b/browser/components/feeds/test/Makefile.in
@@ -1,17 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-		bug408328-data.xml \
-		bug368464-data.xml \
-		test_bug494328.html \
-		bug494328-data.xml \
-		test_bug589543.html \
-		bug589543-data.xml \
-		test_bug436801.html \
-		bug436801-data.xml \
-		test_registerHandler.html \
-		valid-feed.xml \
-		valid-unsniffable-feed.xml \
-		$(NULL)
--- a/browser/components/feeds/test/chrome/Makefile.in
+++ b/browser/components/feeds/test/chrome/Makefile.in
@@ -3,14 +3,8 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # sample_feed.atom was copied from toolkit/components/places/tests/chrome
 MOCHITEST_FILES	= \
 		sample_feed.atom \
 		$(NULL)
 
-MOCHITEST_CHROME_FILES	= \
-		test_423060.xul \
-		test_bug368464.html \
-		test_bug408328.html \
-		test_maxSniffing.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/feeds/test/chrome/chrome.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+
+[test_423060.xul]
+[test_bug368464.html]
+[test_bug408328.html]
+[test_maxSniffing.html]
--- a/browser/components/feeds/test/chrome/moz.build
+++ b/browser/components/feeds/test/chrome/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
new file mode 100644
--- /dev/null
+++ b/browser/components/feeds/test/mochitest.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+support-files =
+  bug368464-data.xml
+  bug408328-data.xml
+  bug436801-data.xml
+  bug494328-data.xml
+  bug589543-data.xml
+  valid-feed.xml
+  valid-unsniffable-feed.xml
+
+[test_bug436801.html]
+[test_bug494328.html]
+[test_bug589543.html]
+[test_registerHandler.html]
--- a/browser/components/feeds/test/moz.build
+++ b/browser/components/feeds/test/moz.build
@@ -4,8 +4,11 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['chrome']
 
 MODULE = 'test_browser_feeds'
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
+
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
--- a/browser/components/places/tests/chrome/Makefile.in
+++ b/browser/components/places/tests/chrome/Makefile.in
@@ -1,16 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_CHROME_FILES = \
-	head.js \
-	test_treeview_date.xul \
-	test_bug485100-change-case-loses-tag.xul \
-	test_bug427633_no_newfolder_if_noip.xul \
-	test_0_multiple_left_pane.xul \
-	test_0_bug510634.xul \
-	test_bug549192.xul \
-	test_bug549491.xul \
-	test_editBookmarkOverlay_tags_liveUpdate.xul \
-	test_bug631374_tags_selector_scroll.xul \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/chrome/chrome.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+support-files = head.js
+
+[test_0_bug510634.xul]
+[test_0_multiple_left_pane.xul]
+[test_bug427633_no_newfolder_if_noip.xul]
+[test_bug485100-change-case-loses-tag.xul]
+[test_bug549192.xul]
+[test_bug549491.xul]
+[test_bug631374_tags_selector_scroll.xul]
+[test_editBookmarkOverlay_tags_liveUpdate.xul]
+[test_treeview_date.xul]
--- a/browser/components/places/tests/chrome/moz.build
+++ b/browser/components/places/tests/chrome/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/browser/components/preferences/in-content/tests/Makefile.in
+++ b/browser/components/preferences/in-content/tests/Makefile.in
@@ -1,25 +1,12 @@
 # -- This Source Code Form is subject to the terms of the Mozilla Public
 #  - License, v. 2.0. If a copy of the MPL was not distributed with this file,
 #  - You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-    head.js \
-    browser_advanced_update.js \
-    browser_bug410900.js \
-    browser_bug731866.js \
-    browser_connection.js \
-    browser_privacypane_1.js \
-    browser_privacypane_3.js \
-    browser_privacypane_5.js \
-    browser_privacypane_8.js \
-    privacypane_tests_perwindow.js \
-    $(NULL)
-
 ifdef ENABLE_TESTS
 pp_mochitest_browser_files := \
     browser_privacypane_4.js \
     $(NULL)
 pp_mochitest_browser_files_PATH := $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 PP_TARGETS += pp_mochitest_browser_files
 endif # ENABLE_TESTS
 
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -0,0 +1,13 @@
+[DEFAULT]
+support-files =
+  head.js
+  privacypane_tests_perwindow.js
+
+[browser_advanced_update.js]
+[browser_bug410900.js]
+[browser_bug731866.js]
+[browser_connection.js]
+[browser_privacypane_1.js]
+[browser_privacypane_3.js]
+[browser_privacypane_5.js]
+[browser_privacypane_8.js]
--- a/browser/components/preferences/in-content/tests/moz.build
+++ b/browser/components/preferences/in-content/tests/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/preferences/tests/Makefile.in
+++ b/browser/components/preferences/tests/Makefile.in
@@ -1,26 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-    head.js \
-    browser_advanced_update.js \
-    browser_bug410900.js \
-    browser_bug705422.js \
-    browser_permissions.js \
-    browser_chunk_permissions.js \
-    browser_privacypane_1.js \
-    browser_privacypane_3.js \
-    browser_privacypane_5.js \
-    browser_privacypane_8.js \
-    privacypane_tests_perwindow.js \
-    $(NULL)
-
 ifdef ENABLE_TESTS
 pp_mochitest_browser_files := \
     browser_privacypane_4.js \
     $(NULL)
 pp_mochitest_browser_files_PATH := $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 PP_TARGETS += pp_mochitest_browser_files
 endif # ENABLE_TESTS
 
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/tests/browser.ini
@@ -0,0 +1,14 @@
+[DEFAULT]
+support-files =
+  head.js
+  privacypane_tests_perwindow.js
+
+[browser_advanced_update.js]
+[browser_bug410900.js]
+[browser_bug705422.js]
+[browser_chunk_permissions.js]
+[browser_permissions.js]
+[browser_privacypane_1.js]
+[browser_privacypane_3.js]
+[browser_privacypane_5.js]
+[browser_privacypane_8.js]
--- a/browser/components/preferences/tests/moz.build
+++ b/browser/components/preferences/tests/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -1,52 +1,7 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Disabled for too many intermittent failures (bug 895390)
 #                browser_privatebrowsing_cache.js \
 
-MOCHITEST_BROWSER_FILES =  \
-		head.js \
-                browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js \
-                browser_privatebrowsing_aboutSessionRestore.js \
-		browser_privatebrowsing_certexceptionsui.js \
-		browser_privatebrowsing_concurrent.js \
-		browser_privatebrowsing_concurrent_page.html \
-		browser_privatebrowsing_cookieacceptdialog.js \
-		browser_privatebrowsing_cookieacceptdialog.html \
-		browser_privatebrowsing_crh.js \
-		browser_privatebrowsing_downloadLastDir.js \
-		browser_privatebrowsing_downloadLastDir_c.js \
-		browser_privatebrowsing_downloadLastDir_toggle.js \
-		browser_privatebrowsing_DownloadLastDirWithCPS.js \
-		browser_privatebrowsing_geoprompt.js \
-		browser_privatebrowsing_geoprompt_page.html \
-		browser_privatebrowsing_lastpbcontextexited.js \
-		browser_privatebrowsing_localStorage.js \
-		browser_privatebrowsing_localStorage_before_after.js \
-		browser_privatebrowsing_localStorage_before_after_page.html \
-		browser_privatebrowsing_localStorage_before_after_page2.html \
-		browser_privatebrowsing_localStorage_page1.html \
-		browser_privatebrowsing_localStorage_page2.html \
-		browser_privatebrowsing_nonbrowser.js \
-                browser_privatebrowsing_noSessionRestoreMenuOption.js \
-		browser_privatebrowsing_opendir.js \
-		browser_privatebrowsing_openlocation.js \
-		browser_privatebrowsing_openLocationLastURL.js \
-		browser_privatebrowsing_placestitle.js \
-		browser_privatebrowsing_placesTitleNoUpdate.js \
-		browser_privatebrowsing_placesTitleNoUpdate.html \
-		browser_privatebrowsing_popupblocker.js \
-		browser_privatebrowsing_protocolhandler.js \
-		browser_privatebrowsing_protocolhandler_page.html \
-    browser_privatebrowsing_sidebar.js \
-		browser_privatebrowsing_theming.js \
-		browser_privatebrowsing_ui.js \
-		browser_privatebrowsing_urlbarfocus.js \
-		browser_privatebrowsing_windowtitle.js \
-		browser_privatebrowsing_windowtitle_page.html \
-		browser_privatebrowsing_zoom.js \
-		browser_privatebrowsing_zoomrestore.js \
-		popup.html \
-		title.sjs \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser.ini
@@ -0,0 +1,46 @@
+[DEFAULT]
+support-files =
+  head.js
+  popup.html
+  title.sjs
+
+[browser_privatebrowsing_DownloadLastDirWithCPS.js]
+[browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js]
+[browser_privatebrowsing_aboutSessionRestore.js]
+[browser_privatebrowsing_certexceptionsui.js]
+[browser_privatebrowsing_concurrent.js]
+[browser_privatebrowsing_concurrent_page.html]
+[browser_privatebrowsing_cookieacceptdialog.html]
+[browser_privatebrowsing_cookieacceptdialog.js]
+[browser_privatebrowsing_crh.js]
+[browser_privatebrowsing_downloadLastDir.js]
+[browser_privatebrowsing_downloadLastDir_c.js]
+[browser_privatebrowsing_downloadLastDir_toggle.js]
+[browser_privatebrowsing_geoprompt.js]
+[browser_privatebrowsing_geoprompt_page.html]
+[browser_privatebrowsing_lastpbcontextexited.js]
+[browser_privatebrowsing_localStorage.js]
+[browser_privatebrowsing_localStorage_before_after.js]
+[browser_privatebrowsing_localStorage_before_after_page.html]
+[browser_privatebrowsing_localStorage_before_after_page2.html]
+[browser_privatebrowsing_localStorage_page1.html]
+[browser_privatebrowsing_localStorage_page2.html]
+[browser_privatebrowsing_noSessionRestoreMenuOption.js]
+[browser_privatebrowsing_nonbrowser.js]
+[browser_privatebrowsing_openLocationLastURL.js]
+[browser_privatebrowsing_opendir.js]
+[browser_privatebrowsing_openlocation.js]
+[browser_privatebrowsing_placesTitleNoUpdate.html]
+[browser_privatebrowsing_placesTitleNoUpdate.js]
+[browser_privatebrowsing_placestitle.js]
+[browser_privatebrowsing_popupblocker.js]
+[browser_privatebrowsing_protocolhandler.js]
+[browser_privatebrowsing_protocolhandler_page.html]
+[browser_privatebrowsing_sidebar.js]
+[browser_privatebrowsing_theming.js]
+[browser_privatebrowsing_ui.js]
+[browser_privatebrowsing_urlbarfocus.js]
+[browser_privatebrowsing_windowtitle.js]
+[browser_privatebrowsing_windowtitle_page.html]
+[browser_privatebrowsing_zoom.js]
+[browser_privatebrowsing_zoomrestore.js]
--- a/browser/components/privatebrowsing/test/browser/moz.build
+++ b/browser/components/privatebrowsing/test/browser/moz.build
@@ -1,9 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-
 MODULE = 'test_privatebrowsing'
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/safebrowsing/content/test/Makefile.in
+++ b/browser/components/safebrowsing/content/test/Makefile.in
@@ -1,19 +1,13 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-  head.js \
-  browser_bug400731.js \
-  $(NULL)
-
-
 # browser_bug415846.js disabled for too many intermittent failures (bug 546169)
 #
 # # The browser chrome test for bug 415846 doesn't run on Mac because of its
 # # bizarre special-and-unique snowflake of a help menu.
 # ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 # MOCHITEST_BROWSER_FILES += \
 #   browser_bug415846.js \
 #   $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/safebrowsing/content/test/browser.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_bug400731.js]
--- a/browser/components/safebrowsing/content/test/moz.build
+++ b/browser/components/safebrowsing/content/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/search/test/Makefile.in
+++ b/browser/components/search/test/Makefile.in
@@ -1,30 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-  head.js \
-  browser_405664.js \
-  browser_addEngine.js \
-  browser_contextmenu.js \
-  browser_healthreport.js \
-  browser_private_search_perwindowpb.js \
-  testEngine.xml \
-  testEngine_mozsearch.xml \
-  testEngine.src \
-  browser_426329.js \
-  426329.xml \
-  browser_483086.js \
-  483086-1.xml \
-  483086-2.xml \
-  test.html \
-  $(NULL)
-
 ifdef ENABLE_TESTS
 pp_mochitest_browser_files := \
   browser_google.js \
   $(NULL)
 pp_mochitest_browser_files_PATH := $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 pp_mochitest_browser_files_FLAGS := -DMOZ_DISTRIBUTION_ID=$(MOZ_DISTRIBUTION_ID)
 PP_TARGETS += pp_mochitest_browser_files
 endif # ENABLE_TESTS
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/browser.ini
@@ -0,0 +1,18 @@
+[DEFAULT]
+support-files =
+  426329.xml
+  483086-1.xml
+  483086-2.xml
+  head.js
+  test.html
+  testEngine.src
+  testEngine.xml
+  testEngine_mozsearch.xml
+
+[browser_405664.js]
+[browser_426329.js]
+[browser_483086.js]
+[browser_addEngine.js]
+[browser_contextmenu.js]
+[browser_healthreport.js]
+[browser_private_search_perwindowpb.js]
--- a/browser/components/search/test/moz.build
+++ b/browser/components/search/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -118,16 +118,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
   "resource:///modules/sessionstore/SessionStorage.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "SessionCookies",
   "resource:///modules/sessionstore/SessionCookies.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
   "resource:///modules/sessionstore/SessionHistory.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "_SessionFile",
   "resource:///modules/sessionstore/_SessionFile.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "TabStateCache",
+  "resource:///modules/sessionstore/TabStateCache.jsm");
 
 #ifdef MOZ_CRASHREPORTER
 XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
   "@mozilla.org/xre/app-info;1", "nsICrashReporter");
 #endif
 
 /**
  * |true| if we are in debug mode, |false| otherwise.
@@ -4175,136 +4177,16 @@ function TabData(obj = null) {
     for (let [key, value] in Iterator(obj)) {
       this[key] = value;
     }
   }
   return this;
 }
 
 /**
- * A cache for tabs data.
- *
- * This cache implements a weak map from tabs (as XUL elements)
- * to tab data (as instances of TabData).
- *
- * Note that we should never cache private data, as:
- * - that data is used very seldom by SessionStore;
- * - caching private data in addition to public data is memory consuming.
- */
-let TabStateCache = {
-  _data: new WeakMap(),
-
-  /**
-   * Tells whether an entry is in the cache.
-   *
-   * @param {XULElement} aKey The tab or the associated browser.
-   * @return {bool} Whether there's a cached entry for the given tab.
-   */
-  has: function (aTab) {
-    let key = this._normalizeToBrowser(aTab);
-    return this._data.has(key);
-  },
-
-  /**
-   * Add or replace an entry in the cache.
-   *
-   * @param {XULElement} aTab The key, which may be either a tab
-   * or the corresponding browser. The binding will disappear
-   * if the tab/browser is destroyed.
-   * @param {TabData} aValue The data associated to |aTab|.
-   */
-  set: function(aTab, aValue) {
-    let key = this._normalizeToBrowser(aTab);
-    if (!(aValue instanceof TabData)) {
-      throw new TypeError("Attempting to cache a non TabData");
-    }
-    this._data.set(key, aValue);
-  },
-
-  /**
-   * Return the tab data associated with a tab.
-   *
-   * @param {XULElement} aKey The tab or the associated browser.
-   *
-   * @return {TabData|undefined} The data if available, |undefined|
-   * otherwise.
-   */
-  get: function(aKey) {
-    let key = this._normalizeToBrowser(aKey);
-    let result = this._data.get(key);
-    TabStateCacheTelemetry.recordAccess(!!result);
-    return result;
-  },
-
-  /**
-   * Delete the tab data associated with a tab.
-   *
-   * @param {XULElement} aKey The tab or the associated browser.
-   *
-   * Noop of there is no tab data associated with the tab.
-   */
-  delete: function(aKey) {
-    let key = this._normalizeToBrowser(aKey);
-    this._data.delete(key);
-  },
-
-  /**
-   * Delete all tab data.
-   */
-  clear: function() {
-    TabStateCacheTelemetry.recordClear();
-    this._data.clear();
-  },
-
-  /**
-   * Update in place a piece of data.
-   *
-   * @param {XULElement} aKey The tab or the associated browser.
-   * If the tab/browser is not present, do nothing.
-   * @param {string} aField The field to update.
-   * @param {*} aValue The new value to place in the field.
-   */
-  updateField: function(aKey, aField, aValue) {
-    let key = this._normalizeToBrowser(aKey);
-    let data = this._data.get(key);
-    if (data) {
-      data[aField] = aValue;
-    }
-    TabStateCacheTelemetry.recordAccess(!!data);
-  },
-
-  /**
-   * Remove a given field from a cached tab state.
-   *
-   * @param {XULElement} aKey The tab or the associated browser.
-   * If the tab/browser is not present, do nothing.
-   * @param {string} aField The field to remove.
-   */
-  removeField: function(aKey, aField) {
-    let key = this._normalizeToBrowser(aKey);
-    let data = this._data.get(key);
-    if (data && aField in data) {
-      delete data[aField];
-    }
-    TabStateCacheTelemetry.recordAccess(!!data);
-  },
-
-  _normalizeToBrowser: function(aKey) {
-    let nodeName = aKey.localName;
-    if (nodeName == "tab") {
-      return aKey.linkedBrowser;
-    }
-    if (nodeName == "browser") {
-      return aKey;
-    }
-    throw new TypeError("Key is neither a tab nor a browser: " + nodeName);
-  }
-};
-
-/**
  * Module that contains tab state collection methods.
  */
 let TabState = {
   // A map (xul:tab -> promise) that keeps track of tabs and
   // their promises when collecting tab data asynchronously.
   _pendingCollections: new WeakMap(),
 
   /**
@@ -4342,17 +4224,17 @@ let TabState = {
 
       // Collect docShell capabilities asynchronously.
       let disallow = yield Messenger.send(tab, "SessionStore:collectDocShellCapabilities");
 
       // Collect basic tab data, without session history and storage.
       let options = {omitSessionHistory: true,
                      omitSessionStorage: true,
                      omitDocShellCapabilities: true};
-      let tabData = new TabData(this._collectBaseTabData(tab, options));
+      let tabData = this._collectBaseTabData(tab, options);
 
       // Apply collected data.
       tabData.entries = history.entries;
       tabData.index = history.index;
 
       if (Object.keys(storage).length) {
         tabData.storage = storage;
       }
@@ -4396,17 +4278,17 @@ let TabState = {
   collectSync: function (tab) {
     if (!tab) {
       throw new TypeError("Expecting a tab");
     }
     if (TabStateCache.has(tab)) {
       return TabStateCache.get(tab);
     }
 
-    let tabData = new TabData(this._collectBaseTabData(tab));
+    let tabData = this._collectBaseTabData(tab);
     if (this._updateTextAndScrollDataForTab(tab, tabData)) {
       TabStateCache.set(tab, tabData);
     }
 
     // Prevent all running asynchronous collections from filling the cache.
     // Every asynchronous data collection started before a collectSync() call
     // can't expect to retrieve different data than the sync call. That's why
     // we just fill the cache with the data collected from the sync call and
@@ -4710,73 +4592,9 @@ let TabState = {
       let selectedPageStyle = this._getSelectedPageStyle(content.frames[i]);
       if (selectedPageStyle)
         return selectedPageStyle;
     }
     return "";
   }
 };
 
-let TabStateCacheTelemetry = {
-  // Total number of hits during the session
-  _hits: 0,
-  // Total number of misses during the session
-  _misses: 0,
-  // Total number of clears during the session
-  _clears: 0,
-  // |true| once we have been initialized
-  _initialized: false,
-
-  /**
-   * Record a cache access.
-   *
-   * @param {boolean} isHit If |true|, the access was a hit, otherwise
-   * a miss.
-   */
-  recordAccess: function(isHit) {
-    this._init();
-    if (isHit) {
-      ++this._hits;
-    } else {
-      ++this._misses;
-    }
-  },
-
-  /**
-   * Record a cache clear
-   */
-  recordClear: function() {
-    this._init();
-    ++this._clears;
-  },
-
-  /**
-   * Initialize the telemetry.
-   */
-  _init: function() {
-    if (this._initialized) {
-      // Avoid double initialization
-      return;
-    }
-    this._initialized = true;
-    Services.obs.addObserver(this, "profile-before-change", false);
-  },
-
-  observe: function() {
-    Services.obs.removeObserver(this, "profile-before-change");
-
-    // Record hit/miss rate
-    let accesses = this._hits + this._misses;
-    if (accesses == 0) {
-      return;
-    }
-
-    this._fillHistogram("HIT_RATE", this._hits, accesses);
-    this._fillHistogram("CLEAR_RATIO", this._clears, accesses);
-  },
-
-  _fillHistogram: function(suffix, positive, total) {
-    let PREFIX = "FX_SESSION_RESTORE_TABSTATECACHE_";
-    let histo = Services.telemetry.getHistogramById(PREFIX + suffix);
-    let rate = Math.floor( ( positive * 100 ) / total );
-    histo.add(rate);
-  }
-};
+
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/src/TabStateCache.jsm
@@ -0,0 +1,292 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["TabStateCache"];
+
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/Services.jsm", this);
+
+
+/**
+ * A cache for tabs data.
+ *
+ * This cache implements a weak map from tabs (as XUL elements)
+ * to tab data (as objects).
+ *
+ * Note that we should never cache private data, as:
+ * - that data is used very seldom by SessionStore;
+ * - caching private data in addition to public data is memory consuming.
+ */
+this.TabStateCache = Object.freeze({
+  /**
+   * Tells whether an entry is in the cache.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   * @return {bool} Whether there's a cached entry for the given tab.
+   */
+  has: function (aTab) {
+    return TabStateCacheInternal.has(aTab);
+  },
+
+  /**
+   * Add or replace an entry in the cache.
+   *
+   * @param {XULElement} aTab The key, which may be either a tab
+   * or the corresponding browser. The binding will disappear
+   * if the tab/browser is destroyed.
+   * @param {*} aValue The data associated to |aTab|.
+   */
+  set: function(aTab, aValue) {
+    return TabStateCacheInternal.set(aTab, aValue);
+  },
+
+  /**
+   * Return the tab data associated with a tab.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   *
+   * @return {*|undefined} The data if available, |undefined|
+   * otherwise.
+   */
+  get: function(aKey) {
+    return TabStateCacheInternal.get(aKey);
+  },
+
+  /**
+   * Delete the tab data associated with a tab.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   *
+   * Noop of there is no tab data associated with the tab.
+   */
+  delete: function(aKey) {
+    return TabStateCacheInternal.delete(aKey);
+  },
+
+  /**
+   * Delete all tab data.
+   */
+  clear: function() {
+    return TabStateCacheInternal.clear();
+  },
+
+  /**
+   * Update in place a piece of data.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   * If the tab/browser is not present, do nothing.
+   * @param {string} aField The field to update.
+   * @param {*} aValue The new value to place in the field.
+   */
+  updateField: function(aKey, aField, aValue) {
+    return TabStateCacheInternal.updateField(aKey, aField, aValue);
+  },
+
+  /**
+   * Remove a given field from a cached tab state.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   * If the tab/browser is not present, do nothing.
+   * @param {string} aField The field to remove.
+   */
+  removeField: function(aKey, aField) {
+    return TabStateCacheInternal.removeField(aKey, aField);
+  },
+
+  /**
+   * Total number of cache hits during the session.
+   */
+  get hits() {
+    return TabStateCacheTelemetry.hits;
+  },
+
+  /**
+   * Total number of cache misses during the session.
+   */
+  get misses() {
+    return TabStateCacheTelemetry.misses;
+  },
+
+  /**
+   * Total number of cache clears during the session.
+   */
+  get clears() {
+    return TabStateCacheTelemetry.clears;
+  },
+});
+
+let TabStateCacheInternal = {
+  _data: new WeakMap(),
+
+  /**
+   * Tells whether an entry is in the cache.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   * @return {bool} Whether there's a cached entry for the given tab.
+   */
+  has: function (aTab) {
+    let key = this._normalizeToBrowser(aTab);
+    return this._data.has(key);
+  },
+
+  /**
+   * Add or replace an entry in the cache.
+   *
+   * @param {XULElement} aTab The key, which may be either a tab
+   * or the corresponding browser. The binding will disappear
+   * if the tab/browser is destroyed.
+   * @param {*} aValue The data associated to |aTab|.
+   */
+  set: function(aTab, aValue) {
+    let key = this._normalizeToBrowser(aTab);
+    this._data.set(key, aValue);
+  },
+
+  /**
+   * Return the tab data associated with a tab.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   *
+   * @return {*|undefined} The data if available, |undefined|
+   * otherwise.
+   */
+  get: function(aKey) {
+    let key = this._normalizeToBrowser(aKey);
+    let result = this._data.get(key);
+    TabStateCacheTelemetry.recordAccess(!!result);
+    return result;
+  },
+
+  /**
+   * Delete the tab data associated with a tab.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   *
+   * Noop of there is no tab data associated with the tab.
+   */
+  delete: function(aKey) {
+    let key = this._normalizeToBrowser(aKey);
+    this._data.delete(key);
+  },
+
+  /**
+   * Delete all tab data.
+   */
+  clear: function() {
+    TabStateCacheTelemetry.recordClear();
+    this._data.clear();
+  },
+
+  /**
+   * Update in place a piece of data.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   * If the tab/browser is not present, do nothing.
+   * @param {string} aField The field to update.
+   * @param {*} aValue The new value to place in the field.
+   */
+  updateField: function(aKey, aField, aValue) {
+    let key = this._normalizeToBrowser(aKey);
+    let data = this._data.get(key);
+    if (data) {
+      data[aField] = aValue;
+    }
+    TabStateCacheTelemetry.recordAccess(!!data);
+  },
+
+  /**
+   * Remove a given field from a cached tab state.
+   *
+   * @param {XULElement} aKey The tab or the associated browser.
+   * If the tab/browser is not present, do nothing.
+   * @param {string} aField The field to remove.
+   */
+  removeField: function(aKey, aField) {
+    let key = this._normalizeToBrowser(aKey);
+    let data = this._data.get(key);
+    if (data && aField in data) {
+      delete data[aField];
+    }
+    TabStateCacheTelemetry.recordAccess(!!data);
+  },
+
+  _normalizeToBrowser: function(aKey) {
+    let nodeName = aKey.localName;
+    if (nodeName == "tab") {
+      return aKey.linkedBrowser;
+    }
+    if (nodeName == "browser") {
+      return aKey;
+    }
+    throw new TypeError("Key is neither a tab nor a browser: " + nodeName);
+  }
+};
+
+let TabStateCacheTelemetry = {
+  // Total number of hits during the session
+  hits: 0,
+  // Total number of misses during the session
+  misses: 0,
+  // Total number of clears during the session
+  clears: 0,
+  // |true| once we have been initialized
+  _initialized: false,
+
+  /**
+   * Record a cache access.
+   *
+   * @param {boolean} isHit If |true|, the access was a hit, otherwise
+   * a miss.
+   */
+  recordAccess: function(isHit) {
+    this._init();
+    if (isHit) {
+      ++this.hits;
+    } else {
+      ++this.misses;
+    }
+  },
+
+  /**
+   * Record a cache clear
+   */
+  recordClear: function() {
+    this._init();
+    ++this.clears;
+  },
+
+  /**
+   * Initialize the telemetry.
+   */
+  _init: function() {
+    if (this._initialized) {
+      // Avoid double initialization
+      return;
+    }
+    this._initialized = true;
+    Services.obs.addObserver(this, "profile-before-change", false);
+  },
+
+  observe: function() {
+    Services.obs.removeObserver(this, "profile-before-change");
+
+    // Record hit/miss rate
+    let accesses = this.hits + this.misses;
+    if (accesses == 0) {
+      return;
+    }
+
+    this._fillHistogram("HIT_RATE", this.hits, accesses);
+    this._fillHistogram("CLEAR_RATIO", this.clears, accesses);
+  },
+
+  _fillHistogram: function(suffix, positive, total) {
+    let PREFIX = "FX_SESSION_RESTORE_TABSTATECACHE_";
+    let histo = Services.telemetry.getHistogramById(PREFIX + suffix);
+    let rate = Math.floor( ( positive * 100 ) / total );
+    histo.add(rate);
+  }
+};
--- a/browser/components/sessionstore/src/moz.build
+++ b/browser/components/sessionstore/src/moz.build
@@ -17,16 +17,17 @@ EXTRA_JS_MODULES = [
     'DocumentUtils.jsm',
     'Messenger.jsm',
     'PrivacyLevel.jsm',
     'SessionCookies.jsm',
     'SessionHistory.jsm',
     'SessionMigration.jsm',
     'SessionStorage.jsm',
     'SessionWorker.js',
+    'TabStateCache.jsm',
     'XPathGenerator.jsm',
     '_SessionFile.jsm',
 ]
 
 EXTRA_PP_JS_MODULES += [
     'SessionSaver.jsm',
     'SessionStore.jsm',
 ]
--- a/browser/components/sessionstore/test/Makefile.in
+++ b/browser/components/sessionstore/test/Makefile.in
@@ -15,16 +15,17 @@ MOCHITEST_BROWSER_FILES = \
 	browser_form_restore_events.js \
 	browser_form_restore_events_sample.html \
 	browser_formdata_format.js \
 	browser_formdata_format_sample.html \
 	browser_input.js \
 	browser_input_sample.html \
 	browser_pageshow.js \
 	browser_sessionStorage.js \
+	browser_tabStateCache.js \
 	browser_upgrade_backup.js \
 	browser_windowRestore_perwindowpb.js \
 	browser_248970_b_perwindowpb.js \
 	browser_248970_b_sample.html \
 	browser_339445.js \
 	browser_339445_sample.html \
 	browser_345898.js \
 	browser_346337.js \
--- a/browser/components/sessionstore/test/browser_sessionStorage.js
+++ b/browser/components/sessionstore/test/browser_sessionStorage.js
@@ -2,36 +2,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let Scope = {};
 Cu.import("resource://gre/modules/Task.jsm", Scope);
 Cu.import("resource://gre/modules/Promise.jsm", Scope);
 let {Task, Promise} = Scope;
 
-function promiseBrowserLoaded(aBrowser) {
-  let deferred = Promise.defer();
-  whenBrowserLoaded(aBrowser, () => deferred.resolve());
-  return deferred.promise;
-}
-
-function forceWriteState() {
-  let deferred = Promise.defer();
-  const PREF = "browser.sessionstore.interval";
-  const TOPIC = "sessionstore-state-write";
-
-  Services.obs.addObserver(function observe() {
-    Services.obs.removeObserver(observe, TOPIC);
-    Services.prefs.clearUserPref(PREF);
-    deferred.resolve();
-  }, TOPIC, false);
-
-  Services.prefs.setIntPref(PREF, 0);
-  return deferred.promise;
-}
 
 function waitForStorageChange(aTab) {
   let deferred = Promise.defer();
   waitForContentMessage(aTab.linkedBrowser,
     "SessionStore:MozStorageChanged",
     1000,
     deferred.resolve);
   return deferred.promise;
@@ -52,38 +32,38 @@ function test() {
       tab = gBrowser.addTab("http://example.com");
       // about:home supports sessionStorage and localStorage
 
       let win = tab.linkedBrowser.contentWindow;
 
       // Flush loading and next save, call getBrowserState()
       // a few times to ensure that everything is cached.
       yield promiseBrowserLoaded(tab.linkedBrowser);
-      yield forceWriteState();
+      yield forceSaveState();
       info("Calling getBrowserState() to populate cache");
       ss.getBrowserState();
 
       info("Change sessionStorage, ensure that state is saved");
       let storageChangedPromise = waitForStorageChange(tab);
       win.sessionStorage[SESSION_STORAGE_KEY] = SESSION_STORAGE_VALUE;
       let storageChanged = yield storageChangedPromise;
       ok(storageChanged, "Changing sessionStorage triggered the right message");
-      yield forceWriteState();
+      yield forceSaveState();
 
       let state = ss.getBrowserState();
       ok(state.indexOf(SESSION_STORAGE_KEY) != -1, "Key appears in state");
       ok(state.indexOf(SESSION_STORAGE_VALUE) != -1, "Value appears in state");
 
 
       info("Change localStorage, ensure that state is not saved");
       storageChangedPromise = waitForStorageChange(tab);
       win.localStorage[LOCAL_STORAGE_KEY] = LOCAL_STORAGE_VALUE;
       storageChanged = yield storageChangedPromise;
       ok(!storageChanged, "Changing localStorage did not trigger a message");
-      yield forceWriteState();
+      yield forceSaveState();
 
       state = ss.getBrowserState();
       ok(state.indexOf(LOCAL_STORAGE_KEY) == -1, "Key does not appear in state");
       ok(state.indexOf(LOCAL_STORAGE_VALUE) == -1, "Value does not appear in state");
     } catch (ex) {
       ok(false, ex);
       info(ex.stack);
     } finally {
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_tabStateCache.js
@@ -0,0 +1,141 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+let wrapper = {};
+Cu.import("resource:///modules/sessionstore/TabStateCache.jsm", wrapper);
+let {TabStateCache} = wrapper;
+
+// The number of tabs that are present in the browser but that we're not dealing
+// with. This should be one (for an empty about:blank), but let's not make this
+// a magic number.
+let numberOfUntrackedTabs;
+
+// Arbitrary URL prefix, used to generate the URL of pages we visit
+const URL_PREFIX = "http://example.org:80/";
+
+/**
+ * Check tab state cache telemetry statistics before and after an operation.
+ *
+ * @param {function} f The operation being measured. If it returns a promise,
+ * we wait until the promise is resolved before proceeding.
+ * @return {promise}
+ */
+function getTelemetryDelta(f) {
+  return Task.spawn(function() {
+    let KEYS = ["hits", "misses", "clears"];
+    let old = {};
+    for (let key of KEYS) {
+      old[key] = TabStateCache[key];
+    }
+    yield f();
+    let result = {};
+    for (let key of KEYS) {
+      result[key] = TabStateCache[key] - old[key];
+    }
+    ok(result.hits >= 0, "Sanity check: hits have not decreased");
+    ok(result.misses >= 0, "Sanity check: misses have not decreased");
+    ok(result.clears >= 0, "Sanity check: clears have not decreased");
+    throw new Task.Result(result);
+  });
+}
+
+add_task(function init() {
+  // Start with an empty cache
+  closeAllButPrimaryWindow();
+  TabStateCache.clear();
+  numberOfUntrackedTabs = gBrowser.tabs.length;
+  info("Starting with " + numberOfUntrackedTabs + " tabs");
+});
+
+add_task(function add_remove() {
+  info("Adding the first tab");
+  // Initialize one tab, save to initialize cache
+  let tab1 = gBrowser.addTab(URL_PREFIX + "?tab1");
+  yield promiseBrowserLoaded(tab1.linkedBrowser);
+  yield getTelemetryDelta(forceSaveState);
+
+  // Save/collect again a few times, ensure that we always hit
+  info("Save/collect a few times with one tab");
+  for (let collector of [forceSaveState, ss.getBrowserState]) {
+    for (let i = 0; i < 5; ++i) {
+      let PREFIX = "Trivial test " + i + " using " + collector.name + ": ";
+      let delta = yield getTelemetryDelta(collector);
+      is(delta.hits, numberOfUntrackedTabs + 1, PREFIX + " has at least one hit " + delta.hits);
+      is(delta.misses, 0, PREFIX + " has no miss");
+      is(delta.clears, 0, PREFIX + " has no clear");
+    }
+  }
+
+  // Add a second tab, ensure that we have both hits and misses
+  info("Adding the second tab");
+  let tab2 = gBrowser.addTab(URL_PREFIX + "?tab2");
+  yield promiseBrowserLoaded(tab2.linkedBrowser);
+
+  let PREFIX = "Adding second tab: ";
+  ok(!TabStateCache.has(tab2), PREFIX + " starts out of the cache");
+  let delta = yield getTelemetryDelta(forceSaveState);
+  is(delta.hits, numberOfUntrackedTabs + 2, PREFIX + " we hit all tabs, thanks to prefetching");
+  is(delta.misses, 0, PREFIX + " we missed no tabs, thanks to prefetching");
+  is(delta.clears, 0, PREFIX + " has no clear");
+
+  // Save/collect again a few times, ensure that we always hit
+  info("Save/collect a few times with two tabs");
+  for (let collector of [forceSaveState, ss.getBrowserState]) {
+    for (let i = 0; i < 5; ++i) {
+      let PREFIX = "With two tabs " + i + " using " + collector.name + ": ";
+      let delta = yield getTelemetryDelta(collector);
+      is(delta.hits, numberOfUntrackedTabs + 2, PREFIX + " both tabs hit");
+      is(delta.misses, 0, PREFIX + " has no miss");
+      is(delta.clears, 0, PREFIX + " has no clear");
+    }
+  }
+
+  info("Removing second tab");
+  gBrowser.removeTab(tab2);
+  PREFIX = "Removing second tab: ";
+  delta = yield getTelemetryDelta(forceSaveState);
+  is(delta.hits, numberOfUntrackedTabs + 1, PREFIX + " we hit for one tab");
+  is(delta.misses, 0, PREFIX + " has no miss");
+  is(delta.clears, 0, PREFIX + " has no clear");
+
+  info("Removing first tab");
+  gBrowser.removeTab(tab1);
+});
+
+add_task(function browsing() {
+  info("Opening first browsing tab");
+  let tab1 = gBrowser.addTab(URL_PREFIX + "?do_not_move_from_here");
+  let browser1 = tab1.linkedBrowser;
+  yield promiseBrowserLoaded(browser1);
+  yield forceSaveState();
+
+  info("Opening second browsing tab");
+  let tab2 = gBrowser.addTab(URL_PREFIX + "?start_browsing_from_here");
+  let browser2 = tab2.linkedBrowser;
+  yield promiseBrowserLoaded(browser2);
+
+  for (let i = 0; i < 4; ++i) {
+    let url = URL_PREFIX + "?browsing" + i; // Arbitrary url, easy to recognize
+    let PREFIX = "Browsing to " + url;
+    info(PREFIX);
+    let delta = yield getTelemetryDelta(function() {
+      return Task.spawn(function() {
+        // Move to new URI then save session
+        let promise = promiseBrowserLoaded(browser2);
+        browser2.loadURI(url);
+        yield promise;
+        ok(!TabStateCache.has(browser2), PREFIX + " starts out of the cache");
+        yield forceSaveState();
+      });
+    });
+    is(delta.hits, numberOfUntrackedTabs + 2, PREFIX + " has all hits, thanks to prefetching");
+    is(delta.misses, 0, PREFIX + " has no miss, thanks to prefetching");
+    is(delta.clears, 0, PREFIX + " has no clear");
+  }
+  gBrowser.removeTab(tab2);
+  gBrowser.removeTab(tab1);
+});
+
+
--- a/browser/components/sessionstore/test/head.js
+++ b/browser/components/sessionstore/test/head.js
@@ -235,23 +235,67 @@ function waitForTopic(aTopic, aTimeout, 
  * within buffering interval + 100 ms, the callback is passed |true|,
  * otherwise, it is passed |false|.
  */
 function waitForSaveState(aCallback) {
   let timeout = 100 +
     Services.prefs.getIntPref("browser.sessionstore.interval");
   return waitForTopic("sessionstore-state-write", timeout, aCallback);
 }
+function promiseSaveState() {
+  let deferred = Promise.defer();
+  waitForSaveState(isSuccessful => {
+    if (isSuccessful) {
+      deferred.resolve();
+    } else {
+      deferred.reject(new Error("timeout"));
+    }});
+  return deferred.promise;
+}
+function forceSaveState() {
+  let promise = promiseSaveState();
+  const PREF = "browser.sessionstore.interval";
+  // Set interval to an arbitrary non-0 duration
+  // to ensure that setting it to 0 will notify observers
+  Services.prefs.setIntPref(PREF, 1000);
+  Services.prefs.setIntPref(PREF, 0);
+  return promise.then(
+    function onSuccess(x) {
+      Services.prefs.clearUserPref(PREF);
+      return x;
+    },
+    function onError(x) {
+      Services.prefs.clearUserPref(PREF);
+      throw x;
+    }
+  );
+}
 
 function whenBrowserLoaded(aBrowser, aCallback = next) {
   aBrowser.addEventListener("load", function onLoad() {
     aBrowser.removeEventListener("load", onLoad, true);
     executeSoon(aCallback);
   }, true);
 }
+function promiseBrowserLoaded(aBrowser) {
+  let deferred = Promise.defer();
+  whenBrowserLoaded(aBrowser, deferred.resolve);
+  return deferred.promise;
+}
+function whenBrowserUnloaded(aBrowser, aContainer, aCallback = next) {
+  aBrowser.addEventListener("unload", function onUnload() {
+    aBrowser.removeEventListener("unload", onUnload, true);
+    executeSoon(aCallback);
+  }, true);
+}
+function promiseBrowserUnloaded(aBrowser, aContainer) {
+  let deferred = Promise.defer();
+  whenBrowserUnloaded(aBrowser, aContainer, deferred.resolve);
+  return deferred.promise;
+}
 
 function whenWindowLoaded(aWindow, aCallback = next) {
   aWindow.addEventListener("load", function windowLoadListener() {
     aWindow.removeEventListener("load", windowLoadListener, false);
     executeSoon(function executeWhenWindowLoaded() {
       aCallback(aWindow);
     });
   }, false);
--- a/browser/components/shell/test/Makefile.in
+++ b/browser/components/shell/test/Makefile.in
@@ -1,8 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-    browser_420786.js \
-    browser_633221.js \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/shell/test/browser.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[browser_420786.js]
+[browser_633221.js]
--- a/browser/components/shell/test/moz.build
+++ b/browser/components/shell/test/moz.build
@@ -2,8 +2,11 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MODULE = 'test_browser_shell'
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
+
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/tabview/test/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -1,161 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-                 browser_tabview_alltabs.js \
-                 browser_tabview_apptabs.js \
-                 browser_tabview_bug580412.js \
-                 browser_tabview_bug586553.js \
-                 browser_tabview_bug587043.js \
-                 browser_tabview_bug587231.js \
-                 browser_tabview_bug587276.js \
-                 browser_tabview_bug587351.js \
-                 browser_tabview_bug587503.js \
-                 browser_tabview_bug587990.js \
-                 browser_tabview_bug588265.js \
-                 browser_tabview_bug589324.js \
-                 browser_tabview_bug590606.js \
-                 browser_tabview_bug591706.js \
-                 browser_tabview_bug593283.js \
-                 browser_tabview_bug595191.js \
-                 browser_tabview_bug595436.js \
-                 browser_tabview_bug595518.js \
-                 browser_tabview_bug595521.js \
-                 browser_tabview_bug595560.js \
-                 browser_tabview_bug595601.js \
-                 browser_tabview_bug595804.js \
-                 browser_tabview_bug595930.js \
-                 browser_tabview_bug595943.js \
-                 browser_tabview_bug595965.js \
-                 browser_tabview_bug596781.js \
-                 browser_tabview_bug597360.js \
-                 browser_tabview_bug597399.js \
-                 browser_tabview_bug598375.js \
-                 browser_tabview_bug598600.js \
-                 browser_tabview_bug599048.js \
-                 browser_tabview_bug599626.js \
-                 browser_tabview_bug600645.js \
-                 browser_tabview_bug600812.js \
-                 browser_tabview_bug604098.js \
-                 browser_tabview_bug606657.js \
-                 browser_tabview_bug606905.js \
-                 browser_tabview_bug607108.js \
-                 browser_tabview_bug608037.js \
-                 browser_tabview_bug608153.js \
-                 browser_tabview_bug608158.js \
-                 browser_tabview_bug608184.js \
-                 browser_tabview_bug608405.js \
-                 browser_tabview_bug610208.js \
-                 browser_tabview_bug612470.js \
-                 browser_tabview_bug613541.js \
-                 browser_tabview_bug616729.js \
-                 browser_tabview_bug616967.js \
-                 browser_tabview_bug618816.js \
-                 browser_tabview_bug618828.js \
-                 browser_tabview_bug619937.js \
-                 browser_tabview_bug622835.js \
-                 browser_tabview_bug623768.js \
-                 browser_tabview_bug624265_perwindowpb.js \
-                 browser_tabview_bug624692.js \
-                 browser_tabview_bug624727_perwindowpb.js \
-                 browser_tabview_bug624847.js \
-                 browser_tabview_bug624931.js \
-                 browser_tabview_bug624953.js \
-                 browser_tabview_bug625195.js \
-                 browser_tabview_bug625269.js \
-                 browser_tabview_bug625424.js \
-                 browser_tabview_bug625955.js \
-                 browser_tabview_bug626368.js \
-                 browser_tabview_bug626455.js \
-                 browser_tabview_bug626525.js \
-                 browser_tabview_bug626791.js \
-                 browser_tabview_bug627736.js \
-                 browser_tabview_bug628061.js \
-                 browser_tabview_bug628165.js \
-                 browser_tabview_bug628270.js \
-                 browser_tabview_bug628887.js \
-                 browser_tabview_bug629189.js \
-                 browser_tabview_bug629195.js \
-                 browser_tabview_bug630102.js \
-                 browser_tabview_bug630157.js \
-                 browser_tabview_bug631662.js \
-                 browser_tabview_bug631752.js \
-                 browser_tabview_bug633788.js \
-                 browser_tabview_bug634077.js \
-                 browser_tabview_bug634085.js \
-                 browser_tabview_bug634672.js \
-                 browser_tabview_bug635696.js \
-                 browser_tabview_bug637840.js \
-                 browser_tabview_bug640765.js \
-                 browser_tabview_bug641802.js \
-                 browser_tabview_bug642793.js \
-                 browser_tabview_bug643392.js \
-                 browser_tabview_bug644097.js \
-                 browser_tabview_bug649006.js \
-                 browser_tabview_bug649307.js \
-                 browser_tabview_bug649319.js \
-                 browser_tabview_bug650280_perwindowpb.js \
-                 browser_tabview_bug650573.js \
-                 browser_tabview_bug651311.js \
-                 browser_tabview_bug654295.js \
-                 browser_tabview_bug654721.js \
-                 browser_tabview_bug655269.js \
-                 browser_tabview_bug656778.js \
-                 browser_tabview_bug656913.js \
-                 browser_tabview_bug659594.js \
-                 browser_tabview_bug662266.js \
-                 browser_tabview_bug663421.js \
-                 browser_tabview_bug665502.js \
-                 browser_tabview_bug669694.js \
-                 browser_tabview_bug673196.js \
-                 browser_tabview_bug681599.js \
-                 browser_tabview_bug685476.js \
-                 browser_tabview_bug685692.js \
-                 browser_tabview_bug686654.js \
-                 browser_tabview_bug697390.js \
-                 browser_tabview_bug705621.js \
-                 browser_tabview_bug706430.js \
-                 browser_tabview_bug706736.js \
-                 browser_tabview_bug707466.js \
-                 browser_tabview_bug712203.js \
-                 browser_tabview_bug715454.js \
-                 browser_tabview_bug716880.js \
-                 browser_tabview_bug728887.js \
-                 browser_tabview_bug733115.js \
-                 browser_tabview_bug749658.js \
-                 browser_tabview_bug766597.js \
-                 browser_tabview_click_group.js \
-                 browser_tabview_dragdrop.js \
-                 browser_tabview_exit_button.js \
-                 browser_tabview_expander.js \
-                 browser_tabview_firstrun_pref.js \
-                 browser_tabview_group.js \
-                 browser_tabview_launch.js \
-                 browser_tabview_multiwindow_search.js \
-                 browser_tabview_privatebrowsing_perwindowpb.js \
-                 browser_tabview_rtl.js \
-                 browser_tabview_search.js \
-                 browser_tabview_snapping.js \
-                 browser_tabview_startup_transitions.js \
-                 browser_tabview_undo_group.js \
-                 browser_tabview_bug610242.js \
-                 dummy_page.html \
-                 head.js \
-                 search1.html \
-                 search2.html \
-                 test_bug600645.html \
-                 test_bug644097.html \
-                 test_bug678374.html \
-                 test_bug678374_icon16.png \
-                 $(NULL)
-
-
 # browser_tabview_bug597980.js is disabled for leaking, see bug 711907
 # browser_tabview_bug678374.js disabled for intermittent failures (bug 795265)
 # browser_tabview_bug602432.js disabled for intermittent failures (bug 704417)
 # browser_tabview_bug610242.js disabled for intermittent failures (bug 736036)
 # browser_tabview_bug648882.js disabled for intermittent failures (bug 752862)
 # browser_tabview_bug654941.js disabled for intermittent failures (bug 754222)
 # browser_tabview_bug673729.js disabled for intermittent failures (bug 749980)
 # browser_tabview_bug696602.js disabled for intermittent failures (bug 736425)
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser.ini
@@ -0,0 +1,148 @@
+[DEFAULT]
+support-files =
+  dummy_page.html
+  head.js
+  search1.html
+  search2.html
+  test_bug600645.html
+  test_bug644097.html
+  test_bug678374.html
+  test_bug678374_icon16.png
+
+[browser_tabview_alltabs.js]
+[browser_tabview_apptabs.js]
+[browser_tabview_bug580412.js]
+[browser_tabview_bug586553.js]
+[browser_tabview_bug587043.js]
+[browser_tabview_bug587231.js]
+[browser_tabview_bug587276.js]
+[browser_tabview_bug587351.js]
+[browser_tabview_bug587503.js]
+[browser_tabview_bug587990.js]
+[browser_tabview_bug588265.js]
+[browser_tabview_bug589324.js]
+[browser_tabview_bug590606.js]
+[browser_tabview_bug591706.js]
+[browser_tabview_bug593283.js]
+[browser_tabview_bug595191.js]
+[browser_tabview_bug595436.js]
+[browser_tabview_bug595518.js]
+[browser_tabview_bug595521.js]
+[browser_tabview_bug595560.js]
+[browser_tabview_bug595601.js]
+[browser_tabview_bug595804.js]
+[browser_tabview_bug595930.js]
+[browser_tabview_bug595943.js]
+[browser_tabview_bug595965.js]
+[browser_tabview_bug596781.js]
+[browser_tabview_bug597360.js]
+[browser_tabview_bug597399.js]
+[browser_tabview_bug598375.js]
+[browser_tabview_bug598600.js]
+[browser_tabview_bug599048.js]
+[browser_tabview_bug599626.js]
+[browser_tabview_bug600645.js]
+[browser_tabview_bug600812.js]
+[browser_tabview_bug604098.js]
+[browser_tabview_bug606657.js]
+[browser_tabview_bug606905.js]
+[browser_tabview_bug607108.js]
+[browser_tabview_bug608037.js]
+[browser_tabview_bug608153.js]
+[browser_tabview_bug608158.js]
+[browser_tabview_bug608184.js]
+[browser_tabview_bug608405.js]
+[browser_tabview_bug610208.js]
+[browser_tabview_bug610242.js]
+[browser_tabview_bug612470.js]
+[browser_tabview_bug613541.js]
+[browser_tabview_bug616729.js]
+[browser_tabview_bug616967.js]
+[browser_tabview_bug618816.js]
+[browser_tabview_bug618828.js]
+[browser_tabview_bug619937.js]
+[browser_tabview_bug622835.js]
+[browser_tabview_bug623768.js]
+[browser_tabview_bug624265_perwindowpb.js]
+[browser_tabview_bug624692.js]
+[browser_tabview_bug624727_perwindowpb.js]
+[browser_tabview_bug624847.js]
+[browser_tabview_bug624931.js]
+[browser_tabview_bug624953.js]
+[browser_tabview_bug625195.js]
+[browser_tabview_bug625269.js]
+[browser_tabview_bug625424.js]
+[browser_tabview_bug625955.js]
+[browser_tabview_bug626368.js]
+[browser_tabview_bug626455.js]
+[browser_tabview_bug626525.js]
+[browser_tabview_bug626791.js]
+[browser_tabview_bug627736.js]
+[browser_tabview_bug628061.js]
+[browser_tabview_bug628165.js]
+[browser_tabview_bug628270.js]
+[browser_tabview_bug628887.js]
+[browser_tabview_bug629189.js]
+[browser_tabview_bug629195.js]
+[browser_tabview_bug630102.js]
+[browser_tabview_bug630157.js]
+[browser_tabview_bug631662.js]
+[browser_tabview_bug631752.js]
+[browser_tabview_bug633788.js]
+[browser_tabview_bug634077.js]
+[browser_tabview_bug634085.js]
+[browser_tabview_bug634672.js]
+[browser_tabview_bug635696.js]
+[browser_tabview_bug637840.js]
+[browser_tabview_bug640765.js]
+[browser_tabview_bug641802.js]
+[browser_tabview_bug642793.js]
+[browser_tabview_bug643392.js]
+[browser_tabview_bug644097.js]
+[browser_tabview_bug649006.js]
+[browser_tabview_bug649307.js]
+[browser_tabview_bug649319.js]
+[browser_tabview_bug650280_perwindowpb.js]
+[browser_tabview_bug650573.js]
+[browser_tabview_bug651311.js]
+[browser_tabview_bug654295.js]
+[browser_tabview_bug654721.js]
+[browser_tabview_bug655269.js]
+[browser_tabview_bug656778.js]
+[browser_tabview_bug656913.js]
+[browser_tabview_bug659594.js]
+[browser_tabview_bug662266.js]
+[browser_tabview_bug663421.js]
+[browser_tabview_bug665502.js]
+[browser_tabview_bug669694.js]
+[browser_tabview_bug673196.js]
+[browser_tabview_bug681599.js]
+[browser_tabview_bug685476.js]
+[browser_tabview_bug685692.js]
+[browser_tabview_bug686654.js]
+[browser_tabview_bug697390.js]
+[browser_tabview_bug705621.js]
+[browser_tabview_bug706430.js]
+[browser_tabview_bug706736.js]
+[browser_tabview_bug707466.js]
+[browser_tabview_bug712203.js]
+[browser_tabview_bug715454.js]
+[browser_tabview_bug716880.js]
+[browser_tabview_bug728887.js]
+[browser_tabview_bug733115.js]
+[browser_tabview_bug749658.js]
+[browser_tabview_bug766597.js]
+[browser_tabview_click_group.js]
+[browser_tabview_dragdrop.js]
+[browser_tabview_exit_button.js]
+[browser_tabview_expander.js]
+[browser_tabview_firstrun_pref.js]
+[browser_tabview_group.js]
+[browser_tabview_launch.js]
+[browser_tabview_multiwindow_search.js]
+[browser_tabview_privatebrowsing_perwindowpb.js]
+[browser_tabview_rtl.js]
+[browser_tabview_search.js]
+[browser_tabview_snapping.js]
+[browser_tabview_startup_transitions.js]
+[browser_tabview_undo_group.js]
--- a/browser/components/tabview/test/moz.build
+++ b/browser/components/tabview/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/components/test/Makefile.in
+++ b/browser/components/test/Makefile.in
@@ -1,7 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-  browser_bug538331.js \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/test/browser.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[browser_bug538331.js]
--- a/browser/components/test/moz.build
+++ b/browser/components/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/app-manager/test/Makefile.in
+++ b/browser/devtools/app-manager/test/Makefile.in
@@ -1,12 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_CHROME_FILES = \
-		test_template.html \
-		test_connection_store.html \
-		test_device_store.html \
-		test_projects_store.html \
-		test_remain_connected.html \
-		hosted_app.manifest \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/app-manager/test/chrome.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+support-files = hosted_app.manifest
+
+[test_connection_store.html]
+[test_device_store.html]
+[test_projects_store.html]
+[test_remain_connected.html]
+[test_template.html]
--- a/browser/devtools/app-manager/test/moz.build
+++ b/browser/devtools/app-manager/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -1,186 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-	browser_dbg_aaa_run_first_leaktest.js \
-	browser_dbg_bfcache.js \
-	browser_dbg_blackboxing-01.js \
-	browser_dbg_blackboxing-02.js \
-	browser_dbg_blackboxing-03.js \
-	browser_dbg_blackboxing-04.js \
-	browser_dbg_blackboxing-05.js \
-	browser_dbg_blackboxing-06.js \
-	browser_dbg_blackboxing-07.js \
-	browser_dbg_breadcrumbs-access.js \
-	browser_dbg_breakpoints-actual-location.js \
-	browser_dbg_breakpoints-contextmenu.js \
-	browser_dbg_breakpoints-disabled-reload.js \
-	browser_dbg_breakpoints-editor.js \
-	browser_dbg_breakpoints-highlight.js \
-	browser_dbg_breakpoints-new-script.js \
-	browser_dbg_breakpoints-pane.js \
-	browser_dbg_chrome-debugging.js \
-	browser_dbg_clean-exit.js \
-	browser_dbg_clean-exit-window.js \
-	browser_dbg_cmd-blackbox.js \
-	browser_dbg_cmd-break.js \
-	browser_dbg_cmd-dbg.js \
-	browser_dbg_conditional-breakpoints-01.js \
-	browser_dbg_conditional-breakpoints-02.js \
-	browser_dbg_debugger-statement.js \
-	browser_dbg_editor-contextmenu.js \
-	browser_dbg_editor-mode.js \
-	browser_dbg_function-display-name.js \
-	browser_dbg_globalactor.js \
-	browser_dbg_iframes.js \
-	browser_dbg_instruments-pane-collapse.js \
-	browser_dbg_listaddons.js \
-	browser_dbg_listtabs-01.js \
-	browser_dbg_listtabs-02.js \
-	browser_dbg_location-changes-01-simple.js \
-	browser_dbg_location-changes-02-blank.js \
-	browser_dbg_location-changes-03-new.js \
-	browser_dbg_location-changes-04-breakpoint.js \
-	browser_dbg_multiple-windows.js \
-	browser_dbg_navigation.js \
-	browser_dbg_on-pause-highlight.js \
-	browser_dbg_panel-size.js \
-	browser_dbg_pause-exceptions-01.js \
-	browser_dbg_pause-exceptions-02.js \
-	browser_dbg_pause-resume.js \
-	browser_dbg_pause-warning.js \
-	browser_dbg_pretty-print-01.js \
-	browser_dbg_pretty-print-02.js \
-	browser_dbg_pretty-print-03.js \
-	browser_dbg_pretty-print-04.js \
-	browser_dbg_pretty-print-05.js \
-	browser_dbg_pretty-print-06.js \
-	browser_dbg_progress-listener-bug.js \
-	browser_dbg_reload-preferred-script-01.js \
-	browser_dbg_reload-preferred-script-02.js \
-	browser_dbg_reload-preferred-script-03.js \
-	browser_dbg_reload-same-script.js \
-	browser_dbg_scripts-switching-01.js \
-	browser_dbg_scripts-switching-02.js \
-	browser_dbg_scripts-switching-03.js \
-	browser_dbg_search-basic-01.js \
-	browser_dbg_search-basic-02.js \
-	browser_dbg_search-basic-03.js \
-	browser_dbg_search-basic-04.js \
-	browser_dbg_search-global-01.js \
-	browser_dbg_search-global-02.js \
-	browser_dbg_search-global-03.js \
-	browser_dbg_search-global-04.js \
-	browser_dbg_search-global-05.js \
-	browser_dbg_search-global-06.js \
-	browser_dbg_search-sources-01.js \
-	browser_dbg_search-sources-02.js \
-	browser_dbg_search-sources-03.js \
-	browser_dbg_search-symbols.js \
-	browser_dbg_searchbox-help-popup-01.js \
-	browser_dbg_searchbox-help-popup-02.js \
-	browser_dbg_searchbox-parse.js \
-	browser_dbg_source-maps-01.js \
-	browser_dbg_source-maps-02.js \
-	browser_dbg_source-maps-03.js \
-	browser_dbg_sources-cache.js \
-	browser_dbg_sources-labels.js \
-	browser_dbg_sources-sorting.js \
-	browser_dbg_stack-01.js \
-	browser_dbg_stack-02.js \
-	browser_dbg_stack-03.js \
-	browser_dbg_stack-04.js \
-	browser_dbg_stack-05.js \
-	browser_dbg_stack-06.js \
-	browser_dbg_step-out.js \
-	browser_dbg_tabactor-01.js \
-	browser_dbg_tabactor-02.js \
-	browser_dbg_variables-view-01.js \
-	browser_dbg_variables-view-02.js \
-	browser_dbg_variables-view-03.js \
-	browser_dbg_variables-view-04.js \
-	browser_dbg_variables-view-05.js \
-	browser_dbg_variables-view-accessibility.js \
-	browser_dbg_variables-view-data.js \
-	browser_dbg_variables-view-edit-getset-01.js \
-	browser_dbg_variables-view-edit-getset-02.js \
-	browser_dbg_variables-view-edit-value.js \
-	browser_dbg_variables-view-edit-watch.js \
-	browser_dbg_variables-view-filter-01.js \
-	browser_dbg_variables-view-filter-02.js \
-	browser_dbg_variables-view-filter-03.js \
-	browser_dbg_variables-view-filter-04.js \
-	browser_dbg_variables-view-filter-05.js \
-	browser_dbg_variables-view-filter-pref.js \
-	browser_dbg_variables-view-filter-searchbox.js \
-	browser_dbg_variables-view-frame-parameters-01.js \
-	browser_dbg_variables-view-frame-parameters-02.js \
-	browser_dbg_variables-view-frame-parameters-03.js \
-	browser_dbg_variables-view-frame-with.js \
-	browser_dbg_variables-view-frozen-sealed-nonext.js \
-	browser_dbg_variables-view-hide-non-enums.js \
-	browser_dbg_variables-view-large-array-buffer.js \
-	browser_dbg_variables-view-reexpand-01.js \
-	browser_dbg_variables-view-reexpand-02.js \
-	browser_dbg_variables-view-webidl.js \
-	browser_dbg_watch-expressions-01.js \
-	browser_dbg_watch-expressions-02.js \
-	head.js \
-	doc_binary_search.html \
-	doc_blackboxing.html \
-	doc_cmd-break.html \
-	doc_cmd-dbg.html \
-	doc_conditional-breakpoints.html \
-	doc_editor-mode.html \
-	doc_empty-tab-01.html \
-	doc_empty-tab-02.html \
-	doc_event-listeners.html \
-	doc_frame-parameters.html \
-	doc_function-display-name.html \
-	doc_function-search.html \
-	doc_iframes.html \
-	doc_included-script.html \
-	doc_inline-debugger-statement.html \
-	doc_inline-script.html \
-	doc_large-array-buffer.html \
-	doc_minified.html \
-	doc_pause-exceptions.html \
-	doc_pretty-print.html \
-	doc_recursion-stack.html \
-	doc_script-switching-01.html \
-	doc_script-switching-02.html \
-	doc_step-out.html \
-	doc_watch-expressions.html \
-	doc_with-frame.html \
-	code_binary_search.coffee \
-	code_binary_search.js \
-	code_binary_search.map \
-	code_blackboxing_blackboxme.js \
-	code_blackboxing_one.js \
-	code_blackboxing_two.js \
-	code_blackboxing_three.js \
-	code_function-search-01.js \
-	code_function-search-02.js \
-	code_function-search-03.js \
-	code_location-changes.js \
-	code_math.js \
-	code_math.map \
-	code_math.min.js \
-	code_script-switching-01.js \
-	code_script-switching-02.js \
-	code_test-editor-mode \
-	code_ugly.js \
-	testactors.js \
-	addon1.xpi \
-	addon2.xpi \
-	$(NULL)
-
 # Bug 888811 & bug 891176:
 #   Disable browser_dbg_on-pause-raise.js due to frequent failures
 # Bug 847558:
 #   Disable browser_dbg_chrome-create.js to fix Ubuntu hangs
 ifneq (Linux,$(OS_ARCH))
 MOCHITEST_BROWSER_FILES += \
 	browser_dbg_chrome-create.js \
 	browser_dbg_on-pause-raise.js \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser.ini
@@ -0,0 +1,174 @@
+[DEFAULT]
+support-files =
+  addon1.xpi
+  addon2.xpi
+  code_binary_search.coffee
+  code_binary_search.js
+  code_binary_search.map
+  code_blackboxing_blackboxme.js
+  code_blackboxing_one.js
+  code_blackboxing_three.js
+  code_blackboxing_two.js
+  code_function-search-01.js
+  code_function-search-02.js
+  code_function-search-03.js
+  code_location-changes.js
+  code_math.js
+  code_math.map
+  code_math.min.js
+  code_script-switching-01.js
+  code_script-switching-02.js
+  code_test-editor-mode
+  code_ugly.js
+  doc_binary_search.html
+  doc_blackboxing.html
+  doc_cmd-break.html
+  doc_cmd-dbg.html
+  doc_conditional-breakpoints.html
+  doc_editor-mode.html
+  doc_empty-tab-01.html
+  doc_empty-tab-02.html
+  doc_event-listeners.html
+  doc_frame-parameters.html
+  doc_function-display-name.html
+  doc_function-search.html
+  doc_iframes.html
+  doc_included-script.html
+  doc_inline-debugger-statement.html
+  doc_inline-script.html
+  doc_large-array-buffer.html
+  doc_minified.html
+  doc_pause-exceptions.html
+  doc_pretty-print.html
+  doc_recursion-stack.html
+  doc_script-switching-01.html
+  doc_script-switching-02.html
+  doc_step-out.html
+  doc_watch-expressions.html
+  doc_with-frame.html
+  head.js
+  testactors.js
+
+[browser_dbg_aaa_run_first_leaktest.js]
+[browser_dbg_bfcache.js]
+[browser_dbg_blackboxing-01.js]
+[browser_dbg_blackboxing-02.js]
+[browser_dbg_blackboxing-03.js]
+[browser_dbg_blackboxing-04.js]
+[browser_dbg_blackboxing-05.js]
+[browser_dbg_blackboxing-06.js]
+[browser_dbg_blackboxing-07.js]
+[browser_dbg_breadcrumbs-access.js]
+[browser_dbg_breakpoints-actual-location.js]
+[browser_dbg_breakpoints-contextmenu.js]
+[browser_dbg_breakpoints-disabled-reload.js]
+[browser_dbg_breakpoints-editor.js]
+[browser_dbg_breakpoints-highlight.js]
+[browser_dbg_breakpoints-new-script.js]
+[browser_dbg_breakpoints-pane.js]
+[browser_dbg_chrome-debugging.js]
+[browser_dbg_clean-exit-window.js]
+[browser_dbg_clean-exit.js]
+[browser_dbg_cmd-blackbox.js]
+[browser_dbg_cmd-break.js]
+[browser_dbg_cmd-dbg.js]
+[browser_dbg_conditional-breakpoints-01.js]
+[browser_dbg_conditional-breakpoints-02.js]
+[browser_dbg_debugger-statement.js]
+[browser_dbg_editor-contextmenu.js]
+[browser_dbg_editor-mode.js]
+[browser_dbg_function-display-name.js]
+[browser_dbg_globalactor.js]
+[browser_dbg_iframes.js]
+[browser_dbg_instruments-pane-collapse.js]
+[browser_dbg_listaddons.js]
+[browser_dbg_listtabs-01.js]
+[browser_dbg_listtabs-02.js]
+[browser_dbg_location-changes-01-simple.js]
+[browser_dbg_location-changes-02-blank.js]
+[browser_dbg_location-changes-03-new.js]
+[browser_dbg_location-changes-04-breakpoint.js]
+[browser_dbg_multiple-windows.js]
+[browser_dbg_navigation.js]
+[browser_dbg_on-pause-highlight.js]
+[browser_dbg_panel-size.js]
+[browser_dbg_pause-exceptions-01.js]
+[browser_dbg_pause-exceptions-02.js]
+[browser_dbg_pause-resume.js]
+[browser_dbg_pause-warning.js]
+[browser_dbg_pretty-print-01.js]
+[browser_dbg_pretty-print-02.js]
+[browser_dbg_pretty-print-03.js]
+[browser_dbg_pretty-print-04.js]
+[browser_dbg_pretty-print-05.js]
+[browser_dbg_pretty-print-06.js]
+[browser_dbg_progress-listener-bug.js]
+[browser_dbg_reload-preferred-script-01.js]
+[browser_dbg_reload-preferred-script-02.js]
+[browser_dbg_reload-preferred-script-03.js]
+[browser_dbg_reload-same-script.js]
+[browser_dbg_scripts-switching-01.js]
+[browser_dbg_scripts-switching-02.js]
+[browser_dbg_scripts-switching-03.js]
+[browser_dbg_search-basic-01.js]
+[browser_dbg_search-basic-02.js]
+[browser_dbg_search-basic-03.js]
+[browser_dbg_search-basic-04.js]
+[browser_dbg_search-global-01.js]
+[browser_dbg_search-global-02.js]
+[browser_dbg_search-global-03.js]
+[browser_dbg_search-global-04.js]
+[browser_dbg_search-global-05.js]
+[browser_dbg_search-global-06.js]
+[browser_dbg_search-sources-01.js]
+[browser_dbg_search-sources-02.js]
+[browser_dbg_search-sources-03.js]
+[browser_dbg_search-symbols.js]
+[browser_dbg_searchbox-help-popup-01.js]
+[browser_dbg_searchbox-help-popup-02.js]
+[browser_dbg_searchbox-parse.js]
+[browser_dbg_source-maps-01.js]
+[browser_dbg_source-maps-02.js]
+[browser_dbg_source-maps-03.js]
+[browser_dbg_sources-cache.js]
+[browser_dbg_sources-labels.js]
+[browser_dbg_sources-sorting.js]
+[browser_dbg_stack-01.js]
+[browser_dbg_stack-02.js]
+[browser_dbg_stack-03.js]
+[browser_dbg_stack-04.js]
+[browser_dbg_stack-05.js]
+[browser_dbg_stack-06.js]
+[browser_dbg_step-out.js]
+[browser_dbg_tabactor-01.js]
+[browser_dbg_tabactor-02.js]
+[browser_dbg_variables-view-01.js]
+[browser_dbg_variables-view-02.js]
+[browser_dbg_variables-view-03.js]
+[browser_dbg_variables-view-04.js]
+[browser_dbg_variables-view-05.js]
+[browser_dbg_variables-view-accessibility.js]
+[browser_dbg_variables-view-data.js]
+[browser_dbg_variables-view-edit-getset-01.js]
+[browser_dbg_variables-view-edit-getset-02.js]
+[browser_dbg_variables-view-edit-value.js]
+[browser_dbg_variables-view-edit-watch.js]
+[browser_dbg_variables-view-filter-01.js]
+[browser_dbg_variables-view-filter-02.js]
+[browser_dbg_variables-view-filter-03.js]
+[browser_dbg_variables-view-filter-04.js]
+[browser_dbg_variables-view-filter-05.js]
+[browser_dbg_variables-view-filter-pref.js]
+[browser_dbg_variables-view-filter-searchbox.js]
+[browser_dbg_variables-view-frame-parameters-01.js]
+[browser_dbg_variables-view-frame-parameters-02.js]
+[browser_dbg_variables-view-frame-parameters-03.js]
+[browser_dbg_variables-view-frame-with.js]
+[browser_dbg_variables-view-frozen-sealed-nonext.js]
+[browser_dbg_variables-view-hide-non-enums.js]
+[browser_dbg_variables-view-large-array-buffer.js]
+[browser_dbg_variables-view-reexpand-01.js]
+[browser_dbg_variables-view-reexpand-02.js]
+[browser_dbg_variables-view-webidl.js]
+[browser_dbg_watch-expressions-01.js]
+[browser_dbg_watch-expressions-02.js]
--- a/browser/devtools/debugger/test/moz.build
+++ b/browser/devtools/debugger/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/fontinspector/test/Makefile.in
+++ b/browser/devtools/fontinspector/test/Makefile.in
@@ -1,9 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-		browser_fontinspector.js \
-		browser_fontinspector.html \
-		browser_font.woff \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/fontinspector/test/browser.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+
+[browser_font.woff]
+[browser_fontinspector.html]
+[browser_fontinspector.js]
--- a/browser/devtools/fontinspector/test/moz.build
+++ b/browser/devtools/fontinspector/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/framework/test/Makefile.in
+++ b/browser/devtools/framework/test/Makefile.in
@@ -1,28 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-		head.js \
-		browser_devtools_api.js \
-		browser_dynamic_tool_enabling.js \
-		browser_new_activation_workflow.js \
-		browser_toolbox_dynamic_registration.js \
-		browser_toolbox_hosts.js \
-		browser_toolbox_ready.js \
-		browser_toolbox_select_event.js \
-		browser_target_events.js \
-		browser_toolbox_tool_ready.js \
-		browser_toolbox_sidebar.js \
-		browser_toolbox_window_shortcuts.js \
-		browser_toolbox_tabsswitch_shortcuts.js \
-		browser_toolbox_window_title_changes.js \
-		browser_toolbox_options.js \
-		browser_toolbox_options_disablejs.js \
-		browser_toolbox_options_disablejs.html \
-		browser_toolbox_options_disablejs_iframe.html \
-		browser_toolbox_highlight.js \
-		browser_toolbox_raise.js \
-		browser_toolbox_zoom.js \
-		browser_keybindings.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/framework/test/browser.ini
@@ -0,0 +1,24 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_devtools_api.js]
+[browser_dynamic_tool_enabling.js]
+[browser_keybindings.js]
+[browser_new_activation_workflow.js]
+[browser_target_events.js]
+[browser_toolbox_dynamic_registration.js]
+[browser_toolbox_highlight.js]
+[browser_toolbox_hosts.js]
+[browser_toolbox_options.js]
+[browser_toolbox_options_disablejs.html]
+[browser_toolbox_options_disablejs.js]
+[browser_toolbox_options_disablejs_iframe.html]
+[browser_toolbox_raise.js]
+[browser_toolbox_ready.js]
+[browser_toolbox_select_event.js]
+[browser_toolbox_sidebar.js]
+[browser_toolbox_tabsswitch_shortcuts.js]
+[browser_toolbox_tool_ready.js]
+[browser_toolbox_window_shortcuts.js]
+[browser_toolbox_window_title_changes.js]
+[browser_toolbox_zoom.js]
--- a/browser/devtools/framework/test/moz.build
+++ b/browser/devtools/framework/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/inspector/test/Makefile.in
+++ b/browser/devtools/inspector/test/Makefile.in
@@ -1,49 +1,7 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Disabled for too many intermittent failures (bug 851349)
 #		browser_inspector_bug_831693_searchbox_panel_navigation.js \
 
-MOCHITEST_BROWSER_FILES := \
-		browser_inspector_iframeTest.js \
-		browser_inspector_initialization.js \
-		browser_inspector_highlighter.js \
-		browser_inspector_scrolling.js \
-		browser_inspector_bug_665880.js \
-		browser_inspector_infobar.js \
-		browser_inspector_breadcrumbs.html \
-		browser_inspector_breadcrumbs.js \
-		browser_inspector_invalidate.js \
-		browser_inspector_menu.js \
-		browser_inspector_menu.html \
-		browser_inspector_pseudoClass_menu.js \
-		browser_inspector_destroyselection.html \
-		browser_inspector_destroyselection.js \
-		browser_inspector_bug_699308_iframe_navigation.js \
-		browser_inspector_bug_672902_keyboard_shortcuts.js \
-		browser_inspector_sidebarstate.js \
-		browser_inspector_pseudoclass_lock.js \
-		browser_inspector_cmd_inspect.js \
-		browser_inspector_cmd_inspect.html \
-		browser_inspector_highlighter_autohide.js \
-		browser_inspector_changes.js \
-		browser_inspector_bug_674871.js \
-		browser_inspector_bug_817558_delete_node.js \
-		browser_inspector_bug_650804_search.js \
-		browser_inspector_bug_650804_search.html \
-		browser_inspector_bug_831693_input_suggestion.js \
-		browser_inspector_bug_831693_combinator_suggestions.js \
-		browser_inspector_bug_831693_search_suggestions.html \
-		browser_inspector_bug_835722_infobar_reappears.js \
-		browser_inspector_bug_840156_destroy_after_navigation.js \
-		browser_inspector_reload.js \
-		browser_inspector_navigation.js \
-		browser_inspector_select_last_selected.js \
-		browser_inspector_select_last_selected.html \
-		browser_inspector_select_last_selected2.html \
-		browser_inspector_basic_highlighter.js \
-    browser_inspector_dead_node_exception.html \
-    browser_inspector_dead_node_exception.js \
-		head.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/inspector/test/browser.ini
@@ -0,0 +1,42 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_inspector_basic_highlighter.js]
+[browser_inspector_breadcrumbs.html]
+[browser_inspector_breadcrumbs.js]
+[browser_inspector_bug_650804_search.html]
+[browser_inspector_bug_650804_search.js]
+[browser_inspector_bug_665880.js]
+[browser_inspector_bug_672902_keyboard_shortcuts.js]
+[browser_inspector_bug_674871.js]
+[browser_inspector_bug_699308_iframe_navigation.js]
+[browser_inspector_bug_817558_delete_node.js]
+[browser_inspector_bug_831693_combinator_suggestions.js]
+[browser_inspector_bug_831693_input_suggestion.js]
+[browser_inspector_bug_831693_search_suggestions.html]
+[browser_inspector_bug_835722_infobar_reappears.js]
+[browser_inspector_bug_840156_destroy_after_navigation.js]
+[browser_inspector_changes.js]
+[browser_inspector_cmd_inspect.html]
+[browser_inspector_cmd_inspect.js]
+[browser_inspector_dead_node_exception.html]
+[browser_inspector_dead_node_exception.js]
+[browser_inspector_destroyselection.html]
+[browser_inspector_destroyselection.js]
+[browser_inspector_highlighter.js]
+[browser_inspector_highlighter_autohide.js]
+[browser_inspector_iframeTest.js]
+[browser_inspector_infobar.js]
+[browser_inspector_initialization.js]
+[browser_inspector_invalidate.js]
+[browser_inspector_menu.html]
+[browser_inspector_menu.js]
+[browser_inspector_navigation.js]
+[browser_inspector_pseudoClass_menu.js]
+[browser_inspector_pseudoclass_lock.js]
+[browser_inspector_reload.js]
+[browser_inspector_scrolling.js]
+[browser_inspector_select_last_selected.html]
+[browser_inspector_select_last_selected.js]
+[browser_inspector_select_last_selected2.html]
+[browser_inspector_sidebarstate.js]
--- a/browser/devtools/inspector/test/moz.build
+++ b/browser/devtools/inspector/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/layoutview/test/Makefile.in
+++ b/browser/devtools/layoutview/test/Makefile.in
@@ -1,7 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-		browser_layoutview.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/layoutview/test/browser.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[browser_layoutview.js]
--- a/browser/devtools/layoutview/test/moz.build
+++ b/browser/devtools/layoutview/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/markupview/test/Makefile.in
+++ b/browser/devtools/markupview/test/Makefile.in
@@ -1,19 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-		browser_inspector_markup_colorconversion.js \
-    browser_inspector_markup_navigation.html \
-    browser_inspector_markup_navigation.js \
-    browser_inspector_markup_mutation.html \
-    browser_inspector_markup_mutation.js \
-    browser_inspector_markup_mutation_flashing.html \
-		browser_inspector_markup_mutation_flashing.js \
-		browser_inspector_markup_edit.html \
-    browser_inspector_markup_edit.js \
-    browser_inspector_markup_subset.html \
-    browser_inspector_markup_subset.js \
-    browser_bug896181_css_mixed_completion_new_attribute.js \
-		head.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/markupview/test/browser.ini
@@ -0,0 +1,17 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_bug896181_css_mixed_completion_new_attribute.js]
+# Bug 916763 - too many intermittent failures
+skip-if = true
+[browser_inspector_markup_colorconversion.js]
+[browser_inspector_markup_edit.html]
+[browser_inspector_markup_edit.js]
+[browser_inspector_markup_mutation.html]
+[browser_inspector_markup_mutation.js]
+[browser_inspector_markup_mutation_flashing.html]
+[browser_inspector_markup_mutation_flashing.js]
+[browser_inspector_markup_navigation.html]
+[browser_inspector_markup_navigation.js]
+[browser_inspector_markup_subset.html]
+[browser_inspector_markup_subset.js]
--- a/browser/devtools/markupview/test/moz.build
+++ b/browser/devtools/markupview/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/netmonitor/test/Makefile.in
+++ b/browser/devtools/netmonitor/test/Makefile.in
@@ -1,63 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-	browser_net_aaa_leaktest.js \
-	browser_net_autoscroll.js \
-	browser_net_simple-init.js \
-	browser_net_page-nav.js \
-	browser_net_prefs-and-l10n.js \
-	browser_net_prefs-reload.js \
-	browser_net_pane-collapse.js \
-	browser_net_pane-toggle.js \
-	browser_net_simple-request.js \
-	browser_net_simple-request-data.js \
-	browser_net_simple-request-details.js \
-	browser_net_content-type.js \
-	browser_net_cyrillic-01.js \
-	browser_net_cyrillic-02.js \
-	browser_net_large-response.js \
-	browser_net_status-codes.js \
-	browser_net_post-data-01.js \
-	browser_net_post-data-02.js \
-	browser_net_jsonp.js \
-	browser_net_json-long.js \
-	browser_net_json-malformed.js \
-	browser_net_json_custom_mime.js \
-	browser_net_timeline_ticks.js \
-	browser_net_sort-01.js \
-	browser_net_sort-02.js \
-	browser_net_sort-03.js \
-	browser_net_filter-01.js \
-	browser_net_filter-02.js \
-	browser_net_filter-03.js \
-	browser_net_accessibility-01.js \
-	browser_net_accessibility-02.js \
-	browser_net_footer-summary.js \
-	browser_net_resend.js \
-	browser_net_req-resp-bodies.js \
-	browser_net_copy_url.js \
-	browser_net_open_request_in_tab.js \
-	head.js \
-	test-image.png \
-	html_simple-test-page.html \
-	html_navigate-test-page.html \
-	html_content-type-test-page.html \
-	html_cyrillic-test-page.html \
-	html_status-codes-test-page.html \
-	html_post-data-test-page.html \
-	html_post-raw-test-page.html \
-	html_jsonp-test-page.html \
-	html_json-long-test-page.html \
-	html_json-malformed-test-page.html \
-	html_json-custom-mime-test-page.html \
-	html_sorting-test-page.html \
-	html_filter-test-page.html \
-	html_infinite-get-page.html \
-	html_custom-get-page.html \
-	sjs_simple-test-server.sjs \
-	sjs_content-type-test-server.sjs \
-	sjs_status-codes-test-server.sjs \
-	sjs_sorting-test-server.sjs \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/netmonitor/test/browser.ini
@@ -0,0 +1,60 @@
+[DEFAULT]
+support-files =
+  head.js
+  html_content-type-test-page.html
+  html_custom-get-page.html
+  html_cyrillic-test-page.html
+  html_filter-test-page.html
+  html_infinite-get-page.html
+  html_json-custom-mime-test-page.html
+  html_json-long-test-page.html
+  html_json-malformed-test-page.html
+  html_jsonp-test-page.html
+  html_navigate-test-page.html
+  html_post-data-test-page.html
+  html_post-raw-test-page.html
+  html_simple-test-page.html
+  html_sorting-test-page.html
+  html_status-codes-test-page.html
+  sjs_content-type-test-server.sjs
+  sjs_simple-test-server.sjs
+  sjs_sorting-test-server.sjs
+  sjs_status-codes-test-server.sjs
+  test-image.png
+
+[browser_net_aaa_leaktest.js]
+[browser_net_accessibility-01.js]
+[browser_net_accessibility-02.js]
+[browser_net_autoscroll.js]
+[browser_net_content-type.js]
+[browser_net_copy_url.js]
+[browser_net_cyrillic-01.js]
+[browser_net_cyrillic-02.js]
+[browser_net_filter-01.js]
+[browser_net_filter-02.js]
+[browser_net_filter-03.js]
+[browser_net_footer-summary.js]
+[browser_net_json-long.js]
+[browser_net_json-malformed.js]
+[browser_net_json_custom_mime.js]
+[browser_net_jsonp.js]
+[browser_net_large-response.js]
+[browser_net_open_request_in_tab.js]
+[browser_net_page-nav.js]
+[browser_net_pane-collapse.js]
+[browser_net_pane-toggle.js]
+[browser_net_post-data-01.js]
+[browser_net_post-data-02.js]
+[browser_net_prefs-and-l10n.js]
+[browser_net_prefs-reload.js]
+[browser_net_req-resp-bodies.js]
+[browser_net_resend.js]
+[browser_net_simple-init.js]
+[browser_net_simple-request-data.js]
+[browser_net_simple-request-details.js]
+[browser_net_simple-request.js]
+[browser_net_sort-01.js]
+[browser_net_sort-02.js]
+[browser_net_sort-03.js]
+[browser_net_status-codes.js]
+[browser_net_timeline_ticks.js]
--- a/browser/devtools/netmonitor/test/moz.build
+++ b/browser/devtools/netmonitor/test/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/profiler/test/Makefile.in
+++ b/browser/devtools/profiler/test/Makefile.in
@@ -1,23 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-		browser_profiler_remote.js \
-		browser_profiler_bug_834878_source_buttons.js \
-		browser_profiler_cmd.js \
-		browser_profiler_run.js \
-		browser_profiler_controller.js \
-		browser_profiler_bug_855244_multiple_tabs.js \
-		browser_profiler_console_api.js \
-		browser_profiler_console_api_named.js \
-		browser_profiler_console_api_mixed.js \
-		browser_profiler_console_api_content.js \
-		browser_profiler_escape.js \
-		browser_profiler_gecko_data.js \
-		browser_profiler_io.js \
-		head.js \
-		mock_profiler_bug_834878_page.html \
-		mock_profiler_bug_834878_script.js \
-		mock_console_api.html \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/profiler/test/browser.ini
@@ -0,0 +1,20 @@
+[DEFAULT]
+support-files =
+  head.js
+  mock_console_api.html
+  mock_profiler_bug_834878_page.html
+  mock_profiler_bug_834878_script.js
+
+[browser_profiler_bug_834878_source_buttons.js]
+[browser_profiler_bug_855244_multiple_tabs.js]
+[browser_profiler_cmd.js]
+[browser_profiler_console_api.js]
+[browser_profiler_console_api_content.js]
+[browser_profiler_console_api_mixed.js]
+[browser_profiler_console_api_named.js]
+[browser_profiler_controller.js]
+[browser_profiler_escape.js]
+[browser_profiler_gecko_data.js]
+[browser_profiler_io.js]
+[browser_profiler_remote.js]
+[browser_profiler_run.js]
--- a/browser/devtools/profiler/test/moz.build
+++ b/browser/devtools/profiler/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/responsivedesign/test/Makefile.in
+++ b/browser/devtools/responsivedesign/test/Makefile.in
@@ -1,14 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-		browser_responsiveui.js \
-		browser_responsiveuiaddcustompreset.js \
-		browser_responsiveruleview.js \
-		browser_responsive_cmd.js \
-		browser_responsivecomputedview.js \
-		browser_responsiveui_touch.js \
-		touch.html \
-		head.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/responsivedesign/test/browser.ini
@@ -0,0 +1,11 @@
+[DEFAULT]
+support-files =
+  head.js
+  touch.html
+
+[browser_responsive_cmd.js]
+[browser_responsivecomputedview.js]
+[browser_responsiveruleview.js]
+[browser_responsiveui.js]
+[browser_responsiveui_touch.js]
+[browser_responsiveuiaddcustompreset.js]
--- a/browser/devtools/responsivedesign/test/moz.build
+++ b/browser/devtools/responsivedesign/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/scratchpad/test/Makefile.in
+++ b/browser/devtools/scratchpad/test/Makefile.in
@@ -1,38 +1,6 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-		browser_scratchpad_initialization.js \
-		browser_scratchpad_contexts.js \
-		browser_scratchpad_tab_switch.js \
-		browser_scratchpad_execute_print.js \
-		browser_scratchpad_inspect.js \
-		browser_scratchpad_files.js \
-		browser_scratchpad_ui.js \
-		browser_scratchpad_bug_646070_chrome_context_pref.js \
-		browser_scratchpad_bug_660560_tab.js \
-		browser_scratchpad_open.js \
-		browser_scratchpad_restore.js \
-		browser_scratchpad_bug_679467_falsy.js \
-		browser_scratchpad_bug_699130_edit_ui_updates.js \
-		browser_scratchpad_bug_669612_unsaved.js \
-		browser_scratchpad_bug684546_reset_undo.js \
-		browser_scratchpad_bug690552_display_outputs_errors.js \
-		browser_scratchpad_bug714942_goto_line_ui.js \
-		browser_scratchpad_bug_650760_help_key.js \
-		browser_scratchpad_bug_651942_recent_files.js \
-		browser_scratchpad_bug756681_display_non_error_exceptions.js \
-		browser_scratchpad_bug_751744_revert_to_saved.js \
-		browser_scratchpad_bug740948_reload_and_run.js \
-		browser_scratchpad_bug_661762_wrong_window_focus.js \
-		browser_scratchpad_bug_644413_modeline.js \
-		browser_scratchpad_bug807924_cannot_convert_to_string.js \
-		browser_scratchpad_long_string.js \
-		browser_scratchpad_open_error_console.js \
-		browser_scratchpad_pprint.js \
-		browser_scratchpad_pprint-02.js\
-		head.js \
-
 # Disable test due to bug 807234 becoming basically permanent
 #		browser_scratchpad_bug_653427_confirm_close.js \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/scratchpad/test/browser.ini
@@ -0,0 +1,32 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_scratchpad_bug684546_reset_undo.js]
+[browser_scratchpad_bug690552_display_outputs_errors.js]
+[browser_scratchpad_bug714942_goto_line_ui.js]
+[browser_scratchpad_bug740948_reload_and_run.js]
+[browser_scratchpad_bug756681_display_non_error_exceptions.js]
+[browser_scratchpad_bug807924_cannot_convert_to_string.js]
+[browser_scratchpad_bug_644413_modeline.js]
+[browser_scratchpad_bug_646070_chrome_context_pref.js]
+[browser_scratchpad_bug_650760_help_key.js]
+[browser_scratchpad_bug_651942_recent_files.js]
+[browser_scratchpad_bug_660560_tab.js]
+[browser_scratchpad_bug_661762_wrong_window_focus.js]
+[browser_scratchpad_bug_669612_unsaved.js]
+[browser_scratchpad_bug_679467_falsy.js]
+[browser_scratchpad_bug_699130_edit_ui_updates.js]
+[browser_scratchpad_bug_751744_revert_to_saved.js]
+[browser_scratchpad_contexts.js]
+[browser_scratchpad_execute_print.js]
+[browser_scratchpad_files.js]
+[browser_scratchpad_initialization.js]
+[browser_scratchpad_inspect.js]
+[browser_scratchpad_long_string.js]
+[browser_scratchpad_open.js]
+[browser_scratchpad_open_error_console.js]
+[browser_scratchpad_pprint-02.js]
+[browser_scratchpad_pprint.js]
+[browser_scratchpad_restore.js]
+[browser_scratchpad_tab_switch.js]
+[browser_scratchpad_ui.js]
--- a/browser/devtools/scratchpad/test/moz.build
+++ b/browser/devtools/scratchpad/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/shared/test/Makefile.in
+++ b/browser/devtools/shared/test/Makefile.in
@@ -1,38 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-		browser_css_color.js \
-		browser_eventemitter_basic.js \
-		browser_observableobject.js \
-		browser_layoutHelpers.js \
-		browser_require_basic.js \
-		browser_telemetry_sidebar.js \
-		browser_telemetry_button_responsive.js \
-		browser_telemetry_button_scratchpad.js \
-		browser_telemetry_button_tilt.js \
-		browser_telemetry_button_paintflashing.js \
-		browser_telemetry_toolboxtabs_inspector.js \
-		browser_telemetry_toolboxtabs_jsdebugger.js \
-		browser_telemetry_toolboxtabs_jsprofiler.js \
-		browser_telemetry_toolboxtabs_netmonitor.js \
-		browser_telemetry_toolboxtabs_options.js \
-		browser_telemetry_toolboxtabs_styleeditor.js \
-		browser_telemetry_toolboxtabs_webconsole.js \
-		browser_templater_basic.js \
-		browser_toolbar_basic.js \
-		browser_toolbar_tooltip.js \
-		browser_toolbar_webconsole_errors_count.js \
-		head.js \
-		leakhunt.js \
-	$(NULL)
-
-MOCHITEST_BROWSER_FILES += \
-		browser_templater_basic.html \
-		browser_toolbar_basic.html \
-		browser_toolbar_webconsole_errors_count.html \
-		browser_layoutHelpers.html \
-		browser_layoutHelpers_iframe.html \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser.ini
@@ -0,0 +1,31 @@
+[DEFAULT]
+support-files =
+  head.js
+  leakhunt.js
+
+[browser_css_color.js]
+[browser_eventemitter_basic.js]
+[browser_layoutHelpers.html]
+[browser_layoutHelpers.js]
+[browser_layoutHelpers_iframe.html]
+[browser_observableobject.js]
+[browser_require_basic.js]
+[browser_telemetry_button_paintflashing.js]
+[browser_telemetry_button_responsive.js]
+[browser_telemetry_button_scratchpad.js]
+[browser_telemetry_button_tilt.js]
+[browser_telemetry_sidebar.js]
+[browser_telemetry_toolboxtabs_inspector.js]
+[browser_telemetry_toolboxtabs_jsdebugger.js]
+[browser_telemetry_toolboxtabs_jsprofiler.js]
+[browser_telemetry_toolboxtabs_netmonitor.js]
+[browser_telemetry_toolboxtabs_options.js]
+[browser_telemetry_toolboxtabs_styleeditor.js]
+[browser_telemetry_toolboxtabs_webconsole.js]
+[browser_templater_basic.html]
+[browser_templater_basic.js]
+[browser_toolbar_basic.html]
+[browser_toolbar_basic.js]
+[browser_toolbar_tooltip.js]
+[browser_toolbar_webconsole_errors_count.html]
+[browser_toolbar_webconsole_errors_count.js]
--- a/browser/devtools/shared/test/moz.build
+++ b/browser/devtools/shared/test/moz.build
@@ -1,7 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
+
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/sourceeditor/test/Makefile.in
+++ b/browser/devtools/sourceeditor/test/Makefile.in
@@ -1,36 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-		browser_sourceeditor_initialization.js \
-		browser_bug684862_paste_html.js \
-		browser_bug687573_vscroll.js \
-		browser_bug687568_pagescroll.js \
-		browser_bug687580_drag_and_drop.js \
-		browser_bug684546_reset_undo.js \
-		browser_bug695035_middle_click_paste.js \
-		browser_bug687160_line_api.js \
-		browser_bug650345_find.js \
-		browser_bug703692_focus_blur.js \
-		browser_bug725388_mouse_events.js \
-		browser_bug707987_debugger_breakpoints.js \
-		browser_bug712982_line_ruler_click.js \
-		browser_bug725618_moveLines_shortcut.js \
-		browser_bug700893_dirty_state.js \
-		browser_bug729480_line_vertical_align.js \
-		browser_bug725430_comment_uncomment.js \
-		browser_bug731721_debugger_stepping.js \
-		browser_bug729960_block_bracket_jump.js \
-		browser_bug744021_next_prev_bracket_jump.js \
-		browser_bug725392_mouse_coords_char_offset.js \
-		browser_codemirror.js \
-		head.js \
-		codemirror.html \
-		cm_comment_test.js \
-		cm_driver.js \
-		cm_mode_test.css \
-		cm_mode_test.js \
-		cm_test.js \
-		cm_mode_javascript_test.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/sourceeditor/test/browser.ini
@@ -0,0 +1,33 @@
+[DEFAULT]
+support-files =
+  cm_comment_test.js
+  cm_driver.js
+  cm_mode_javascript_test.js
+  cm_mode_test.css
+  cm_mode_test.js
+  cm_test.js
+  codemirror.html
+  head.js
+
+[browser_bug650345_find.js]
+[browser_bug684546_reset_undo.js]
+[browser_bug684862_paste_html.js]
+[browser_bug687160_line_api.js]
+[browser_bug687568_pagescroll.js]
+[browser_bug687573_vscroll.js]
+[browser_bug687580_drag_and_drop.js]
+[browser_bug695035_middle_click_paste.js]
+[browser_bug700893_dirty_state.js]
+[browser_bug703692_focus_blur.js]
+[browser_bug707987_debugger_breakpoints.js]
+[browser_bug712982_line_ruler_click.js]
+[browser_bug725388_mouse_events.js]
+[browser_bug725392_mouse_coords_char_offset.js]
+[browser_bug725430_comment_uncomment.js]
+[browser_bug725618_moveLines_shortcut.js]
+[browser_bug729480_line_vertical_align.js]
+[browser_bug729960_block_bracket_jump.js]
+[browser_bug731721_debugger_stepping.js]
+[browser_bug744021_next_prev_bracket_jump.js]
+[browser_codemirror.js]
+[browser_sourceeditor_initialization.js]
--- a/browser/devtools/sourceeditor/test/moz.build
+++ b/browser/devtools/sourceeditor/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/styleeditor/test/Makefile.in
+++ b/browser/devtools/styleeditor/test/Makefile.in
@@ -1,44 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-                 browser_styleeditor_enabled.js \
-                 browser_styleeditor_filesave.js \
-                 browser_styleeditor_cmd_edit.js \
-                 browser_styleeditor_cmd_edit.html \
-                 browser_styleeditor_import.js \
-                 browser_styleeditor_import_rule.js \
-                 browser_styleeditor_init.js \
-                 browser_styleeditor_loading.js \
-                 browser_styleeditor_new.js \
-                 browser_styleeditor_pretty.js \
-                 browser_styleeditor_private_perwindowpb.js \
-                 browser_styleeditor_sv_keynav.js \
-                 browser_styleeditor_sv_resize.js \
-                 browser_styleeditor_bug_740541_iframes.js \
-                 browser_styleeditor_bug_851132_middle_click.js \
-                 browser_styleeditor_bug_870339.js \
-                 browser_styleeditor_nostyle.js \
-                 browser_styleeditor_reload.js \
-                 head.js \
-                 four.html \
-                 import.css \
-                 import.html \
-                 import2.css \
-                 longload.html \
-                 media.html \
-                 media-small.css \
-                 minified.html \
-                 nostyle.html \
-                 resources_inpage.jsi \
-                 resources_inpage1.css \
-                 resources_inpage2.css \
-                 simple.css \
-                 simple.css.gz \
-                 simple.css.gz^headers^ \
-                 simple.gz.html \
-                 simple.html \
-                 test_private.html \
-                 test_private.css \
-                 $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleeditor/test/browser.ini
@@ -0,0 +1,41 @@
+[DEFAULT]
+support-files =
+  four.html
+  head.js
+  import.css
+  import.html
+  import2.css
+  longload.html
+  media-small.css
+  media.html
+  minified.html
+  nostyle.html
+  resources_inpage.jsi
+  resources_inpage1.css
+  resources_inpage2.css
+  simple.css
+  simple.css.gz
+  simple.css.gz^headers^
+  simple.gz.html
+  simple.html
+  test_private.css
+  test_private.html
+
+[browser_styleeditor_bug_740541_iframes.js]
+[browser_styleeditor_bug_851132_middle_click.js]
+[browser_styleeditor_bug_870339.js]
+[browser_styleeditor_cmd_edit.html]
+[browser_styleeditor_cmd_edit.js]
+[browser_styleeditor_enabled.js]
+[browser_styleeditor_filesave.js]
+[browser_styleeditor_import.js]
+[browser_styleeditor_import_rule.js]
+[browser_styleeditor_init.js]
+[browser_styleeditor_loading.js]
+[browser_styleeditor_new.js]
+[browser_styleeditor_nostyle.js]
+[browser_styleeditor_pretty.js]
+[browser_styleeditor_private_perwindowpb.js]
+[browser_styleeditor_reload.js]
+[browser_styleeditor_sv_keynav.js]
+[browser_styleeditor_sv_resize.js]
--- a/browser/devtools/styleeditor/test/moz.build
+++ b/browser/devtools/styleeditor/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/tilt/test/Makefile.in
+++ b/browser/devtools/tilt/test/Makefile.in
@@ -1,53 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-	head.js \
-	browser_tilt_01_lazy_getter.js \
-	browser_tilt_02_notifications-seq.js \
-	browser_tilt_02_notifications.js \
-	browser_tilt_02_notifications-tabs.js \
-	browser_tilt_03_tab_switch.js \
-	browser_tilt_04_initialization.js \
-	browser_tilt_05_destruction-esc.js \
-	browser_tilt_05_destruction-url.js \
-	browser_tilt_05_destruction.js \
-	browser_tilt_arcball-reset-typeahead.js \
-	browser_tilt_arcball-reset.js \
-	browser_tilt_arcball.js \
-	browser_tilt_controller.js \
-	browser_tilt_gl01.js \
-	browser_tilt_gl02.js \
-	browser_tilt_gl03.js \
-	browser_tilt_gl04.js \
-	browser_tilt_gl05.js \
-	browser_tilt_gl06.js \
-	browser_tilt_gl07.js \
-	browser_tilt_gl08.js \
-	browser_tilt_math01.js \
-	browser_tilt_math02.js \
-	browser_tilt_math03.js \
-	browser_tilt_math04.js \
-	browser_tilt_math05.js \
-	browser_tilt_math06.js \
-	browser_tilt_math07.js \
-	browser_tilt_picking.js \
-	browser_tilt_picking_inspector.js \
-	browser_tilt_picking_delete.js \
-	browser_tilt_picking_highlight01-offs.js \
-	browser_tilt_picking_highlight01.js \
-	browser_tilt_picking_highlight02.js \
-	browser_tilt_picking_highlight03.js \
-	browser_tilt_picking_miv.js \
-	browser_tilt_utils01.js \
-	browser_tilt_utils02.js \
-	browser_tilt_utils03.js \
-	browser_tilt_utils04.js \
-	browser_tilt_utils05.js \
-	browser_tilt_utils06.js \
-	browser_tilt_utils07.js \
-	browser_tilt_utils08.js \
-	browser_tilt_visualizer.js \
-	browser_tilt_zoom.js \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/tilt/test/browser.ini
@@ -0,0 +1,49 @@
+[DEFAULT]
+support-files = head.js
+
+[browser_tilt_01_lazy_getter.js]
+[browser_tilt_02_notifications-seq.js]
+[browser_tilt_02_notifications-tabs.js]
+[browser_tilt_02_notifications.js]
+[browser_tilt_03_tab_switch.js]
+[browser_tilt_04_initialization.js]
+[browser_tilt_05_destruction-esc.js]
+[browser_tilt_05_destruction-url.js]
+[browser_tilt_05_destruction.js]
+[browser_tilt_arcball-reset-typeahead.js]
+[browser_tilt_arcball-reset.js]
+[browser_tilt_arcball.js]
+[browser_tilt_controller.js]
+[browser_tilt_gl01.js]
+[browser_tilt_gl02.js]
+[browser_tilt_gl03.js]
+[browser_tilt_gl04.js]
+[browser_tilt_gl05.js]
+[browser_tilt_gl06.js]
+[browser_tilt_gl07.js]
+[browser_tilt_gl08.js]
+[browser_tilt_math01.js]
+[browser_tilt_math02.js]
+[browser_tilt_math03.js]
+[browser_tilt_math04.js]
+[browser_tilt_math05.js]
+[browser_tilt_math06.js]
+[browser_tilt_math07.js]
+[browser_tilt_picking.js]
+[browser_tilt_picking_delete.js]
+[browser_tilt_picking_highlight01-offs.js]
+[browser_tilt_picking_highlight01.js]
+[browser_tilt_picking_highlight02.js]
+[browser_tilt_picking_highlight03.js]
+[browser_tilt_picking_inspector.js]
+[browser_tilt_picking_miv.js]
+[browser_tilt_utils01.js]
+[browser_tilt_utils02.js]
+[browser_tilt_utils03.js]
+[browser_tilt_utils04.js]
+[browser_tilt_utils05.js]
+[browser_tilt_utils06.js]
+[browser_tilt_utils07.js]
+[browser_tilt_utils08.js]
+[browser_tilt_visualizer.js]
+[browser_tilt_zoom.js]
--- a/browser/devtools/tilt/test/moz.build
+++ b/browser/devtools/tilt/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/devtools/webconsole/test/Makefile.in
+++ b/browser/devtools/webconsole/test/Makefile.in
@@ -1,248 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-	browser_webconsole_notifications.js \
-	browser_webconsole_message_node_id.js \
-	browser_webconsole_bug_580030_errors_after_page_reload.js \
-	browser_webconsole_basic_net_logging.js \
-	browser_webconsole_bug_579412_input_focus.js \
-	browser_webconsole_bug_580001_closing_after_completion.js \
-	browser_webconsole_bug_588730_text_node_insertion.js \
-	browser_webconsole_bug_601667_filter_buttons.js \
-	browser_webconsole_bug_597136_external_script_errors.js \
-	browser_webconsole_bug_597136_network_requests_from_chrome.js \
-	browser_webconsole_completion.js \
-	browser_webconsole_console_logging_api.js \
-	browser_webconsole_change_font_size.js \
-	browser_webconsole_chrome.js \
-	browser_webconsole_execution_scope.js \
-	browser_webconsole_for_of.js \
-	browser_webconsole_history.js \
-	browser_webconsole_js_input_expansion.js \
-	browser_webconsole_live_filtering_of_message_types.js \
-	browser_webconsole_live_filtering_on_search_strings.js \
-	browser_warn_user_about_replaced_api.js \
-	browser_webconsole_bug_586388_select_all.js  \
-	browser_webconsole_bug_588967_input_expansion.js \
-	browser_webconsole_network_panel.js \
-	browser_webconsole_jsterm.js \
-	browser_webconsole_output_order.js \
-	browser_webconsole_property_provider.js \
-	browser_webconsole_bug_587617_output_copy.js \
-	browser_webconsole_bug_585237_line_limit.js \
-	browser_webconsole_bug_582201_duplicate_errors.js \
-	browser_webconsole_bug_580454_timestamp_l10n.js \
-	browser_webconsole_netlogging.js \
-	browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js \
-	browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js \
-	browser_webconsole_bug_594477_clickable_output.js \
-	browser_webconsole_bug_589162_css_filter.js \
-	browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js \
-	browser_webconsole_bug_595350_multiple_windows_and_tabs.js \
-	browser_webconsole_bug_594497_history_arrow_keys.js \
-	browser_webconsole_bug_588342_document_focus.js \
-	browser_webconsole_bug_595934_message_categories.js \
-	browser_webconsole_bug_601352_scroll.js \
-	browser_webconsole_bug_592442_closing_brackets.js \
-	browser_webconsole_bug_593003_iframe_wrong_hud.js \
-	browser_webconsole_bug_613013_console_api_iframe.js \
-	browser_webconsole_bug_597756_reopen_closed_tab.js \
-	browser_webconsole_bug_600183_charset.js \
-	browser_webconsole_bug_601177_log_levels.js \
-	browser_webconsole_bug_597460_filter_scroll.js \
-	browser_webconsole_console_extras.js \
-	browser_webconsole_bug_598357_jsterm_output.js \
-	browser_webconsole_bug_603750_websocket.js \
-	browser_webconsole_abbreviate_source_url.js \
-	browser_webconsole_view_source.js \
-	browser_webconsole_bug_602572_log_bodies_checkbox.js \
-	browser_webconsole_bug_614793_jsterm_scroll.js \
-	browser_webconsole_bug_599725_response_headers.js \
-	browser_webconsole_bug_613642_maintain_scroll.js \
-	browser_webconsole_bug_613642_prune_scroll.js \
-	browser_webconsole_bug_618078_network_exceptions.js \
-	browser_webconsole_bug_613280_jsterm_copy.js \
-	browser_webconsole_bug_630733_response_redirect_headers.js \
-	browser_webconsole_bug_621644_jsterm_dollar.js \
-	browser_webconsole_bug_632817.js \
-	browser_webconsole_bug_611795.js \
-	browser_webconsole_bug_618311_close_panels.js \
-	browser_webconsole_bug_632347_iterators_generators.js \
-	browser_webconsole_bug_642108_pruneTest.js \
-	browser_webconsole_bug_585956_console_trace.js \
-	browser_webconsole_bug_595223_file_uri.js \
-	browser_webconsole_bug_632275_getters_document_width.js \
-	browser_webconsole_bug_644419_log_limits.js \
-	browser_webconsole_bug_646025_console_file_location.js \
-	browser_webconsole_bug_642615_autocomplete.js \
-	browser_webconsole_bug_585991_autocomplete_popup.js \
-	browser_webconsole_bug_585991_autocomplete_keys.js \
-	browser_webconsole_bug_660806_history_nav.js \
-	browser_webconsole_bug_651501_document_body_autocomplete.js \
-	browser_webconsole_bug_653531_highlighter_console_helper.js \
-	browser_webconsole_bug_659907_console_dir.js \
-	browser_webconsole_bug_664131_console_group.js \
-	browser_webconsole_bug_704295.js \
-	browser_webconsole_bug_658368_time_methods.js \
-	browser_webconsole_bug_764572_output_open_url.js \
-	browser_webconsole_bug_622303_persistent_filters.js \
-	browser_webconsole_bug_770099_bad_policyuri.js \
-	browser_webconsole_bug_770099_violation.js \
-	browser_webconsole_bug_766001_JS_Console_in_Debugger.js \
-	browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js \
-	browser_cached_messages.js \
-	browser_bug664688_sandbox_update_after_navigation.js \
-	browser_result_format_as_string.js \
-	browser_webconsole_bug_737873_mixedcontent.js \
-	browser_output_breaks_after_console_dir_uninspectable.js \
-	browser_console_log_inspectable_object.js \
-	browser_bug_638949_copy_link_location.js \
-	browser_output_longstring_expand.js \
-	browser_netpanel_longstring_expand.js \
-	browser_repeated_messages_accuracy.js \
-	browser_webconsole_bug_821877_csp_errors.js \
-	browser_webconsole_bug_846918_hsts_invalid-headers.js \
-	browser_eval_in_debugger_stackframe.js \
-	browser_console_variables_view.js \
-	browser_console_variables_view_while_debugging.js \
-	browser_console.js \
-	browser_longstring_hang.js \
-	browser_console_consolejsm_output.js \
-	browser_webconsole_bug_837351_securityerrors.js \
-	browser_bug_865871_variables_view_close_on_esc_key.js \
-	browser_bug_865288_repeat_different_objects.js \
-	browser_jsterm_inspect.js \
-	browser_bug_869003_inspect_cross_domain_object.js \
-	browser_bug_862916_console_dir_and_filter_off.js \
-	browser_console_native_getters.js \
-	browser_bug_871156_ctrlw_close_tab.js \
-	browser_console_private_browsing.js \
-	browser_console_nsiconsolemessage.js \
-	browser_webconsole_bug_817834_add_edited_input_to_history.js \
-	browser_console_addonsdk_loader_exception.js \
-	browser_console_error_source_click.js \
-	browser_console_clear_on_reload.js \
-	browser_console_keyboard_accessibility.js \
-	browser_console_filters.js \
-	browser_console_dead_objects.js \
-	browser_console_iframe_messages.js \
-	browser_console_variables_view_while_debugging_and_inspecting.js \
-	browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js \
-	browser_webconsole_cached_autocomplete.js \
-	browser_console_navigation_marker.js \
-	browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js \
-	browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js \
-	browser_webconsole_allow_mixedcontent_securityerrors.js \
-	browser_webconsole_block_mixedcontent_securityerrors.js \
-	browser_webconsole_output_copy_newlines.js \
-	head.js \
-	$(NULL)
-
 ifeq ($(OS_ARCH), Darwin)
 MOCHITEST_BROWSER_FILES += \
 	browser_webconsole_bug_804845_ctrl_key_nav.js \
         $(NULL)
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 MOCHITEST_BROWSER_FILES += \
 	browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js \
 	$(NULL)
 endif
 
-MOCHITEST_BROWSER_FILES += \
-	test-console.html \
-	test-network.html \
-	test-network-request.html \
-	test-mutation.html \
-	testscript.js \
-	test-filter.html \
-	test-observe-http-ajax.html \
-	test-data.json \
-	test-data.json^headers^ \
-	test-property-provider.html \
-	test-error.html \
-	test-duplicate-error.html \
-	test-image.png \
-	test-encoding-ISO-8859-1.html \
-	test-bug-593003-iframe-wrong-hud.html \
-	test-bug-593003-iframe-wrong-hud-iframe.html \
-	test-console-replaced-api.html \
-	test-own-console.html \
-	test-bug-595934-css-loader.html \
-	test-bug-595934-css-loader.css \
-	test-bug-595934-css-loader.css^headers^ \
-	test-bug-595934-imagemap.html \
-	test-bug-595934-html.html \
-	test-bug-595934-malformedxml.xhtml \
-	test-bug-595934-svg.xhtml \
-	test-bug-595934-workers.html \
-	test-bug-595934-workers.js \
-	test-bug-595934-css-parser.html \
-	test-bug-595934-css-parser.css \
-	test-bug-595934-canvas-css.html \
-	test-bug-595934-canvas-css.js \
-	test-bug-595934-malformedxml-external.html \
-	test-bug-595934-malformedxml-external.xml \
-	test-bug-595934-empty-getelementbyid.html \
-	test-bug-595934-empty-getelementbyid.js \
-	test-bug-595934-image.html \
-	test-bug-595934-image.jpg \
-	test-bug-597136-external-script-errors.html \
-	test-bug-597136-external-script-errors.js \
-	test-bug-613013-console-api-iframe.html \
-	test-bug-597756-reopen-closed-tab.html \
-	test-bug-600183-charset.html \
-	test-bug-600183-charset.html^headers^ \
-	test-bug-601177-log-levels.html \
-	test-bug-601177-log-levels.js \
-	test-console-extras.html \
-	test-bug-603750-websocket.html \
-	test-bug-603750-websocket.js \
-	test-bug-599725-response-headers.sjs \
-	test-bug-618078-network-exceptions.html \
-	test-bug-630733-response-redirect-headers.sjs \
-	test-bug-621644-jsterm-dollar.html \
-	test-bug-632347-iterators-generators.html \
-	test-bug-585956-console-trace.html \
-	test-bug-644419-log-limits.html \
-	test-bug-632275-getters.html \
-	test-bug-646025-console-file-location.html \
-	test-bug-782653-css-errors.html \
-	test-bug-782653-css-errors-1.css \
-	test-bug-782653-css-errors-2.css \
-	test-file-location.js \
-	test-bug-658368-time-methods.html \
-	test-webconsole-error-observer.html \
-	test-for-of.html \
-	test_bug_770099_violation.html \
-	test_bug_770099_violation.html^headers^ \
-	test_bug_770099_bad_policy_uri.html \
-	test_bug_770099_bad_policy_uri.html^headers^ \
-	test-result-format-as-string.html \
-	test-bug-737873-mixedcontent.html \
-	test-repeated-messages.html \
-	test-bug-766001-console-log.js \
-	test-bug-766001-js-console-links.html \
-	test-bug-766001-js-errors.js \
-	test-bug-821877-csperrors.html \
-	test-bug-821877-csperrors.html^headers^ \
-	test-bug-846918-hsts-invalid-headers.html \
-	test-bug-846918-hsts-invalid-headers.html^headers^ \
-	test-eval-in-stackframe.html \
-	test-bug-859170-longstring-hang.html \
-	test-bug-837351-security-errors.html \
-	test-bug-869003-top-window.html \
-	test-bug-869003-iframe.html \
-	test-iframe-762593-insecure-form-action.html \
-	test-iframe-762593-insecure-frame.html \
-	test-bug-762593-insecure-passwords-web-console-warning.html \
-	test-bug-762593-insecure-passwords-about-blank-web-console-warning.html \
-	test-consoleiframes.html \
-	test-iframe1.html \
-	test-iframe2.html \
-	test-iframe3.html \
-	test-mixedcontent-securityerrors.html \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -0,0 +1,230 @@
+[DEFAULT]
+support-files =
+  head.js
+  test-bug-585956-console-trace.html
+  test-bug-593003-iframe-wrong-hud-iframe.html
+  test-bug-593003-iframe-wrong-hud.html
+  test-bug-595934-canvas-css.html
+  test-bug-595934-canvas-css.js
+  test-bug-595934-css-loader.css
+  test-bug-595934-css-loader.css^headers^
+  test-bug-595934-css-loader.html
+  test-bug-595934-css-parser.css
+  test-bug-595934-css-parser.html
+  test-bug-595934-empty-getelementbyid.html
+  test-bug-595934-empty-getelementbyid.js
+  test-bug-595934-html.html
+  test-bug-595934-image.html
+  test-bug-595934-image.jpg
+  test-bug-595934-imagemap.html
+  test-bug-595934-malformedxml-external.html
+  test-bug-595934-malformedxml-external.xml
+  test-bug-595934-malformedxml.xhtml
+  test-bug-595934-svg.xhtml
+  test-bug-595934-workers.html
+  test-bug-595934-workers.js
+  test-bug-597136-external-script-errors.html
+  test-bug-597136-external-script-errors.js
+  test-bug-597756-reopen-closed-tab.html
+  test-bug-599725-response-headers.sjs
+  test-bug-600183-charset.html
+  test-bug-600183-charset.html^headers^
+  test-bug-601177-log-levels.html
+  test-bug-601177-log-levels.js
+  test-bug-603750-websocket.html
+  test-bug-603750-websocket.js
+  test-bug-613013-console-api-iframe.html
+  test-bug-618078-network-exceptions.html
+  test-bug-621644-jsterm-dollar.html
+  test-bug-630733-response-redirect-headers.sjs
+  test-bug-632275-getters.html
+  test-bug-632347-iterators-generators.html
+  test-bug-644419-log-limits.html
+  test-bug-646025-console-file-location.html
+  test-bug-658368-time-methods.html
+  test-bug-737873-mixedcontent.html
+  test-bug-762593-insecure-passwords-about-blank-web-console-warning.html
+  test-bug-762593-insecure-passwords-web-console-warning.html
+  test-bug-766001-console-log.js
+  test-bug-766001-js-console-links.html
+  test-bug-766001-js-errors.js
+  test-bug-782653-css-errors-1.css
+  test-bug-782653-css-errors-2.css
+  test-bug-782653-css-errors.html
+  test-bug-821877-csperrors.html
+  test-bug-821877-csperrors.html^headers^
+  test-bug-837351-security-errors.html
+  test-bug-846918-hsts-invalid-headers.html
+  test-bug-846918-hsts-invalid-headers.html^headers^
+  test-bug-859170-longstring-hang.html
+  test-bug-869003-iframe.html
+  test-bug-869003-top-window.html
+  test-console-extras.html
+  test-console-replaced-api.html
+  test-console.html
+  test-consoleiframes.html
+  test-data.json
+  test-data.json^headers^
+  test-duplicate-error.html
+  test-encoding-ISO-8859-1.html
+  test-error.html
+  test-eval-in-stackframe.html
+  test-file-location.js
+  test-filter.html
+  test-for-of.html
+  test-iframe-762593-insecure-form-action.html
+  test-iframe-762593-insecure-frame.html
+  test-iframe1.html
+  test-iframe2.html
+  test-iframe3.html
+  test-image.png
+  test-mixedcontent-securityerrors.html
+  test-mutation.html
+  test-network-request.html
+  test-network.html
+  test-observe-http-ajax.html
+  test-own-console.html
+  test-property-provider.html
+  test-repeated-messages.html
+  test-result-format-as-string.html
+  test-webconsole-error-observer.html
+  test_bug_770099_bad_policy_uri.html
+  test_bug_770099_bad_policy_uri.html^headers^
+  test_bug_770099_violation.html
+  test_bug_770099_violation.html^headers^
+  testscript.js
+
+[browser_bug664688_sandbox_update_after_navigation.js]
+[browser_bug_638949_copy_link_location.js]
+[browser_bug_862916_console_dir_and_filter_off.js]
+[browser_bug_865288_repeat_different_objects.js]
+[browser_bug_865871_variables_view_close_on_esc_key.js]
+[browser_bug_869003_inspect_cross_domain_object.js]
+[browser_bug_871156_ctrlw_close_tab.js]
+[browser_cached_messages.js]
+[browser_console.js]
+[browser_console_addonsdk_loader_exception.js]
+[browser_console_clear_on_reload.js]
+[browser_console_consolejsm_output.js]
+[browser_console_dead_objects.js]
+[browser_console_error_source_click.js]
+[browser_console_filters.js]
+[browser_console_iframe_messages.js]
+[browser_console_keyboard_accessibility.js]
+[browser_console_log_inspectable_object.js]
+[browser_console_native_getters.js]
+[browser_console_navigation_marker.js]
+[browser_console_nsiconsolemessage.js]
+[browser_console_private_browsing.js]
+[browser_console_variables_view.js]
+[browser_console_variables_view_while_debugging.js]
+[browser_console_variables_view_while_debugging_and_inspecting.js]
+[browser_eval_in_debugger_stackframe.js]
+[browser_jsterm_inspect.js]
+[browser_longstring_hang.js]
+[browser_netpanel_longstring_expand.js]
+[browser_output_breaks_after_console_dir_uninspectable.js]
+[browser_output_longstring_expand.js]
+[browser_repeated_messages_accuracy.js]
+[browser_result_format_as_string.js]
+[browser_warn_user_about_replaced_api.js]
+[browser_webconsole_abbreviate_source_url.js]
+[browser_webconsole_allow_mixedcontent_securityerrors.js]
+[browser_webconsole_basic_net_logging.js]
+[browser_webconsole_block_mixedcontent_securityerrors.js]
+[browser_webconsole_bug_579412_input_focus.js]
+[browser_webconsole_bug_580001_closing_after_completion.js]
+[browser_webconsole_bug_580030_errors_after_page_reload.js]
+[browser_webconsole_bug_580454_timestamp_l10n.js]
+[browser_webconsole_bug_582201_duplicate_errors.js]
+[browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js]
+[browser_webconsole_bug_585237_line_limit.js]
+[browser_webconsole_bug_585956_console_trace.js]
+[browser_webconsole_bug_585991_autocomplete_keys.js]
+[browser_webconsole_bug_585991_autocomplete_popup.js]
+[browser_webconsole_bug_586388_select_all.js]
+[browser_webconsole_bug_587617_output_copy.js]
+[browser_webconsole_bug_588342_document_focus.js]
+[browser_webconsole_bug_588730_text_node_insertion.js]
+[browser_webconsole_bug_588967_input_expansion.js]
+[browser_webconsole_bug_589162_css_filter.js]
+[browser_webconsole_bug_592442_closing_brackets.js]
+[browser_webconsole_bug_593003_iframe_wrong_hud.js]
+[browser_webconsole_bug_594477_clickable_output.js]
+[browser_webconsole_bug_594497_history_arrow_keys.js]
+[browser_webconsole_bug_595223_file_uri.js]
+[browser_webconsole_bug_595350_multiple_windows_and_tabs.js]
+[browser_webconsole_bug_595934_message_categories.js]
+[browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js]
+[browser_webconsole_bug_597136_external_script_errors.js]
+[browser_webconsole_bug_597136_network_requests_from_chrome.js]
+[browser_webconsole_bug_597460_filter_scroll.js]
+[browser_webconsole_bug_597756_reopen_closed_tab.js]
+[browser_webconsole_bug_598357_jsterm_output.js]
+[browser_webconsole_bug_599725_response_headers.js]
+[browser_webconsole_bug_600183_charset.js]
+[browser_webconsole_bug_601177_log_levels.js]
+[browser_webconsole_bug_601352_scroll.js]
+[browser_webconsole_bug_601667_filter_buttons.js]
+[browser_webconsole_bug_602572_log_bodies_checkbox.js]
+[browser_webconsole_bug_603750_websocket.js]
+[browser_webconsole_bug_611795.js]
+[browser_webconsole_bug_613013_console_api_iframe.js]
+[browser_webconsole_bug_613280_jsterm_copy.js]
+[browser_webconsole_bug_613642_maintain_scroll.js]
+[browser_webconsole_bug_613642_prune_scroll.js]
+[browser_webconsole_bug_614793_jsterm_scroll.js]
+[browser_webconsole_bug_618078_network_exceptions.js]
+[browser_webconsole_bug_618311_close_panels.js]
+[browser_webconsole_bug_621644_jsterm_dollar.js]
+[browser_webconsole_bug_622303_persistent_filters.js]
+[browser_webconsole_bug_630733_response_redirect_headers.js]
+[browser_webconsole_bug_632275_getters_document_width.js]
+[browser_webconsole_bug_632347_iterators_generators.js]
+[browser_webconsole_bug_632817.js]
+[browser_webconsole_bug_642108_pruneTest.js]
+[browser_webconsole_bug_642615_autocomplete.js]
+[browser_webconsole_bug_644419_log_limits.js]
+[browser_webconsole_bug_646025_console_file_location.js]
+[browser_webconsole_bug_651501_document_body_autocomplete.js]
+[browser_webconsole_bug_653531_highlighter_console_helper.js]
+[browser_webconsole_bug_658368_time_methods.js]
+[browser_webconsole_bug_659907_console_dir.js]
+[browser_webconsole_bug_660806_history_nav.js]
+[browser_webconsole_bug_664131_console_group.js]
+[browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js]
+[browser_webconsole_bug_704295.js]
+[browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js]
+[browser_webconsole_bug_737873_mixedcontent.js]
+[browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js]
+[browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js]
+[browser_webconsole_bug_764572_output_open_url.js]
+[browser_webconsole_bug_766001_JS_Console_in_Debugger.js]
+[browser_webconsole_bug_770099_bad_policyuri.js]
+[browser_webconsole_bug_770099_violation.js]
+[browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js]
+[browser_webconsole_bug_817834_add_edited_input_to_history.js]
+[browser_webconsole_bug_821877_csp_errors.js]
+[browser_webconsole_bug_837351_securityerrors.js]
+[browser_webconsole_bug_846918_hsts_invalid-headers.js]
+[browser_webconsole_cached_autocomplete.js]
+[browser_webconsole_change_font_size.js]
+[browser_webconsole_chrome.js]
+[browser_webconsole_completion.js]
+[browser_webconsole_console_extras.js]
+[browser_webconsole_console_logging_api.js]
+[browser_webconsole_execution_scope.js]
+[browser_webconsole_for_of.js]
+[browser_webconsole_history.js]
+[browser_webconsole_js_input_expansion.js]
+[browser_webconsole_jsterm.js]
+[browser_webconsole_live_filtering_of_message_types.js]
+[browser_webconsole_live_filtering_on_search_strings.js]
+[browser_webconsole_message_node_id.js]
+[browser_webconsole_netlogging.js]
+[browser_webconsole_network_panel.js]
+[browser_webconsole_notifications.js]
+[browser_webconsole_output_copy_newlines.js]
+[browser_webconsole_output_order.js]
+[browser_webconsole_property_provider.js]
+[browser_webconsole_view_source.js]
--- a/browser/devtools/webconsole/test/moz.build
+++ b/browser/devtools/webconsole/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/extensions/pdfjs/test/Makefile.in
+++ b/browser/extensions/pdfjs/test/Makefile.in
@@ -1,10 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES = \
-  browser_pdfjs_main.js \
-  browser_pdfjs_savedialog.js \
-  browser_pdfjs_views.js \
-  file_pdfjs_test.pdf \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pdfjs/test/browser.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+support-files = file_pdfjs_test.pdf
+
+[browser_pdfjs_main.js]
+[browser_pdfjs_savedialog.js]
+[browser_pdfjs_views.js]
--- a/browser/extensions/pdfjs/test/moz.build
+++ b/browser/extensions/pdfjs/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/fuel/test/Makefile.in
+++ b/browser/fuel/test/Makefile.in
@@ -1,15 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-  browser_Application.js \
-  browser_ApplicationPrefs.js \
-  browser_ApplicationStorage.js \
-  browser_ApplicationQuitting.js \
-  browser_Bookmarks.js \
-  browser_Browser.js \
-  ContentA.html \
-  ContentB.html \
-  ContentWithFrames.html \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/fuel/test/browser.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+support-files =
+  ContentA.html
+  ContentB.html
+  ContentWithFrames.html
+
+[browser_Application.js]
+[browser_ApplicationPrefs.js]
+[browser_ApplicationQuitting.js]
+[browser_ApplicationStorage.js]
+[browser_Bookmarks.js]
+[browser_Browser.js]
--- a/browser/fuel/test/moz.build
+++ b/browser/fuel/test/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/browser/modules/test/Makefile.in
+++ b/browser/modules/test/Makefile.in
@@ -1,16 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_BROWSER_FILES := \
-  browser_NetworkPrioritizer.js \
-  $(NULL)
-
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 MOCHITEST_BROWSER_FILES += \
   browser_taskbar_preview.js \
   $(NULL)
 endif
 
 # bug 793906 - temporarily disabling desktop UI while working on b2g
 # browser_SignInToWebsite.js
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/browser.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[browser_NetworkPrioritizer.js]
--- a/browser/modules/test/chrome/Makefile.in
+++ b/browser/modules/test/chrome/Makefile.in
@@ -1,8 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_CHROME_FILES = \
-		test_sharedframe.xul \
-		sharedframe.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/chrome/chrome.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files = sharedframe.xul
+
+[test_sharedframe.xul]
--- a/browser/modules/test/chrome/moz.build
+++ b/browser/modules/test/chrome/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/browser/modules/test/moz.build
+++ b/browser/modules/test/moz.build
@@ -1,7 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['chrome', 'unit']
+
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/build/docs/Vagrantfile
+++ b/build/docs/Vagrantfile
@@ -4,10 +4,10 @@
 # We intentionally use the old config format because Mozilla's Jenkins
 # server doesn't run a modern Vagrant.
 Vagrant::Config.run do |config|
   config.vm.box = "precise64"
   config.vm.box_url = "http://files.vagrantup.com/precise64.box"
   config.vm.share_folder("gecko", "/gecko", "../..")
   # Doxygen needs more than the default memory or it will swap and be
   # extremely slow.
-  config.vm.customize ["modifyvm", :id, "--memory", 1024]
+  config.vm.customize ["modifyvm", :id, "--memory", 2048]
 end
--- a/build/docs/build-overview.rst
+++ b/build/docs/build-overview.rst
@@ -17,87 +17,96 @@ harmony to build the source tree. We beg
    digraph build_components {
       rankdir="LR";
       "configure" -> "config.status" -> "build backend" -> "build output"
    }
 
 Phase 1: Configuration
 ======================
 
-Phase 1 centers around the configure script, which is a bash shell script.
-The file is generated from a file called configure.in which is written in M4
+Phase 1 centers around the ``configure`` script, which is a bash shell script.
+The file is generated from a file called ``configure.in`` which is written in M4
 and processed using Autoconf 2.13 to create the final configure script.
-You don't have to worry about how you obtain a configure file: the build system
-does this for you.
+You don't have to worry about how you obtain a ``configure`` file: the build
+system does this for you.
 
-The primary job of configure is to determine characteristics of the system and
-compiler, apply options passed into it, and validate everything looks OK to
-build. The primary output of the configure script is an executable file in the
-object directory called config.status. configure also produces some additional
-files (like autoconf.mk). However, the most important file in terms of
-architecture is config.status.
+The primary job of ``configure`` is to determine characteristics of the system
+and compiler, apply options passed into it, and validate everything looks OK to
+build. The primary output of the ``configure`` script is an executable file
+in the object directory called ``config.status``. ``configure`` also produces
+some additional files (like ``autoconf.mk``). However, the most important file
+in terms of architecture is ``config.status``.
 
-The existence of a config.status file may be familiar to those who have worked
-with Autoconf before. However, Mozilla's config.status is different from almost
-any other config.status you've ever seen: it's written in Python! Instead of
-having our configure script produce a shell script, we have it generating Python.
+The existence of a ``config.status`` file may be familiar to those who have worked
+with Autoconf before. However, Mozilla's ``config.status`` is different from almost
+any other ``config.status`` you've ever seen: it's written in Python! Instead of
+having our ``configure`` script produce a shell script, we have it generating
+Python.
 
 Now is as good a time as any to mention that Python is prevalent in our build
 system. If we need to write code for the build system, we do it in Python.
-That's just how we roll.
+That's just how we roll. For more, see :ref:`python`.
 
-config.status contains 2 parts: data structures representing the output of
-configure and a command-line interface for preparing/configuring/generating
+``config.status`` contains 2 parts: data structures representing the output of
+``configure`` and a command-line interface for preparing/configuring/generating
 an appropriate build backend. (A build backend is merely a tool used to build
 the tree - like GNU Make or Tup). These data structures essentially describe
 the current state of the system and what the existing build configuration looks
 like. For example, it defines which compiler to use, how to invoke it, which
 application features are enabled, etc. You are encouraged to open up
-config.status to have a look for yourself!
+``config.status`` to have a look for yourself!
 
-Once we have emitted a config.status file, we pass into the realm of phase 2.
+Once we have emitted a ``config.status`` file, we pass into the realm of
+phase 2.
 
 Phase 2: Build Backend Preparation and the Build Definition
 ===========================================================
 
-Once configure has determined what the current build configuration is, we need
-to apply this to the source tree so we can actually build.
+Once ``configure`` has determined what the current build configuration is,
+we need to apply this to the source tree so we can actually build.
 
-What essentially happens is the automatically-produced config.status Python
-script is executed as soon as configure has generated it. config.status is charged
-with the task of tell a tool had to build the tree. To do this, config.status
-must first scan the build system definition.
+What essentially happens is the automatically-produced ``config.status`` Python
+script is executed as soon as ``configure`` has generated it. ``config.status``
+is charged with the task of tell a tool how to build the tree. To do this,
+``config.status`` must first scan the build system definition.
 
-The build system definition consists of various moz.build files in the tree.
-There is roughly one moz.build file per directory or pet set of related directories.
-Each moz.build files defines how its part of the build config works. For example it
-says I want these C++ files compiled or look for additional information in these
-directories. config.status starts with the main moz.build file and then recurses
-into all referenced files and directories. As the moz.build files are read, data
-structures describing the overall build system definition are emitted. These data
-structures are then read by a build backend generator which then converts them
-into files, function calls, etc. In the case of a `make` backend, the generator
-writes out Makefiles.
+The build system definition consists of various ``moz.build`` files in the tree.
+There is roughly one ``moz.build`` file per directory or per set of related directories.
+Each ``moz.build`` files defines how its part of the build config works. For
+example it says *I want these C++ files compiled* or *look for additional
+information in these directories.* config.status starts with the ``moz.build``
+file from the root directory and then descends into referenced ``moz.build``
+files by following ``DIRS`` variables or similar.
 
-When config.status runs, you'll see the following output::
+As the ``moz.build`` files are read, data structures describing the overall
+build system definition are emitted. These data structures are then fed into a
+build backend, which then performs actions, such as writing out files to
+be read by a build tool. e.g. a ``make`` backend will write a
+``Makefile``.
+
+When ``config.status`` runs, you'll see the following output::
 
    Reticulating splines...
    Finished reading 1096 moz.build files into 1276 descriptors in 2.40s
    Backend executed in 2.39s
    2188 total backend files. 0 created; 1 updated; 2187 unchanged
    Total wall time: 5.03s; CPU time: 3.79s; Efficiency: 75%
 
-What this is saying is that a total of 1096 moz.build files were read. Altogether,
-1276 data structures describing the build configuration were derived from them.
-It took 2.40s wall time to just read these files and produce the data structures.
-The 1276 data structures were fed into the build backend which then determined it
-had to manage 2188 files derived from those data structures. Most of them
-already existed and didn't need changed. However, 1 was updated as a result of
-the new configuration. The whole process took 5.03s. Although, only 3.79s was in
-CPU time. That likely means we spent roughly 25% of the time waiting on I/O.
+What this is saying is that a total of *1096* ``moz.build`` files were read.
+Altogether, *1276* data structures describing the build configuration were
+derived from them.  It took *2.40s* wall time to just read these files and
+produce the data structures.  The *1276* data structures were fed into the
+build backend which then determined it had to manage *2188* files derived
+from those data structures. Most of them already existed and didn't need
+changed. However, *1* was updated as a result of the new configuration.
+The whole process took *5.03s*. Although, only *3.79s* was in
+CPU time. That likely means we spent roughly *25%* of the time waiting on
+I/O.
+
+For more on how ``moz.build`` files work, see :ref:`mozbuild-files`.
 
 Phase 3: Invokation of the Build Backend
 ========================================
 
 When most people think of the build system, they think of phase 3. This is
 where we take all the code in the tree and produce Firefox or whatever
 application you are creating. Phase 3 effectively takes whatever was
 generated by phase 2 and runs it. Since the dawn of Mozilla, this has been
--- a/build/docs/index.rst
+++ b/build/docs/index.rst
@@ -12,33 +12,34 @@ Overview
 
 Important Concepts
 ==================
 .. toctree::
    :maxdepth: 1
 
    build-overview
    Mozconfig Files <mozconfigs>
+   mozbuild-files
    Profile Guided Optimization <pgo>
    slow
    environment-variables
    build-targets
+   python
    test_manifests
 
 mozbuild
 ========
 
 mozbuild is a Python package containing a lot of the code for the
 Mozilla build system.
 
 .. toctree::
    :maxdepth: 1
 
    mozbuild/index
-   mozbuild/frontend
    mozbuild/dumbmake
 
 
 Indices and tables
 ==================
 
 * :ref:`genindex`
 * :ref:`modindex`
new file mode 100644
--- /dev/null
+++ b/build/docs/mozbuild-files.rst
@@ -0,0 +1,116 @@
+.. _mozbuild-files:
+
+===============
+moz.build Files
+===============
+
+``moz.build`` files are the mechanism by which tree metadata (notably
+the build configuration) is defined.
+
+Directories in the tree contain ``moz.build`` files which declare
+functionality for their respective part of the tree. This includes
+things such as the list of C++ files to compile, where to find tests,
+etc.
+
+``moz.build`` files are actually Python scripts. However, their
+execution is governed by special rules. This is explained below.
+
+moz.build Python Sandbox
+========================
+
+As mentioned above, ``moz.build`` files are Python scripts. However,
+they are executed in a special Python *sandbox* that significantly
+changes and limits the execution environment. The environment is so
+different, it's doubtful most ``moz.build`` files would execute without
+error if executed by a vanilla Python interpreter (e.g. ``python
+moz.build``.
+
+The following properties make execution of ``moz.build`` files special:
+
+1. The execution environment exposes a limited subset of Python.
+2. There is a special set of global symbols and an enforced naming
+   convention of symbols.
+
+The limited subset of Python is actually an extremely limited subset.
+Only a few symbols from ``__builtins__`` are exposed. These include
+``True``, ``False``, and ``None``. Global functions like ``import``,
+``print``, and ``open`` aren't available. Without these, ``moz.build``
+files can do very little. *This is by design*.
+
+The execution sandbox treats all ``UPPERCASE`` variables specially. Any
+``UPPERCASE`` variable must be known to the sandbox before the script
+executes. Any attempt to read or write to an unknown ``UPPERCASE``
+variable will result in an exception being raised. Furthermore, the
+types of all ``UPPERCASE`` variables is strictly enforced. Attempts to
+assign an incompatible type to an ``UPPERCASE`` variable will result in
+an exception being raised.
+
+The strictness of behavior with ``UPPERCASE`` variables is a very
+intentional design decision. By ensuring strict behavior, any operation
+involving an ``UPPERCASE`` variable is guaranteed to have well-defined
+side-effects. Previously, when the build configuration was defined in
+``Makefiles``, assignments to variables that did nothing would go
+unnoticed. ``moz.build`` files fix this problem by eliminating the
+potential for false promises.
+
+In the sandbox, all ``UPPERCASE`` variables are globals and all
+non-``UPPERCASE`` variables are locals. After a ``moz.build`` file has
+completed execution, only the globals are used to retrieve state.
+
+The set of variables and functions available to the Python sandbox is
+defined by the :py:mod:`mozbuild.frontend.sandbox_symbols` module. The
+data structures in this module are consumed by the
+:py:class:`mozbuild.frontend.reader.MozbuildSandbox` class to construct
+the sandbox. There are tests to ensure that the set of symbols exposed
+to an empty sandbox are all defined in the ``sandbox_symbols`` module.
+This module also contains documentation for each symbol, so nothing can
+sneak into the sandbox without being explicitly defined and documented.
+
+Reading and Traversing moz.build Files
+======================================
+
+The process responsible for reading ``moz.build`` files simply starts at
+a root ``moz.build`` file, processes it, emits the globals namespace to
+a consumer, and then proceeds to process additional referenced
+``moz.build`` files from the original file. The consumer then examines
+the globals/``UPPERCASE`` variables set as part of execution and then
+converts the data therein to Python class instances.
+
+The executed Python sandbox is essentially represented as a dictionary
+of all the special ``UPPERCASE`` variables populated during its
+execution.
+
+The code for reading ``moz.build`` files lives in
+:py:mod:`mozbuild.frontend.reader`. The evaluated Python sandboxes are
+passed into :py:mod:`mozbuild.frontend.emitter`, which converts them to
+classes defined in :py:mod:`mozbuild.frontend.data`. Each class in this
+module define a domain-specific component of tree metdata. e.g. there
+will be separate classes that represent a JavaScript file vs a compiled
+C++ file or test manifests. This means downstream consumers of this data
+can filter on class types to only consume what they are interested in.
+
+There is no well-defined mapping between ``moz.build`` file instances
+and the number of :py:mod:`mozbuild.frontend.data` classes derived from
+each. Depending on the content of the ``moz.build`` file, there may be 1
+object derived or 100.
+
+The purpose of the ``emitter`` layer between low-level sandbox execution
+and metadata representation is to facilitate a unified normalization and
+verification step. There are multiple downstream consumers of the
+``moz.build``-derived data and many will perform the same actions. This
+logic can be complicated, so we a component dedicated to it.
+
+Other Notes
+===========
+
+:py:class:`mozbuild.frontend.reader.BuildReader`` and
+:py:class:`mozbuild.frontend.reader.TreeMetadataEmitter`` have a
+stream-based API courtesy of generators. When you hook them up properly,
+the :py:mod:`mozbuild.frontend.data` classes are emitted before all
+``moz.build`` files have been read. This means that downstream errors
+are raised soon after sandbox execution.
+
+Lots of the code for evaluating Python sandboxes is applicable to
+non-Mozilla systems. In theory, it could be extracted into a standalone
+and generic package. However, until there is a need, there will
+likely be some tightly coupled bits.
deleted file mode 100644
--- a/build/docs/mozbuild/frontend.rst
+++ /dev/null
@@ -1,137 +0,0 @@
-=================
-mozbuild.frontend
-=================
-
-The mozbuild.frontend package is of sufficient importance and complexity
-to warrant its own README file. If you are looking for documentation on
-how the build system gets started, you've come to the right place.
-
-Overview
-========
-
-Tree metadata (including the build system) is defined by a collection of
-files in the source tree called *mozbuild* files. These typically are files
-named *moz.build*. But, the actual name can vary.
-
-Each *mozbuild* file defines basic metadata about the part of the tree
-(typically directory scope) it resides in. This includes build system
-configuration, such as the list of C++ files to compile or headers to install
-or libraries to link together.
-
-*mozbuild* files are actually Python scripts. However, their execution
-is governed by special rules. This will be explained later.
-
-Once a *mozbuild* file has executed, it is converted into a set of static
-data structures.
-
-The set of all data structures from all relevant *mozbuild* files
-constitute all of the metadata from the tree.
-
-How *mozbuild* Files Work
-=========================
-
-As stated above, *mozbuild* files are actually Python scripts. However,
-their behavior is very different from what you would expect if you executed
-the file using the standard Python interpreter from the command line.
-
-There are two properties that make execution of *mozbuild* files special:
-
-1. They are evaluated in a sandbox which exposes a limited subset of Python
-2. There is a special set of global variables which hold the output from
-   execution.
-
-The limited subset of Python is actually an extremely limited subset.
-Only a few built-ins are exposed. These include *True*, *False*, and
-*None*. Global functions like *import*, *print*, and *open* aren't defined.
-Without these, *mozbuild* files can do very little. This is by design.
-
-The side-effects of the execution of a *mozbuild* file are used to define
-the build configuration. Specifically, variables set during the execution
-of a *mozbuild* file are examined and their values are used to populate
-data structures.
-
-The enforced convention is that all UPPERCASE names inside a sandbox are
-reserved and it is the value of these variables post-execution that is
-examined. Furthermore, the set of allowed UPPERCASE variable names and
-their types is statically defined. If you attempt to reference or assign
-to an UPPERCASE variable name that isn't known to the build system or
-attempt to assign a value of the wrong type (e.g. a string when it wants a
-list), an error will be raised during execution of the *mozbuild* file.
-This strictness is to ensure that assignment to all UPPERCASE variables
-actually does something. If things weren't this way, *mozbuild* files
-might think they were doing something but in reality wouldn't be. We don't
-want to create false promises, so we validate behavior strictly.
-
-If a variable is not UPPERCASE, you can do anything you want with it,
-provided it isn't a function or other built-in. In other words, normal
-Python rules apply.
-
-All of the logic for loading and evaluating *mozbuild* files is in the
-*reader* module. Of specific interest is the *MozbuildSandbox* class. The
-*BuildReader* class is also important, as it is in charge of
-instantiating *MozbuildSandbox* instances and traversing a tree of linked
-*mozbuild* files. Unless you are a core component of the build system,
-*BuildReader* is probably the only class you care about in this module.
-
-The set of variables and functions *exported* to the sandbox is defined by
-the *sandbox_symbols* module. These data structures are actually used to
-populate MozbuildSandbox instances. And, there are tests to ensure that the
-sandbox doesn't add new symbols without those symbols being added to the
-module. And, since the module contains documentation, this ensures the
-documentation is up to date (at least in terms of symbol membership).
-
-How Sandboxes are Converted into Data Structures
-================================================
-
-The output of a *mozbuild* file execution is essentially a dict of all
-the special UPPERCASE variables populated during its execution. While these
-dicts are data structures, they aren't the final data structures that
-represent the build configuration.
-
-We feed the *mozbuild* execution output (actually *reader.MozbuildSandbox*
-instances) into a *TreeMetadataEmitter* class instance. This class is
-defined in the *emitter* module. *TreeMetadataEmitter* converts the
-*MozbuildSandbox* instances into instances of the *TreeMetadata*-derived
-classes from the *data* module.
-
-All the classes in the *data* module define a domain-specific
-component of the tree metadata, including build configuration. File compilation
-and IDL generation are separate classes, for example. The only thing these
-classes have in common is that they inherit from *TreeMetadata*, which is
-merely an abstract base class.
-
-The set of all emitted *TreeMetadata* instances (converted from executed
-*mozbuild* files) constitutes the aggregate tree metadata. This is the
-the authoritative definition of the build system, etc and is what's used by
-all downstream consumers, such as build backends. There is no monolithic
-class or data structure. Instead, the tree metadata is modeled as a collection
-of *TreeMetadata* instances.
-
-There is no defined mapping between the number of
-*MozbuildSandbox*/*moz.build* instances and *TreeMetadata* instances.
-Some *mozbuild* files will emit only 1 *TreeMetadata* instance. Some
-will emit 7. Some may even emit 0!
-
-The purpose of this *emitter* layer between the raw *mozbuild* execution
-result and *TreeMetadata* is to facilitate additional normalization and
-verification of the output. There are multiple downstream consumers of
-this data and there is common functionality shared between them. An
-abstraction layer that provides high-level filtering is a useful feature.
-Thus *TreeMetadataEmitter* exists.
-
-Other Notes
-===========
-
-*reader.BuildReader* and *emitter.TreeMetadataEmitter* have a nice
-stream-based API courtesy of generators. When you hook them up properly,
-*TreeMetadata* instances can be consumed before all *mozbuild* files have
-been read. This means that errors down the pipe can trigger before all
-upstream tasks (such as executing and converting) are complete. This should
-reduce the turnaround time in the event of errors. This likely translates to
-a more rapid pace for implementing backends, which require lots of iterative
-runs through the entire system.
-
-Lots of code in this sub-module is applicable to other systems, not just
-Mozilla's. However, some of the code is tightly coupled. If there is a will
-to extract the generic bits for re-use in other projects, that can and should
-be done.
new file mode 100644
--- /dev/null
+++ b/build/docs/python.rst
@@ -0,0 +1,163 @@
+.. _python:
+
+===========================
+Python and the Build System
+===========================
+
+The Python programming language is used significantly in the build
+system. If we need to write code for the build system or for a tool
+related to the build system, Python is typically the first choice.
+
+Python Requirements
+===================
+
+The tree requires Python 2.7.3 or greater but not Python 3 to build.
+All Python packages not in the Python distribution are included in the
+source tree. So all you should need is a vanilla Python install and you
+should be good to go.
+
+Only CPython (the Python distribution available from www.python.org) is
+supported.
+
+We require Python 2.7.3 (and not say 2.7.2) to build because Python
+2.7.3 contains numerous bug fixes, especially around the area of Unicode
+handling. These bug fixes are extremely annoying and have to be worked
+around. The build maintainers were tired of doing this, so the minimum
+version requirement was upped (bug 870420).
+
+We intend to eventually support Python 3. This will come by way of dual
+2.7/3.x compatibility because a single flag day conversion to 3.x will
+be too cumbersome given the amount of Python that would need converted.
+We will not know which 3.x minor release we are targeting until this
+effort is underway. This is tracked in bug 636155.
+
+Compiled Python Packages
+========================
+
+There are some features of the build that rely on compiled Python packages
+(packages containing C source). These features are currently all
+optional because not every system contains the Python development
+headers required to build these extensions.
+
+We recommend you have the Python development headers installed (``mach
+bootstrap`` should do this for you) so you can take advantage of these
+features.
+
+Issues with OS X System Python
+==============================
+
+The Python that ships with OS X has historically been littered with
+subtle bugs and suboptimalities. Furthermore, OS X up through 10.8 don't
+ship with Python 2.7.3 (10.8 ships with 2.7.2).
+
+OS X 10.8 and below users will be required to install a new Python
+distribution. This may not be necessary for OS X 10.9+. However, we
+still recommend installing a separate Python because of the history with
+OS X's system Python issues.
+
+We recommend installing Python through Homebrew or MacPorts. If you run
+``mach bootstrap``, this should be done for you.
+
+Virtualenvs
+===========
+
+The build system relies heavily on
+`virtualenvs <http://www.virtualenv.org/en/latest/>`_. Virtualenvs are
+standalone and isolated Python environments. The problem a virtualenv
+solves is that of dependencies across multiple Python components. If two
+components on a system relied on different versions of a package, there
+could be a conflict. Instead of managing multiple versions of a package
+simultaneously, Python and virtualenvs take the route that it is easier
+to just keep them separate so there is no potential for conflicts.
+
+Very early in the build process, a virtualenv is created inside the
+:term:`object directory`. The virtualenv is configured such that it can
+find all the Python packages in the source tree. The code for this lives
+in :py:mod:`mozbuild.virtualenv`.
+
+Deficiencies
+------------
+
+There are numerous deficiencies with the way virtualenvs are handled in
+the build system.
+
+* mach reinvents the virtualenv.
+
+  There is code in ``build/mach_bootstrap.py`` that configures ``sys.path``
+  much the same way the virtualenv does. There are various bugs tracking
+  this. However, no clear solution has yet been devised. It's not a huge
+  problem and thus not a huge priority.
+
+* They aren't preserved across copies and packaging.
+
+  If you attempt to copy an entire tree from one machine to another or
+  from one directory to another, chances are the virtualenv will fall
+  apart. It would be nice if we could preserve it somehow. Instead of
+  actually solving portable virtualenvs, all we really need to solve is
+  encapsulating the logic for populating the virtualenv along with all
+  dependent files in the appropriate place.
+
+* .pyc files written to source directory.
+
+  We rely heavily on ``.pth`` files in our virtualenv. A ``.pth`` file
+  is a special file that contains a list of paths. Python will take the
+  set of listed paths encountered in ``.pth`` files and add them to
+  ``sys.path``.
+
+  When Python compiles a ``.py`` file to bytecode, it writes out a
+  ``.pyc`` file so it doesn't have to perform this compilation again.
+  It puts these ``.pyc`` files alongside the ``.pyc`` file. Python
+  provides very little control for determing where these ``.pyc`` files
+  go, even in Python 3 (which offers customer importers).
+
+  With ``.pth`` files pointing back to directories in the source tree
+  and not the object directory, ``.pyc`` files are created in the source
+  tree. This is bad because when Python imports a module, it first looks
+  for a ``.pyc`` file before the ``.py`` file. If there is a ``.pyc``
+  file but no ``.py`` file, it will happily import the module. This
+  wreaks havoc during file moves, refactoring, etc.
+
+  There are various proposals for fixing this. See bug 795995.
+
+Common Issues with Python
+=========================
+
+Upgrading your Python distribution breaks the virtualenv
+--------------------------------------------------------
+
+If you upgrade the Python distribution (e.g. install Python 2.7.5
+from 2.7.3, chances are parts of the virtualenv will break.
+This commonly manifests as a cryptic ``Cannot import XXX`` exception.
+More often than not, the module being imported contains binary/compiled
+components.
+
+If you upgrade or reinstall your Python distribution, we recommend
+clobbering your build.
+
+Packages installed at the system level conflict with build system's
+-------------------------------------------------------------------
+
+It is common for people to install Python packages using ``sudo`` (e.g.
+``sudo pip install psutil``) or with the system's package manager
+(e.g. ``apt-get install python-mysql``.
+
+A problem with this is that packages installed at the system level may
+conflict with the package provided by the source tree. As of bug 907902
+and changeset f18eae7c3b27 (September 16, 2013), this should no longer
+be an issue since the virtualenv created as part of the build doesn't
+add the system's ``site-packages`` directory to ``sys.path``. However,
+poorly installed packages may still find a way to creep into the mix and
+interfere with our virtualenv.
+
+As a general principle, we recommend against using your system's package
+manager or using ``sudo`` to install Python packages. Instead, create
+virtualenvs and isolated Python environments for all of your Python
+projects.
+
+Python on $PATH is not appropriate
+----------------------------------
+
+Tools like ``mach`` will look for Python by performing ``/usr/bin/env
+python`` or equivalent. Please be sure the appropriate Python 2.7.3+
+path is on $PATH. On OS X, this likely means you'll need to modify your
+shell's init script to put something ahead of ``/usr/bin``.
--- a/caps/tests/mochitest/Makefile.in
+++ b/caps/tests/mochitest/Makefile.in
@@ -1,18 +1,10 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = 	test_bug423375.html \
-                test_bug246699.html \
-                test_bug292789.html \
-                test_bug470804.html \
-                test_disallowInheritPrincipal.html \
-                test_app_principal_equality.html \
-                $(NULL)
-
 # jarPrefix test doesn't work on Windows, see bug 776296.
 ifneq ($(OS_ARCH),WINNT)
 MOCHITEST_CHROME_FILES = test_principal_jarprefix_origin_appid_appstatus.html \
                          $(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/caps/tests/mochitest/mochitest.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+
+[test_app_principal_equality.html]
+[test_bug246699.html]
+[test_bug292789.html]
+[test_bug423375.html]
+[test_bug470804.html]
+[test_disallowInheritPrincipal.html]
--- a/caps/tests/mochitest/moz.build
+++ b/caps/tests/mochitest/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -1,613 +1,30 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-		responseIdentical.sjs \
-		test_bug5141.html \
-		test_bug51034.html \
-		test_bug166235.html \
-		test_bug199959.html \
-		test_bug218236.html \
-		test_bug218277.html \
-		test_bug238409.html \
-		test_bug254337.html \
-		test_bug276037-1.html \
-		test_bug276037-2.xhtml \
-		test_bug298064.html \
-		bug298064-subframe.html \
-		test_xhr_forbidden_headers.html \
-		test_bug311681.xml \
-		test_bug320799.html \
-		test_bug322317.html \
-		test_bug330925.xhtml \
-		test_bug331959.html \
-		test_bug333673.html \
-		test_bug337631.html \
-		test_bug338541.xhtml \
-		test_bug338679.html \
-		test_bug339494.html \
-		test_bug339494.xhtml \
-		test_bug340571.html \
-		test_bug343596.html \
-		test_bug345339.html \
-		345339_iframe.html \
-		test_bug352728.html \
-		test_bug352728.xhtml \
-		test_bug353334.html \
-		test_bug355026.html \
-		test_bug357450.js \
-		test_bug357450.html \
-		test_bug357450.xhtml \
-		test_bug357450_svg.xhtml \
-		test_bug357509.html \
-		test_bug358660.html \
-		test_bug362391.xhtml \
-		test_bug364092.xhtml \
-		test_bug364413.xhtml \
-		test_bug366946.html \
-		test_bug367164.html \
-		test_bug371576-2.html \
-		test_bug371576-3.html \
-		test_bug371576-4.html \
-		test_bug371576-5.html \
-		test_bug372086.html \
-		test_bug372964.html \
-		test_bug372964-2.html \
-		test_bug373181.xhtml \
-		test_bug375314.html \
-		test_bug378969.html \
-		test_bug382113.html \
-		test_bug382871.html \
-		test_bug384003.xhtml \
-		test_bug390219.html \
-		test_bug390735.html \
-		test_bug392318.html \
-		test_bug392511.html \
-		test_bug393968.html \
-		test_bug395915.html \
-		test_bug397234.html \
-		test_bug398243.html \
-		test_bug419132.html \
-		bug419132.html \
-		formReset.html \
-		bug382113_object.html \
-		test_bug326337.html \
-		file_bug326337_inner.html \
-		file_bug326337_outer.html \
-		file_bug326337.xml \
-		test_bug333198.html \
-		test_bug402150.html \
-		test_bug402150.html^headers^ \
-		test_bug401662.html \
-		test_bug403852.html \
-		test_fileapi.html \
-		test_fileapi_slice.html \
-		test_bug403868.xml \
-		test_bug405182.html \
-		test_bug403841.html \
-		test_bug409380.html \
-		test_bug410229.html \
-		test_bug413974.html \
-		test_bug415860.html \
-		test_bug414190.html \
-		test_bug527896.html \
-		test_bug416317-1.html \
-		test_bug416317-2.html \
-		test_XHRSendData.html \
-		file_XHRSendData.sjs \
-		file_XHRSendData_doc.xml \
-		file_XHRSendData_doc.xml^headers^ \
-		file_bug416317.xhtml \
-		test_bug416383.html \
-		test_bug417255.html \
-		test_bug417384.html \
-		test_bug418214.html \
-		test_bug419527.xhtml \
-		test_bug420609.xhtml \
-		test_bug420700.html \
-		test_bug421602.html \
-		test_bug422537.html \
-		test_bug424359-1.html \
-		test_bug499656.html \
-		test_bug499656.xhtml \
-		file_htmlserializer_1.html \
-		file_htmlserializer_1_bodyonly.html \
-		file_htmlserializer_1_format.html \
-		file_htmlserializer_1_linebreak.html \
-		file_htmlserializer_1_links.html \
-		file_htmlserializer_1_noflag.html \
-		file_htmlserializer_1_noformatpre.html \
-		file_htmlserializer_1_raw.html \
-		file_htmlserializer_1_nested_body.html \
-		file_htmlserializer_1_sibling_body.html \
-		file_htmlserializer_1_sibling_body_only_body.html \
-		file_htmlserializer_1_no_body.html \
-		file_htmlserializer_1_wrap.html \
-		test_bug424359-2.html \
-		file_htmlserializer_2.html \
-		test_bug431082.html \
-		file_htmlserializer_2_basic.html \
-		file_htmlserializer_2_enthtml.html \
-		file_htmlserializer_2_entw3c.html \
-		file_htmlserializer_2_latin1.html \
-		test_bug424212.html \
-		test_bug425013.html \
-		bug426308-redirect.sjs \
-		test_bug426308.html \
-		test_bug426646.html \
-		file_bug426646-1.html \
-		file_bug426646-2.html \
-		test_bug429157.html \
-		test_XHR.html \
-		file_XHR_pass1.xml \
-		file_XHR_pass2.txt \
-		file_XHR_pass3.txt \
-		file_XHR_pass3.txt^headers^ \
-		file_XHR_fail1.txt \
-		file_XHR_fail1.txt^headers^ \
-		file_XHR_binary1.bin \
-		file_XHR_binary1.bin^headers^ \
-		file_XHR_binary2.bin \
-		file_XHR_header.sjs \
-		test_XHR_header.html \
-		test_bug428847.html \
-		file_bug428847-1.xhtml \
-		file_bug428847-2.xhtml \
-		test_bug431701.html \
-		test_bug431833.html \
-		test_bug435425.html \
-		bug435425.sjs \
-		bug435425_redirect.sjs \
-		test_bug438519.html \
-		test_bug444722.html \
-		test_bug451376.html \
-		test_text_wholeText.html \
-		test_bug433533.html \
-		wholeTexty-helper.xml \
-		test_bug444030.xhtml \
-		test_NodeIterator_basics_filters.xhtml \
-		test_NodeIterator_mutations_1.xhtml \
-		test_NodeIterator_mutations_2.html \
-		test_NodeIterator_mutations_3.html \
-		test_bug28293.html \
-		test_bug28293.xhtml \
-		file_bug28293.sjs \
-		test_title.html \
-		test_bug453521.html \
-		test_bug454325.html \
-		test_bug456262.html \
-		test_bug482935.html \
-		     bug482935.sjs \
-		test_bug590870.html \
-		file_bug590870.html \
-		test_bug590812.html \
-		file_bug590812.xml \
-		file_bug590812-ref.xhtml \
-		test_bug368972.html \
-		test_bug448993.html \
-		test_bug450160.html \
-		test_bug453736.html \
-		test_bug454326.html \
-		test_bug505783.html \
-		test_bug457746.html \
-		test_bug587931.html \
-		test_bug592829.html \
-		test_bug518104.html \
-		test_bug682463.html \
-		bug457746.sjs \
-		test_CrossSiteXHR.html \
-		test_CrossSiteXHR_origin.html \
-		file_CrossSiteXHR_inner.html \
-		file_CrossSiteXHR_inner_data.sjs \
-		file_CrossSiteXHR_inner.jar \
-		file_CrossSiteXHR_server.sjs \
-		test_CrossSiteXHR_cache.html \
-		file_CrossSiteXHR_cache_server.sjs \
-		test_XHRDocURI.html \
-		file_XHRDocURI.xml \
-		file_XHRDocURI.xml^headers^ \
-		file_XHRDocURI.text \
-		file_XHRDocURI.text^headers^ \
-		test_DOMException.html \
-		test_domparsing.html \
-		test_meta_viewport0.html \
-		test_meta_viewport1.html \
-		test_meta_viewport2.html \
-		test_meta_viewport3.html \
-		test_meta_viewport4.html \
-		test_meta_viewport5.html \
-		test_meta_viewport6.html \
-			viewport_helpers.js \
-		test_mutationobservers.html \
-		mutationobserver_dialog.html \
-		test_bug744830.html \
-		file_bug782342.txt \
-		test_bug782342.html \
-		test_bug282547.html \
-		bug282547.sjs \
-		test_domparser_null_char.html \
-		test_bug811701.html \
-		test_bug811701.xhtml \
-		test_bug820909.html \
-		test_bug704063.html \
-		test_bug894874.html \
-		test_bug895974.html \
-		test_bug895239.html \
-		test_bug459424.html \
-		bug461735-redirect1.sjs \
-		bug461735-redirect2.sjs \
-		bug461735-post-redirect.js \
-		test_bug513194.html \
-		test_bug461735.html \
-		test_bug380418.html \
-		test_bug469304.html \
-		test_bug465767.html \
-		test_bug380418.html^headers^ \
-		test_bug422403-1.html \
-		file_xhtmlserializer_1.xhtml \
-		file_xhtmlserializer_1_bodyonly.xhtml \
-		file_xhtmlserializer_1_format.xhtml \
-		file_xhtmlserializer_1_linebreak.xhtml \
-		file_xhtmlserializer_1_links.xhtml \
-		file_xhtmlserializer_1_noflag.xhtml \
-		file_xhtmlserializer_1_noformatpre.xhtml \
-		file_xhtmlserializer_1_raw.xhtml \
-		file_xhtmlserializer_1_nested_body.xhtml \
-		file_xhtmlserializer_1_sibling_body.xhtml \
-		file_xhtmlserializer_1_sibling_body_only_body.xhtml \
-		file_xhtmlserializer_1_no_body.xhtml \
-		file_xhtmlserializer_1_wrap.xhtml \
-		test_bug422403-2.xhtml \
-		file_xhtmlserializer_2.xhtml \
-		file_xhtmlserializer_2_basic.xhtml \
-		file_xhtmlserializer_2_enthtml.xhtml \
-		file_xhtmlserializer_2_entw3c.xhtml \
-		file_xhtmlserializer_2_latin1.xhtml \
-		test_bug500937.html \
-		test_htmlcopyencoder.html \
-		test_bug313646.html \
-		bug313646.txt \
-		test_htmlcopyencoder.xhtml \
-		test_bug270145.xhtml \
-		test_elementTraversal.html \
-		test_w3element_traversal.html \
-		test_w3element_traversal.xhtml \
-		test_bug469020.html \
-		test_w3element_traversal_svg.html \
-		w3element_traversal.svg \
-		test_bug444322.html \
-		bug444322.txt \
-		bug444322.js \
-		test_bug455472.html \
-		test_bug455629.html \
-		bug455629-helper.svg \
-		test_bug473162-1.html \
-		test_bug473162-2.html \
-		test_bug466751.xhtml \
-		test_bug461555.html \
-		test_sync_xhr_timer.xhtml \
-		test_bug498240.html \
-		file_htmlserializer_ipv6.html \
-		file_htmlserializer_ipv6_out.html \
-		test_bug498433.html \
-		test_bug498897.html \
-		file_bug498897.html \
-		file_bug498897.html^headers^ \
-		file_bug498897.css \
-		test_bug493881.js \
-		test_bug493881.html \
-		bug466409-page.html \
-		bug466409-empty.css \
-		test_bug466409.html \
-		test_classList.html \
-		test_bug514487.html \
-		test_range_bounds.html \
-		test_mozfiledataurl.html \
-		file_mozfiledataurl_audio.ogg \
-		file_mozfiledataurl_img.jpg \
-		file_mozfiledataurl_inner.html \
-		file_mozfiledataurl_doc.html \
-		file_mozfiledataurl_text.txt \
-		test_bug475156.html \
-		bug475156.sjs \
-		test_bug544642.html \
-		test_bug564863.xhtml \
-		test_bug588990.html \
-		test_copypaste.html \
-		test_copypaste.xhtml \
-		copypaste.js \
-		test_bug503481.html \
-		file_bug503481.sjs \
-		test_bug503481b.html \
-		file_bug503481b_inner.html \
-		test_viewport_scroll.html \
-		test_bug540854.html \
-		bug540854.sjs \
-		test_bug548463.html \
-		test_bug545644.html \
-		test_bug545644.xhtml \
-		test_bug553896.xhtml \
-		test_bug515401.html \
-		test_bug541937.html \
-		file_bug541937.html \
-		file_bug541937.xhtml \
-		test_bug558726.html \
-		test_bug557892.html \
-		file_bug557892.html \
-		test_bug559526.html \
-		test_bug346485.html \
-		test_bug560780.html \
-		test_bug562652.html \
-		test_bug562137.html \
-		file_bug562137.txt \
-		test_bug562169-1.html \
-		test_bug562169-2.html \
-		test_bug548193.html \
-		file_bug548193.sjs \
-		test_html_colors_quirks.html \
-		test_html_colors_standards.html \
-		test_bug300992.html \
-		test_websocket_hello.html \
-		file_websocket_hello_wsh.py \
-		test_websocket_basic.html \
-		file_websocket_basic_wsh.py \
-		test_websocket.html \
-		file_websocket_wsh.py \
-		file_websocket_http_resource.txt \
-		test_x-frame-options.html \
-		file_x-frame-options_main.html \
-		file_x-frame-options_page.sjs \
-		test_createHTMLDocument.html \
-		test_bug622088.html \
-		file_bug622088_inner.html \
-		file_bug622088.sjs \
-		test_bug564047.html \
-		test_bug567350.html \
-		test_bug578096.html \
-		test_bug585978.html \
-		test_bug592366.html \
-		test_bug597345.html \
-		script-1_bug597345.sjs \
-		script-2_bug597345.js \
-		test_bug599588.html \
-		test_bug601803.html \
-		file_bug601803a.html \
-		file_bug601803b.html \
-		test_bug602838.html \
-		script_bug602838.sjs \
-		test_bug614583.html \
-		test_bug604660.html \
-		file_bug604660-1.xml \
-		file_bug604660-2.xsl \
-		file_bug604660-3.js \
-		file_bug604660-4.js \
-		file_bug604660-5.xml \
-		file_bug604660-6.xsl \
-		test_bug605982.html \
-		test_bug606729.html \
-		test_treewalker_nextsibling.xml \
-		test_bug614058.html \
-		test_bug622117.html \
-		test_base.xhtml \
-		file_base_xbl.xml \
-		test_bug622246.html \
-		test_bug484396.html \
-		test_bug466080.html \
-		bug466080.sjs \
-		test_bug625722.html \
-		test_bug631615.html \
-		test_bug558431.html \
-		file_bug558431.html \
-		file_bug558431.html^headers^ \
-		test_bug604592.html \
-		test_bug628938.html \
-		test_bug626262.html \
-		test_plugin_freezing.html \
-		test_bug638112.html \
-		bug638112-response.txt \
-		bug638112.sjs \
-		test_bug656283.html \
-		test_blobconstructor.html \
-		fileutils.js \
-		test_bug338583.html \
-		test_EventSource_redirects.html \
-		eventsource.resource \
-		eventsource.resource^headers^ \
-		eventsource_redirect.resource \
-		eventsource_redirect.resource^headers^ \
-		eventsource_redirect_to.resource \
-		eventsource_redirect_to.resource^headers^ \
-		badContentType.eventsource \
-		badContentType.eventsource^headers^ \
-		badHTTPResponseCode.eventsource \
-		badHTTPResponseCode.eventsource^headers^ \
-		badMessageEvent.eventsource \
-		badMessageEvent.eventsource^headers^ \
-		file_restrictedEventSource.sjs \
-		forRemoval.resource \
-		forRemoval.resource^headers^ \
-		accesscontrol.resource \
-		accesscontrol.resource^headers^ \
-		invalid_accesscontrol.resource \
-		invalid_accesscontrol.resource^headers^ \
-		file_bug869432.eventsource \
-		file_bug869432.eventsource^headers^ \
-		test_xhr_progressevents.html \
-		progressserver.sjs \
-		somedatas.resource \
-		somedatas.resource^headers^ \
-		delayedServerEvents.sjs \
-		test_html_in_xhr.html \
-		file_html_in_xhr.html \
-		file_html_in_xhr2.html \
-		file_html_in_xhr3.html \
-		file_html_in_xhr.sjs \
-		test_bug647518.html \
-		test_caretPositionFromPoint.html \
-		Ahem.ttf \
-		test_bug664916.html \
-		test_bug666604.html \
-		test_bug675121.html \
-		file_bug675121.sjs \
-		test_bug675166.html \
-		test_bug682554.html \
-		test_bug682592.html \
-		bug682592-subframe.html \
-		bug682592-subframe-ref.html \
-		test_bug684671.html \
-		test_bug685798.html \
-		test_bug686449.xhtml \
-		test_bug690056.html \
-		test_bug692434.html \
-		file_bug692434.xml \
-		test_bug693615.html \
-		test_bug693875.html \
-		test_bug694754.xhtml \
-		test_bug698384.html \
-		test_nodelist_holes.html \
-		test_xhr_abort_after_load.html \
-		test_bug702439.html \
-		test_bug702439.html^headers^ \
-		file_bug702439.html \
-		test_bug707142.html \
-		file_bug707142_baseline.json \
-		file_bug707142_bom.json \
-		file_bug707142_utf-16.json \
-		test_reentrant_flush.html \
-		test_bug708620.html \
-		file_bug708620.html \
-		file_bug708620-2.html \
-		test_XHR_timeout.html \
-		test_XHR_timeout.js \
-		file_XHR_timeout.sjs \
-		test_bug717511.html \
-		file_bug717511.html \
-		file_bug717511.html^headers^ \
-		file_bug717511_2.html \
-		file_bug717511_2.html^headers^ \
-		test_bug726364.html \
-		test_bug698381.html \
-		test_bug711047.html \
-		test_bug696301-1.html \
-		test_bug696301-2.html \
-		bug696301-script-1.js \
-		bug696301-script-1.js^headers^ \
-		bug696301-script-2.js \
-		test_bug737565.html \
-		test_bug737612.html \
-		test_bug738108.html \
-		test_bug366944.html \
-		test_bug650386_redirect_301.html \
-		test_bug650386_redirect_302.html \
-		test_bug650386_redirect_303.html \
-		test_bug650386_redirect_307.html \
-		file_bug650386_content.sjs \
-		file_bug650386_report.sjs \
-		test_bug687859.html \
-		file_bug687859-bom.js \
-		file_bug687859-bom.js^headers^ \
-		file_bug687859-16.js \
-		file_bug687859-16.js^headers^ \
-		file_bug687859-http.js \
-		file_bug687859-http.js^headers^ \
-		file_bug687859-charset.js \
-		file_bug687859-inherit.js \
-		test_bug719533.html \
-		test_bug737087.html \
-		test_bug433662.html \
-		test_bug749367.html \
-		test_bug753278.html \
-		test_bug761120.html \
-		test_bug787778.html \
-		file_bug787778.sjs \
-		test_xbl_userdata.xhtml \
-		test_XHR_onuploadprogress.html \
-		test_XHR_anon.html \
-		file_XHR_anon.sjs \
-		file_XHR_system_redirect.html \
-		file_XHR_system_redirect.html^headers^ \
-		test_XHR_system.html \
-		test_XHR_parameters.html \
-		test_ipc_messagemanager_blob.html \
-		test_mixed_content_blocker.html \
-		file_mixed_content_main.html \
-		file_mixed_content_server.sjs \
-		test_mixed_content_blocker_bug803225.html \
-		file_mixed_content_main_bug803225.html \
-		file_mixed_content_main_bug803225_websocket_wsh.py \
-		bug803225_test_mailto.html \
-		test_mixed_content_blocker_frameNavigation.html \
-		file_mixed_content_frameNavigation.html \
-		file_mixed_content_frameNavigation_innermost.html \
-		file_mixed_content_frameNavigation_grandchild.html \
-		file_mixed_content_frameNavigation_secure.html \
-		file_mixed_content_frameNavigation_secure_grandchild.html \
-		file_mixed_content_frameNavigation_blankTarget.html \
-		file_bug902350.html \
-		file_bug902350_frame.html \
-		test_bug789856.html \
-		file_bug804395.jar \
-		test_bug804395.html \
-		test_bug809003.html \
-		test_bug810494.html \
-		test_bug819051.html \
-		bug819051.sjs \
-		test_textnode_split_in_selection.html \
-		test_textnode_normalize_in_selection.html \
-		test_xhr_send_readystate.html \
-		test_bug813919.html \
-		test_bug814576.html \
-		test_xhr_withCredentials.html \
-		badMessageEvent2.eventsource \
-		badMessageEvent2.eventsource^headers^ \
-		test_object.html \
-		test_bug869006.html \
-		test_bug868999.html \
-		test_bug869000.html \
-		test_bug869002.html \
-		test_bug876282.html \
-		test_bug890580.html \
-		test_declare_stylesheet_obsolete.html \
-		variable_style_sheet.sjs \
-		test_processing_instruction_update_stylesheet.xhtml \
-		test_bug907892.html \
-		file_bug907892.html \
-		test_bug902847.html \
-		$(NULL)
-
 # OOP tests don't work on Windows (bug 763081) or native-fennec
 # (see Bug 774939). App permission checks are also disabled on
 # anything but B2G (Bug 900707).
 ifdef MOZ_CHILD_PERMISSIONS
 MOCHITEST_FILES += \
 		test_messagemanager_assertpermission.html \
 		test_child_process_shutdown_message.html \
 		$(NULL)
 endif
 
-MOCHITEST_CHROME_FILES =	\
-		test_bug357450.js \
-		test_copypaste.xul \
-		$(NULL)
-
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 gtk3 windows,$(MOZ_WIDGET_TOOLKIT)))
 MOCHITEST_FILES += \
 		test_copyimage.html \
 		$(NULL)
 endif
 
 # Disabled for now. Mochitest isn't reliable enough for these.
 # test_bug444546.html \
 # bug444546.sjs \
 
 # Disabled due to making the harness time out
 #		test_bug503473.html \
 #		file_bug503473-frame.sjs \
 
-MOCHITEST_BROWSER_FILES = \
-		browser_bug593387.js \
-		browser_bug902350.js \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/base/test/browser.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[browser_bug593387.js]
+[browser_bug902350.js]
new file mode 100644
--- /dev/null
+++ b/content/base/test/chrome.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_bug357450.js]
+[test_copypaste.xul]
--- a/content/base/test/chrome/Makefile.in
+++ b/content/base/test/chrome/Makefile.in
@@ -4,64 +4,15 @@
 
 MOCHITEST_FILES = \
     bug421622-referer.sjs \
     nochrome_bug765993.html \
     nochrome_bug765993.js \
     nochrome_bug765993.js^headers^ \
     $(NULL)
 
-MOCHITEST_CHROME_FILES = \
-    test_bug206691.xul \
-    test_bug380418.html \
-    test_bug380418.html^headers^ \
-    test_bug383430.html \
-    test_bug391728.html \
-    blockPluginHard.xml \
-    blockNoPlugins.xml \
-    file_bug391728.html \
-    file_bug391728_2.html \
-    test_bug421622.xul \
-    test_bug429785.xul \
-    test_bug430050.xul \
-    test_bug467123.xul \
-    test_title.xul \
-    title_window.xul \
-    test_bug549682.xul \
-    file_bug549682.xul \
-    test_bug616841.xul \
-    file_bug616841.xul \
-    test_bug635835.xul \
-    test_fileconstructor.xul \
-    fileconstructor_file.png \
-    test_bug339494.xul \
-    test_bug357450.xul \
-    test_bug571390.xul \
-    test_bug574596.html \
-    test_bug683852.xul \
-    test_bug599295.html \
-    test_bug650776.html \
-    test_bug650784.html \
-    test_bug750096.html \
-    test_bug752226-3.xul \
-    test_bug752226-4.xul \
-    test_bug682305.html \
-    test_bug780199.xul \
-    test_bug780529.xul \
-    test_bug800386.xul \
-    test_bug816340.xul \
-    file_bug816340.xul \
-    test_domparsing.xul \
-    test_bug814638.xul \
-    host_bug814638.xul \
-    test_document_register.xul \
-    frame_bug814638.xul \
-    test_bug914381.html \
-    test_bug765993.html \
-    $(NULL)
-
 ifneq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 MOCHITEST_CHROME_FILES += \
     test_cpows.xul \
     cpows_parent.xul \
     cpows_child.js \
     $(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/content/base/test/chrome/chrome.ini
@@ -0,0 +1,49 @@
+[DEFAULT]
+support-files =
+  blockNoPlugins.xml
+  blockPluginHard.xml
+  file_bug391728.html
+  file_bug391728_2.html
+  file_bug549682.xul
+  file_bug616841.xul
+  file_bug816340.xul
+  fileconstructor_file.png
+  frame_bug814638.xul
+  host_bug814638.xul
+  title_window.xul
+
+[test_bug206691.xul]
+[test_bug339494.xul]
+[test_bug357450.xul]
+[test_bug380418.html]
+[test_bug380418.html^headers^]
+[test_bug383430.html]
+[test_bug391728.html]
+[test_bug421622.xul]
+[test_bug429785.xul]
+[test_bug430050.xul]
+[test_bug467123.xul]
+[test_bug549682.xul]
+[test_bug571390.xul]
+[test_bug574596.html]
+[test_bug599295.html]
+[test_bug616841.xul]
+[test_bug635835.xul]
+[test_bug650776.html]
+[test_bug650784.html]
+[test_bug682305.html]
+[test_bug683852.xul]
+[test_bug750096.html]
+[test_bug752226-3.xul]
+[test_bug752226-4.xul]
+[test_bug765993.html]
+[test_bug780199.xul]
+[test_bug780529.xul]
+[test_bug800386.xul]
+[test_bug814638.xul]
+[test_bug816340.xul]
+[test_bug914381.html]
+[test_document_register.xul]
+[test_domparsing.xul]
+[test_fileconstructor.xul]
+[test_title.xul]
--- a/content/base/test/chrome/moz.build
+++ b/content/base/test/chrome/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/content/base/test/csp/Makefile.in
+++ b/content/base/test/csp/Makefile.in
@@ -5,106 +5,9 @@
 DEPTH := @DEPTH@
 topsrcdir := @top_srcdir@
 srcdir := @srcdir@
 VPATH := @srcdir@
 relativesrcdir := @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MOCHITEST_FILES := \
-  test_CSP.html \
-  file_CSP.sjs \
-  file_CSP.css \
-  file_CSP_main.html \
-  file_CSP_main.html^headers^ \
-  file_CSP_main_spec_compliant.html \
-  file_CSP_main_spec_compliant.html^headers^ \
-  file_CSP_main.js \
-  file_CSP_main_spec_compliant.js \
-  test_CSP_frameancestors.html \
-  file_CSP_frameancestors.sjs \
-  file_CSP_frameancestors_main.html \
-  file_CSP_frameancestors_main.js \
-  file_CSP_frameancestors_spec_compliant.sjs \
-  file_CSP_frameancestors_main_spec_compliant.html \
-  file_CSP_frameancestors_main_spec_compliant.js \
-  test_CSP_inlinescript.html \
-  file_CSP_inlinescript_main.html \
-  file_CSP_inlinescript_main.html^headers^ \
-  file_CSP_inlinescript_main_spec_compliant.html \
-  file_CSP_inlinescript_main_spec_compliant.html^headers^ \
-  file_CSP_inlinescript_main_spec_compliant_allowed.html \
-  file_CSP_inlinescript_main_spec_compliant_allowed.html^headers^ \
-  test_CSP_evalscript.html \
-  file_CSP_evalscript_main.html \
-  file_CSP_evalscript_main.html^headers^ \
-  file_CSP_evalscript_main.js \
-  file_CSP_evalscript_main_allowed.js \
-  file_CSP_evalscript_main_spec_compliant.html \
-  file_CSP_evalscript_main_spec_compliant.html^headers^ \
-  file_CSP_evalscript_main_spec_compliant_allowed.html \
-  file_CSP_evalscript_main_spec_compliant_allowed.html^headers^ \
-  test_CSP_evalscript_getCRMFRequest.html \
-  file_CSP_evalscript_main_getCRMFRequest.html \
-  file_CSP_evalscript_main_getCRMFRequest.html^headers^ \
-  file_CSP_evalscript_main_getCRMFRequest.js \
-  file_CSP_evalscript_main_allowed_getCRMFRequest.js \
-  file_CSP_evalscript_main_spec_compliant_getCRMFRequest.html \
-  file_CSP_evalscript_main_spec_compliant_getCRMFRequest.html^headers^ \
-  file_CSP_evalscript_main_spec_compliant_allowed_getCRMFRequest.html \
-  file_CSP_evalscript_main_spec_compliant_allowed_getCRMFRequest.html^headers^ \
-  file_CSP_evalscript_no_CSP_at_all.html \
-  file_CSP_evalscript_no_CSP_at_all.html^headers^ \
-  file_CSP_evalscript_no_CSP_at_all.js \
-  test_CSP_inlinestyle.html \
-  file_CSP_inlinestyle_main.html \
-  file_CSP_inlinestyle_main.html^headers^ \
-  file_CSP_inlinestyle_main_spec_compliant.html \
-  file_CSP_inlinestyle_main_spec_compliant.html^headers^ \
-  file_CSP_inlinestyle_main_spec_compliant_allowed.html \
-  file_CSP_inlinestyle_main_spec_compliant_allowed.html^headers^ \
-  file_csp_bug768029.html \
-  file_csp_bug768029.sjs \
-  file_csp_bug773891.html \
-  file_csp_bug773891.sjs \
-  test_csp_redirects.html \
-  file_csp_redirects_page.sjs \
-  file_csp_redirects_main.html \
-  file_csp_redirects_resource.sjs \
-  test_bothCSPheaders.html \
-  file_bothCSPheaders.html \
-  file_bothCSPheaders.html^headers^ \
-  test_CSP_bug663567.html \
-  file_CSP_bug663567_allows.xml \
-  file_CSP_bug663567_allows.xml^headers^ \
-  file_CSP_bug663567.xsl \
-  file_CSP_bug663567_blocks.xml \
-  file_CSP_bug663567_blocks.xml^headers^ \
-  test_CSP_bug802872.html \
-  file_CSP_bug802872.html \
-  file_CSP_bug802872.html^headers^ \
-  file_CSP_bug802872.js \
-  file_CSP_bug802872.sjs \
-  test_CSP_bug885433.html \
-  file_CSP_bug885433_allows.html \
-  file_CSP_bug885433_allows.html^headers^ \
-  file_CSP_bug885433_blocks.html \
-  file_CSP_bug885433_blocks.html^headers^ \
-  test_CSP_bug888172.html \
-  file_CSP_bug888172.html \
-  file_CSP_bug888172.sjs \
-  test_bug836922_npolicies.html \
-  file_bug836922_npolicies.html \
-  file_bug836922_npolicies.html^headers^ \
-  file_bug836922_npolicies_violation.sjs \
-  file_bug836922_npolicies_ro_violation.sjs \
-  test_CSP_bug916446.html \
-  file_CSP_bug916446.html \
-  file_CSP_bug916446.html^headers^ \
-  $(NULL)
-
-MOCHITEST_CHROME_FILES := \
-  test_csp_bug768029.html \
-  test_csp_bug773891.html \
-  $(NULL)
-
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/chrome.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+
+[test_csp_bug768029.html]
+[test_csp_bug773891.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/mochitest.ini
@@ -0,0 +1,92 @@
+[DEFAULT]
+support-files =
+  file_CSP.css
+  file_CSP.sjs
+  file_CSP_bug663567.xsl
+  file_CSP_bug663567_allows.xml
+  file_CSP_bug663567_allows.xml^headers^
+  file_CSP_bug663567_blocks.xml
+  file_CSP_bug663567_blocks.xml^headers^
+  file_CSP_bug802872.html
+  file_CSP_bug802872.html^headers^
+  file_CSP_bug802872.js
+  file_CSP_bug802872.sjs
+  file_CSP_bug885433_allows.html
+  file_CSP_bug885433_allows.html^headers^
+  file_CSP_bug885433_blocks.html
+  file_CSP_bug885433_blocks.html^headers^
+  file_CSP_bug888172.html
+  file_CSP_bug888172.sjs
+  file_CSP_bug916446.html
+  file_CSP_bug916446.html^headers^
+  file_CSP_evalscript_main.html
+  file_CSP_evalscript_main.html^headers^
+  file_CSP_evalscript_main.js
+  file_CSP_evalscript_main_allowed.js
+  file_CSP_evalscript_main_allowed_getCRMFRequest.js
+  file_CSP_evalscript_main_getCRMFRequest.html
+  file_CSP_evalscript_main_getCRMFRequest.html^headers^
+  file_CSP_evalscript_main_getCRMFRequest.js
+  file_CSP_evalscript_main_spec_compliant.html
+  file_CSP_evalscript_main_spec_compliant.html^headers^
+  file_CSP_evalscript_main_spec_compliant_allowed.html
+  file_CSP_evalscript_main_spec_compliant_allowed.html^headers^
+  file_CSP_evalscript_main_spec_compliant_allowed_getCRMFRequest.html
+  file_CSP_evalscript_main_spec_compliant_allowed_getCRMFRequest.html^headers^
+  file_CSP_evalscript_main_spec_compliant_getCRMFRequest.html
+  file_CSP_evalscript_main_spec_compliant_getCRMFRequest.html^headers^
+  file_CSP_evalscript_no_CSP_at_all.html
+  file_CSP_evalscript_no_CSP_at_all.html^headers^
+  file_CSP_evalscript_no_CSP_at_all.js
+  file_CSP_frameancestors.sjs
+  file_CSP_frameancestors_main.html
+  file_CSP_frameancestors_main.js
+  file_CSP_frameancestors_main_spec_compliant.html
+  file_CSP_frameancestors_main_spec_compliant.js
+  file_CSP_frameancestors_spec_compliant.sjs
+  file_CSP_inlinescript_main.html
+  file_CSP_inlinescript_main.html^headers^
+  file_CSP_inlinescript_main_spec_compliant.html
+  file_CSP_inlinescript_main_spec_compliant.html^headers^
+  file_CSP_inlinescript_main_spec_compliant_allowed.html
+  file_CSP_inlinescript_main_spec_compliant_allowed.html^headers^
+  file_CSP_inlinestyle_main.html
+  file_CSP_inlinestyle_main.html^headers^
+  file_CSP_inlinestyle_main_spec_compliant.html
+  file_CSP_inlinestyle_main_spec_compliant.html^headers^
+  file_CSP_inlinestyle_main_spec_compliant_allowed.html
+  file_CSP_inlinestyle_main_spec_compliant_allowed.html^headers^
+  file_CSP_main.html
+  file_CSP_main.html^headers^
+  file_CSP_main.js
+  file_CSP_main_spec_compliant.html
+  file_CSP_main_spec_compliant.html^headers^
+  file_CSP_main_spec_compliant.js
+  file_bothCSPheaders.html
+  file_bothCSPheaders.html^headers^
+  file_bug836922_npolicies.html
+  file_bug836922_npolicies.html^headers^
+  file_bug836922_npolicies_ro_violation.sjs
+  file_bug836922_npolicies_violation.sjs
+  file_csp_bug768029.html
+  file_csp_bug768029.sjs
+  file_csp_bug773891.html
+  file_csp_bug773891.sjs
+  file_csp_redirects_main.html
+  file_csp_redirects_page.sjs
+  file_csp_redirects_resource.sjs
+
+[test_CSP.html]
+[test_CSP_bug663567.html]
+[test_CSP_bug802872.html]
+[test_CSP_bug885433.html]
+[test_CSP_bug888172.html]
+[test_CSP_bug916446.html]
+[test_CSP_evalscript.html]
+[test_CSP_evalscript_getCRMFRequest.html]
+[test_CSP_frameancestors.html]
+[test_CSP_inlinescript.html]
+[test_CSP_inlinestyle.html]
+[test_bothCSPheaders.html]
+[test_bug836922_npolicies.html]
+[test_csp_redirects.html]
--- a/content/base/test/csp/moz.build
+++ b/content/base/test/csp/moz.build
@@ -1,6 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
new file mode 100644
--- /dev/null
+++ b/content/base/test/mochitest.ini
@@ -0,0 +1,574 @@
+[DEFAULT]
+support-files =
+  345339_iframe.html
+  Ahem.ttf
+  accesscontrol.resource
+  accesscontrol.resource^headers^
+  badContentType.eventsource
+  badContentType.eventsource^headers^
+  badHTTPResponseCode.eventsource
+  badHTTPResponseCode.eventsource^headers^
+  badMessageEvent.eventsource
+  badMessageEvent.eventsource^headers^
+  badMessageEvent2.eventsource
+  badMessageEvent2.eventsource^headers^
+  bug282547.sjs
+  bug298064-subframe.html
+  bug313646.txt
+  bug382113_object.html
+  bug419132.html
+  bug426308-redirect.sjs
+  bug435425.sjs
+  bug435425_redirect.sjs
+  bug444322.js
+  bug444322.txt
+  bug455629-helper.svg
+  bug457746.sjs
+  bug461735-post-redirect.js
+  bug461735-redirect1.sjs
+  bug461735-redirect2.sjs
+  bug466080.sjs
+  bug466409-empty.css
+  bug466409-page.html
+  bug475156.sjs
+  bug482935.sjs
+  bug540854.sjs
+  bug638112-response.txt
+  bug638112.sjs
+  bug682592-subframe-ref.html
+  bug682592-subframe.html
+  bug696301-script-1.js
+  bug696301-script-1.js^headers^
+  bug696301-script-2.js
+  bug803225_test_mailto.html
+  bug819051.sjs
+  copypaste.js
+  delayedServerEvents.sjs
+  eventsource.resource
+  eventsource.resource^headers^
+  eventsource_redirect.resource
+  eventsource_redirect.resource^headers^
+  eventsource_redirect_to.resource
+  eventsource_redirect_to.resource^headers^
+  file_CrossSiteXHR_cache_server.sjs
+  file_CrossSiteXHR_inner.html
+  file_CrossSiteXHR_inner.jar
+  file_CrossSiteXHR_inner_data.sjs
+  file_CrossSiteXHR_server.sjs
+  file_XHRDocURI.text
+  file_XHRDocURI.text^headers^
+  file_XHRDocURI.xml
+  file_XHRDocURI.xml^headers^
+  file_XHRSendData.sjs
+  file_XHRSendData_doc.xml
+  file_XHRSendData_doc.xml^headers^
+  file_XHR_anon.sjs
+  file_XHR_binary1.bin
+  file_XHR_binary1.bin^headers^
+  file_XHR_binary2.bin
+  file_XHR_fail1.txt
+  file_XHR_fail1.txt^headers^
+  file_XHR_header.sjs
+  file_XHR_pass1.xml
+  file_XHR_pass2.txt
+  file_XHR_pass3.txt
+  file_XHR_pass3.txt^headers^
+  file_XHR_system_redirect.html
+  file_XHR_system_redirect.html^headers^
+  file_XHR_timeout.sjs
+  file_base_xbl.xml
+  file_bug28293.sjs
+  file_bug326337.xml
+  file_bug326337_inner.html
+  file_bug326337_outer.html
+  file_bug416317.xhtml
+  file_bug426646-1.html
+  file_bug426646-2.html
+  file_bug428847-1.xhtml
+  file_bug428847-2.xhtml
+  file_bug498897.css
+  file_bug498897.html
+  file_bug498897.html^headers^
+  file_bug503481.sjs
+  file_bug503481b_inner.html
+  file_bug541937.html
+  file_bug541937.xhtml
+  file_bug548193.sjs
+  file_bug557892.html
+  file_bug558431.html
+  file_bug558431.html^headers^
+  file_bug562137.txt
+  file_bug590812-ref.xhtml
+  file_bug590812.xml
+  file_bug590870.html
+  file_bug601803a.html
+  file_bug601803b.html
+  file_bug604660-1.xml
+  file_bug604660-2.xsl
+  file_bug604660-3.js
+  file_bug604660-4.js
+  file_bug604660-5.xml
+  file_bug604660-6.xsl
+  file_bug622088.sjs
+  file_bug622088_inner.html
+  file_bug650386_content.sjs
+  file_bug650386_report.sjs
+  file_bug675121.sjs
+  file_bug687859-16.js
+  file_bug687859-16.js^headers^
+  file_bug687859-bom.js
+  file_bug687859-bom.js^headers^
+  file_bug687859-charset.js
+  file_bug687859-http.js
+  file_bug687859-http.js^headers^
+  file_bug687859-inherit.js
+  file_bug692434.xml
+  file_bug702439.html
+  file_bug707142_baseline.json
+  file_bug707142_bom.json
+  file_bug707142_utf-16.json
+  file_bug708620-2.html
+  file_bug708620.html
+  file_bug717511.html
+  file_bug717511.html^headers^
+  file_bug717511_2.html
+  file_bug717511_2.html^headers^
+  file_bug782342.txt
+  file_bug787778.sjs
+  file_bug804395.jar
+  file_bug869432.eventsource
+  file_bug869432.eventsource^headers^
+  file_bug902350.html
+  file_bug902350_frame.html
+  file_bug907892.html
+  file_html_in_xhr.html
+  file_html_in_xhr.sjs
+  file_html_in_xhr2.html
+  file_html_in_xhr3.html
+  file_htmlserializer_1.html
+  file_htmlserializer_1_bodyonly.html
+  file_htmlserializer_1_format.html
+  file_htmlserializer_1_linebreak.html
+  file_htmlserializer_1_links.html
+  file_htmlserializer_1_nested_body.html
+  file_htmlserializer_1_no_body.html
+  file_htmlserializer_1_noflag.html
+  file_htmlserializer_1_noformatpre.html
+  file_htmlserializer_1_raw.html
+  file_htmlserializer_1_sibling_body.html
+  file_htmlserializer_1_sibling_body_only_body.html
+  file_htmlserializer_1_wrap.html
+  file_htmlserializer_2.html
+  file_htmlserializer_2_basic.html
+  file_htmlserializer_2_enthtml.html
+  file_htmlserializer_2_entw3c.html
+  file_htmlserializer_2_latin1.html
+  file_htmlserializer_ipv6.html
+  file_htmlserializer_ipv6_out.html
+  file_mixed_content_frameNavigation.html
+  file_mixed_content_frameNavigation_blankTarget.html
+  file_mixed_content_frameNavigation_grandchild.html
+  file_mixed_content_frameNavigation_innermost.html
+  file_mixed_content_frameNavigation_secure.html
+  file_mixed_content_frameNavigation_secure_grandchild.html
+  file_mixed_content_main.html
+  file_mixed_content_main_bug803225.html
+  file_mixed_content_main_bug803225_websocket_wsh.py
+  file_mixed_content_server.sjs
+  file_mozfiledataurl_audio.ogg
+  file_mozfiledataurl_doc.html
+  file_mozfiledataurl_img.jpg
+  file_mozfiledataurl_inner.html
+  file_mozfiledataurl_text.txt
+  file_restrictedEventSource.sjs
+  file_websocket_basic_wsh.py
+  file_websocket_hello_wsh.py
+  file_websocket_http_resource.txt
+  file_websocket_wsh.py
+  file_x-frame-options_main.html
+  file_x-frame-options_page.sjs
+  file_xhtmlserializer_1.xhtml
+  file_xhtmlserializer_1_bodyonly.xhtml
+  file_xhtmlserializer_1_format.xhtml
+  file_xhtmlserializer_1_linebreak.xhtml
+  file_xhtmlserializer_1_links.xhtml
+  file_xhtmlserializer_1_nested_body.xhtml
+  file_xhtmlserializer_1_no_body.xhtml
+  file_xhtmlserializer_1_noflag.xhtml
+  file_xhtmlserializer_1_noformatpre.xhtml
+  file_xhtmlserializer_1_raw.xhtml
+  file_xhtmlserializer_1_sibling_body.xhtml
+  file_xhtmlserializer_1_sibling_body_only_body.xhtml
+  file_xhtmlserializer_1_wrap.xhtml
+  file_xhtmlserializer_2.xhtml
+  file_xhtmlserializer_2_basic.xhtml
+  file_xhtmlserializer_2_enthtml.xhtml
+  file_xhtmlserializer_2_entw3c.xhtml
+  file_xhtmlserializer_2_latin1.xhtml
+  fileutils.js
+  forRemoval.resource
+  forRemoval.resource^headers^
+  formReset.html
+  invalid_accesscontrol.resource
+  invalid_accesscontrol.resource^headers^
+  mutationobserver_dialog.html
+  progressserver.sjs
+  responseIdentical.sjs
+  script-1_bug597345.sjs
+  script-2_bug597345.js
+  script_bug602838.sjs
+  somedatas.resource
+  somedatas.resource^headers^
+  variable_style_sheet.sjs
+  viewport_helpers.js
+  w3element_traversal.svg
+  wholeTexty-helper.xml
+
+[test_CrossSiteXHR.html]
+[test_CrossSiteXHR_cache.html]
+[test_CrossSiteXHR_origin.html]
+[test_DOMException.html]
+[test_EventSource_redirects.html]
+[test_NodeIterator_basics_filters.xhtml]
+[test_NodeIterator_mutations_1.xhtml]
+[test_NodeIterator_mutations_2.html]
+[test_NodeIterator_mutations_3.html]
+[test_XHR.html]
+[test_XHRDocURI.html]
+[test_XHRSendData.html]
+[test_XHR_anon.html]
+[test_XHR_header.html]
+[test_XHR_onuploadprogress.html]
+[test_XHR_parameters.html]
+[test_XHR_system.html]
+[test_XHR_timeout.html]
+[test_XHR_timeout.js]
+[test_base.xhtml]
+[test_blobconstructor.html]
+[test_bug166235.html]
+[test_bug199959.html]
+[test_bug218236.html]
+[test_bug218277.html]
+[test_bug238409.html]
+[test_bug254337.html]
+[test_bug270145.xhtml]
+[test_bug276037-1.html]
+[test_bug276037-2.xhtml]
+[test_bug282547.html]
+[test_bug28293.html]
+[test_bug28293.xhtml]
+[test_bug298064.html]
+[test_bug300992.html]
+[test_bug311681.xml]
+[test_bug313646.html]
+[test_bug320799.html]
+[test_bug322317.html]
+[test_bug326337.html]
+[test_bug330925.xhtml]
+[test_bug331959.html]
+[test_bug333198.html]
+[test_bug333673.html]
+[test_bug337631.html]
+[test_bug338541.xhtml]
+[test_bug338583.html]
+[test_bug338679.html]
+[test_bug339494.html]
+[test_bug339494.xhtml]
+[test_bug340571.html]
+[test_bug343596.html]
+[test_bug345339.html]
+[test_bug346485.html]
+[test_bug352728.html]
+[test_bug352728.xhtml]
+[test_bug353334.html]
+[test_bug355026.html]
+[test_bug357450.html]
+[test_bug357450.js]
+[test_bug357450.xhtml]
+[test_bug357450_svg.xhtml]
+[test_bug357509.html]
+[test_bug358660.html]
+[test_bug362391.xhtml]
+[test_bug364092.xhtml]
+[test_bug364413.xhtml]
+[test_bug366944.html]
+[test_bug366946.html]
+[test_bug367164.html]
+[test_bug368972.html]
+[test_bug371576-2.html]
+[test_bug371576-3.html]
+[test_bug371576-4.html]
+[test_bug371576-5.html]
+[test_bug372086.html]
+[test_bug372964-2.html]
+[test_bug372964.html]
+[test_bug373181.xhtml]
+[test_bug375314.html]
+[test_bug378969.html]
+[test_bug380418.html]
+[test_bug380418.html^headers^]
+[test_bug382113.html]
+[test_bug382871.html]
+[test_bug384003.xhtml]
+[test_bug390219.html]
+[test_bug390735.html]
+[test_bug392318.html]
+[test_bug392511.html]
+[test_bug393968.html]
+[test_bug395915.html]
+[test_bug397234.html]
+[test_bug398243.html]
+[test_bug401662.html]
+[test_bug402150.html]
+[test_bug402150.html^headers^]
+[test_bug403841.html]
+[test_bug403852.html]
+[test_bug403868.xml]
+[test_bug405182.html]
+[test_bug409380.html]
+[test_bug410229.html]
+[test_bug413974.html]
+[test_bug414190.html]
+[test_bug415860.html]
+[test_bug416317-1.html]
+[test_bug416317-2.html]
+[test_bug416383.html]
+[test_bug417255.html]
+[test_bug417384.html]
+[test_bug418214.html]
+[test_bug419132.html]
+[test_bug419527.xhtml]
+[test_bug420609.xhtml]
+[test_bug420700.html]
+[test_bug421602.html]
+[test_bug422403-1.html]
+[test_bug422403-2.xhtml]
+[test_bug422537.html]
+[test_bug424212.html]
+[test_bug424359-1.html]
+[test_bug424359-2.html]
+[test_bug425013.html]
+[test_bug426308.html]
+[test_bug426646.html]
+[test_bug428847.html]
+[test_bug429157.html]
+[test_bug431082.html]
+[test_bug431701.html]
+[test_bug431833.html]
+[test_bug433533.html]
+[test_bug433662.html]
+[test_bug435425.html]
+[test_bug438519.html]
+[test_bug444030.xhtml]
+[test_bug444322.html]
+[test_bug444722.html]
+[test_bug448993.html]
+[test_bug450160.html]
+[test_bug451376.html]
+[test_bug453521.html]
+[test_bug453736.html]
+[test_bug454325.html]
+[test_bug454326.html]
+[test_bug455472.html]
+[test_bug455629.html]
+[test_bug456262.html]
+[test_bug457746.html]
+[test_bug459424.html]
+[test_bug461555.html]
+[test_bug461735.html]
+[test_bug465767.html]
+[test_bug466080.html]
+[test_bug466409.html]
+[test_bug466751.xhtml]
+[test_bug469020.html]
+[test_bug469304.html]
+[test_bug473162-1.html]
+[test_bug473162-2.html]
+[test_bug475156.html]
+[test_bug482935.html]
+[test_bug484396.html]
+[test_bug493881.html]
+[test_bug493881.js]
+[test_bug498240.html]
+[test_bug498433.html]
+[test_bug498897.html]
+[test_bug499656.html]
+[test_bug499656.xhtml]
+[test_bug500937.html]
+[test_bug503481.html]
+[test_bug503481b.html]
+[test_bug505783.html]
+[test_bug51034.html]
+[test_bug513194.html]
+[test_bug5141.html]
+[test_bug514487.html]
+[test_bug515401.html]
+[test_bug518104.html]
+[test_bug527896.html]
+[test_bug540854.html]
+[test_bug541937.html]
+[test_bug544642.html]
+[test_bug545644.html]
+[test_bug545644.xhtml]
+[test_bug548193.html]
+[test_bug548463.html]
+[test_bug553896.xhtml]
+[test_bug557892.html]
+[test_bug558431.html]
+[test_bug558726.html]
+[test_bug559526.html]
+[test_bug560780.html]
+[test_bug562137.html]
+[test_bug562169-1.html]
+[test_bug562169-2.html]
+[test_bug562652.html]
+[test_bug564047.html]
+[test_bug564863.xhtml]
+[test_bug567350.html]
+[test_bug578096.html]
+[test_bug585978.html]
+[test_bug587931.html]
+[test_bug588990.html]
+[test_bug590812.html]
+[test_bug590870.html]
+[test_bug592366.html]
+[test_bug592829.html]
+[test_bug597345.html]
+[test_bug599588.html]
+[test_bug601803.html]
+[test_bug602838.html]
+[test_bug604592.html]
+[test_bug604660.html]
+[test_bug605982.html]
+[test_bug606729.html]
+[test_bug614058.html]
+[test_bug614583.html]
+[test_bug622088.html]
+[test_bug622117.html]
+[test_bug622246.html]
+[test_bug625722.html]
+[test_bug626262.html]
+[test_bug628938.html]
+[test_bug631615.html]
+[test_bug638112.html]
+[test_bug647518.html]
+[test_bug650386_redirect_301.html]
+[test_bug650386_redirect_302.html]
+[test_bug650386_redirect_303.html]
+[test_bug650386_redirect_307.html]
+[test_bug656283.html]
+[test_bug664916.html]
+[test_bug666604.html]
+[test_bug675121.html]
+[test_bug675166.html]
+[test_bug682463.html]
+[test_bug682554.html]
+[test_bug682592.html]
+[test_bug684671.html]
+[test_bug685798.html]
+[test_bug686449.xhtml]
+[test_bug687859.html]
+[test_bug690056.html]
+[test_bug692434.html]
+[test_bug693615.html]
+[test_bug693875.html]
+[test_bug694754.xhtml]
+[test_bug696301-1.html]
+[test_bug696301-2.html]
+[test_bug698381.html]
+[test_bug698384.html]
+[test_bug702439.html]
+[test_bug702439.html^headers^]
+[test_bug704063.html]
+[test_bug707142.html]
+[test_bug708620.html]
+[test_bug711047.html]
+[test_bug717511.html]
+[test_bug719533.html]
+[test_bug726364.html]
+[test_bug737087.html]
+[test_bug737565.html]
+[test_bug737612.html]
+[test_bug738108.html]
+[test_bug744830.html]
+[test_bug749367.html]
+[test_bug753278.html]
+[test_bug761120.html]
+[test_bug782342.html]
+[test_bug787778.html]
+[test_bug789856.html]
+[test_bug804395.html]
+[test_bug809003.html]
+[test_bug810494.html]
+[test_bug811701.html]
+[test_bug811701.xhtml]
+[test_bug813919.html]
+[test_bug814576.html]
+[test_bug819051.html]
+[test_bug820909.html]
+[test_bug868999.html]
+[test_bug869000.html]
+[test_bug869002.html]
+[test_bug869006.html]
+[test_bug876282.html]
+[test_bug890580.html]
+[test_bug894874.html]
+[test_bug895239.html]
+[test_bug895974.html]
+[test_bug902847.html]
+[test_bug907892.html]
+[test_caretPositionFromPoint.html]
+[test_classList.html]
+[test_copypaste.html]
+[test_copypaste.xhtml]
+[test_createHTMLDocument.html]
+[test_declare_stylesheet_obsolete.html]
+[test_domparser_null_char.html]
+[test_domparsing.html]
+[test_elementTraversal.html]
+[test_fileapi.html]
+[test_fileapi_slice.html]
+[test_html_colors_quirks.html]
+[test_html_colors_standards.html]
+[test_html_in_xhr.html]
+[test_htmlcopyencoder.html]
+[test_htmlcopyencoder.xhtml]
+[test_ipc_messagemanager_blob.html]
+[test_meta_viewport0.html]
+[test_meta_viewport1.html]
+[test_meta_viewport2.html]
+[test_meta_viewport3.html]
+[test_meta_viewport4.html]
+[test_meta_viewport5.html]
+[test_meta_viewport6.html]
+[test_mixed_content_blocker.html]
+[test_mixed_content_blocker_bug803225.html]
+[test_mixed_content_blocker_frameNavigation.html]
+[test_mozfiledataurl.html]
+[test_mutationobservers.html]
+[test_nodelist_holes.html]
+[test_object.html]
+[test_plugin_freezing.html]
+[test_processing_instruction_update_stylesheet.xhtml]
+[test_range_bounds.html]
+[test_reentrant_flush.html]
+[test_sync_xhr_timer.xhtml]
+[test_text_wholeText.html]
+[test_textnode_normalize_in_selection.html]
+[test_textnode_split_in_selection.html]
+[test_title.html]
+[test_treewalker_nextsibling.xml]
+[test_viewport_scroll.html]
+[test_w3element_traversal.html]
+[test_w3element_traversal.xhtml]
+[test_w3element_traversal_svg.html]
+[test_websocket.html]
+[test_websocket_basic.html]
+[test_websocket_hello.html]
+[test_x-frame-options.html]
+[test_xbl_userdata.xhtml]
+[test_xhr_abort_after_load.html]
+[test_xhr_forbidden_headers.html]
+[test_xhr_progressevents.html]
+[test_xhr_send_readystate.html]
+[test_xhr_withCredentials.html]
--- a/content/base/test/moz.build
+++ b/content/base/test/moz.build
@@ -19,8 +19,14 @@ if CONFIG['OS_ARCH'] != 'Darwin':
     XPCSHELL_TESTS_MANIFESTS += ['unit_ipc/xpcshell.ini']
 
 CPP_UNIT_TESTS += [
     'TestGetURL.cpp',
     'TestNativeXMLHttpRequest.cpp',
     'TestPlainTextSerializer.cpp',
 ]
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
+BROWSER_CHROME_MANIFESTS += ['browser.ini']
+
--- a/content/base/test/websocket_hybi/Makefile.in
+++ b/content/base/test/websocket_hybi/Makefile.in
@@ -1,15 +1,7 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #### MODULE = content
 
-MOCHITEST_FILES = \
-    test_send-arraybuffer.html \
-    test_send-blob.html \
-    file_check-binary-messages_wsh.py \
-    test_receive-arraybuffer.html \
-    test_receive-blob.html \
-    file_binary-frames_wsh.py \
-    $(NULL)
new file mode 100644
--- /dev/null
+++ b/content/base/test/websocket_hybi/mochitest.ini
@@ -0,0 +1,9 @@
+[DEFAULT]
+support-files =
+  file_binary-frames_wsh.py
+  file_check-binary-messages_wsh.py
+
+[test_receive-arraybuffer.html]
+[test_receive-blob.html]
+[test_send-arraybuffer.html]
+[test_send-blob.html]
--- a/content/base/test/websocket_hybi/moz.build
+++ b/content/base/test/websocket_hybi/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
--- a/content/canvas/test/Makefile.in
+++ b/content/canvas/test/Makefile.in
@@ -1,125 +1,14 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-	android.json \
-	test_canvas.html \
-	test_isPointInStroke.html \
-	image_transparent50.png \
-	image_redtransparent.png \
-	image_yellow.png \
-	image_anim-poster-gr.png \
-	image_green-16x16.png \
-	image_red-16x16.png \
-	image_green-1x1.png \
-	image_ggrr-256x256.png \
-	image_yellow75.png \
-	image_anim-gr.gif \
-	image_rrgg-256x256.png \
-	image_broken.png \
-	image_anim-gr.png \
-	image_rgrg-256x256.png \
-	image_red.png \
-	image_transparent.png \
-	image_green.png \
-	image_green-redirect \
-	image_green-redirect^headers^ \
-	test_drawImageIncomplete.html \
-	test_canvas_font_setter.html \
-	test_2d.clearRect.image.offscreen.html \
-	test_2d.clip.winding.html \
-	test_2d.composite.canvas.destination-atop.html \
-	test_2d.composite.canvas.destination-in.html \
-	test_2d.composite.canvas.source-in.html \
-	test_2d.composite.canvas.source-out.html \
-	test_2d.composite.canvas.hard-light.html \
-	test_2d.composite.canvas.soft-light.html \
-	test_2d.composite.canvas.color.html \
-	test_2d.composite.image.destination-atop.html \
-	test_2d.composite.image.destination-in.html \
-	test_2d.composite.image.source-in.html \
-	test_2d.composite.image.source-out.html \
-	test_2d.composite.solid.hard-light.html \
-	test_2d.composite.uncovered.image.destination-in.html \
-	test_2d.composite.uncovered.image.source-in.html \
-	test_2d.composite.uncovered.image.source-out.html \
-	test_2d.composite.uncovered.fill.multiply.html \
-	test_2d.composite.uncovered.fill.screen.html \
-	test_2d.composite.uncovered.fill.overlay.html \
-	test_2d.composite.uncovered.fill.darken.html \
-	test_2d.composite.uncovered.fill.lighten.html \
-	test_2d.composite.uncovered.fill.color-dodge.html \
-	test_2d.composite.uncovered.fill.color-burn.html \
-	test_2d.composite.uncovered.fill.hard-light.html \
-	test_2d.composite.uncovered.fill.soft-light.html \
-	test_2d.composite.uncovered.fill.difference.html \
-	test_2d.composite.uncovered.fill.exclusion.html \
-	test_2d.composite.uncovered.fill.hue.html \
-	test_2d.composite.uncovered.fill.saturation.html \
-	test_2d.composite.uncovered.fill.color.html \
-	test_2d.composite.uncovered.fill.luminosity.html \
-	test_2d.drawImage.zerocanvas.html \
-	test_2d.fill.winding.html \
-	test_2d.isPointInPath.winding.html \
-	test_2d.strokeRect.zero.5.html \
-	test_toBlob.html \
-	test_toDataURL_alpha.html \
-	test_toDataURL_lowercase_ascii.html \
-	test_toDataURL_parameters.html \
-	test_mozGetAsFile.html \
-	test_canvas_strokeStyle_getter.html \
-	test_bug613794.html \
-	test_bug753758.html \
-	test_bug764125.html \
-	test_bug856472.html \
-	test_bug866575.html \
-	test_drawImage_edge_cases.html \
-	test_drawImage_document_domain.html \
-	test_mozDashOffset.html \
-	file_drawImage_document_domain.html \
-	test_windingRuleUndefined.html \
-	test_strokeText_throw.html \
-	test_bug902651.html \
-	$(NULL)
-
 # SkiaGL on Android/Gonk does not implement these composite ops yet
-
-MOCHITEST_FILES += \
-	test_2d.composite.canvas.color-burn.html \
-	test_2d.composite.canvas.color-dodge.html \
-	test_2d.composite.canvas.darken.html \
-	test_2d.composite.canvas.difference.html \
-	test_2d.composite.canvas.exclusion.html \
-	test_2d.composite.canvas.hue.html \
-	test_2d.composite.canvas.lighten.html \
-	test_2d.composite.canvas.luminosity.html \
-	test_2d.composite.canvas.multiply.html \
-	test_2d.composite.canvas.overlay.html \
-	test_2d.composite.canvas.saturation.html \
-	test_2d.composite.canvas.screen.html \
-	test_2d.composite.solid.color-burn.html \
-	test_2d.composite.solid.color-dodge.html \
-	test_2d.composite.solid.color.html \
-	test_2d.composite.solid.darken.html \
-	test_2d.composite.solid.difference.html \
-	test_2d.composite.solid.exclusion.html \
-	test_2d.composite.solid.hue.html \
-	test_2d.composite.solid.lighten.html \
-	test_2d.composite.solid.luminosity.html \
-	test_2d.composite.solid.multiply.html \
-	test_2d.composite.solid.overlay.html \
-	test_2d.composite.solid.saturation.html \
-	test_2d.composite.solid.screen.html \
-	test_2d.composite.solid.soft-light.html \
-	$(NULL)
-
 ifneq (1_Linux,$(MOZ_SUITE)_$(OS_ARCH))
 # This test fails in Suite on Linux for some reason, disable it there
 MOCHITEST_FILES += test_2d.composite.uncovered.image.destination-atop.html
 endif
 
 # xor and lighter aren't well handled by cairo; they mostly work, but we don't want
 # to test that
 #	test_2d.composite.solid.xor.html \
--- a/content/canvas/test/chrome/Makefile.in
+++ b/content/canvas/test/chrome/Makefile.in
@@ -1,9 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_CHROME_FILES = \
-	test_webgl_debug_renderer_info.html \
-	nonchrome_webgl_debug_renderer_info.html \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/chrome/chrome.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files = nonchrome_webgl_debug_renderer_info.html
+
+[test_webgl_debug_renderer_info.html]
--- a/content/canvas/test/chrome/moz.build
+++ b/content/canvas/test/chrome/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/content/canvas/test/crossorigin/Makefile.in
+++ b/content/canvas/test/crossorigin/Makefile.in
@@ -1,16 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-	image-allow-credentials.png \
-	image-allow-credentials.png^headers^ \
-	image-allow-star.png \
-	image-allow-star.png^headers^ \
-	image.png \
-	test_canvas2d_crossorigin.html \
-	test_webgl_crossorigin_textures.html \
-	video.sjs \
-	test_video_crossorigin.html \
-	$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/crossorigin/mochitest.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+support-files =
+  image-allow-credentials.png
+  image-allow-credentials.png^headers^
+  image-allow-star.png
+  image-allow-star.png^headers^
+  image.png
+  video.sjs
+
+[test_canvas2d_crossorigin.html]
+[test_video_crossorigin.html]
+[test_webgl_crossorigin_textures.html]
--- a/content/canvas/test/crossorigin/moz.build
+++ b/content/canvas/test/crossorigin/moz.build
@@ -1,6 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/mochitest.ini
@@ -0,0 +1,107 @@
+[DEFAULT]
+support-files =
+  android.json
+  file_drawImage_document_domain.html
+  image_anim-gr.gif
+  image_anim-gr.png
+  image_anim-poster-gr.png
+  image_broken.png
+  image_ggrr-256x256.png
+  image_green-16x16.png
+  image_green-1x1.png
+  image_green-redirect
+  image_green-redirect^headers^
+  image_green.png
+  image_red-16x16.png
+  image_red.png
+  image_redtransparent.png
+  image_rgrg-256x256.png
+  image_rrgg-256x256.png
+  image_transparent.png
+  image_transparent50.png
+  image_yellow.png
+  image_yellow75.png
+
+[test_2d.clearRect.image.offscreen.html]
+[test_2d.clip.winding.html]
+[test_2d.composite.canvas.color-burn.html]
+[test_2d.composite.canvas.color-dodge.html]
+[test_2d.composite.canvas.color.html]
+[test_2d.composite.canvas.darken.html]
+[test_2d.composite.canvas.destination-atop.html]
+[test_2d.composite.canvas.destination-in.html]
+[test_2d.composite.canvas.difference.html]
+[test_2d.composite.canvas.exclusion.html]
+[test_2d.composite.canvas.hard-light.html]
+[test_2d.composite.canvas.hue.html]
+[test_2d.composite.canvas.lighten.html]
+[test_2d.composite.canvas.luminosity.html]
+[test_2d.composite.canvas.multiply.html]
+[test_2d.composite.canvas.overlay.html]
+[test_2d.composite.canvas.saturation.html]
+[test_2d.composite.canvas.screen.html]
+[test_2d.composite.canvas.soft-light.html]
+[test_2d.composite.canvas.source-in.html]
+[test_2d.composite.canvas.source-out.html]
+[test_2d.composite.image.destination-atop.html]
+[test_2d.composite.image.destination-in.html]
+[test_2d.composite.image.source-in.html]
+[test_2d.composite.image.source-out.html]
+[test_2d.composite.solid.color-burn.html]
+[test_2d.composite.solid.color-dodge.html]
+[test_2d.composite.solid.color.html]
+[test_2d.composite.solid.darken.html]
+[test_2d.composite.solid.difference.html]
+[test_2d.composite.solid.exclusion.html]
+[test_2d.composite.solid.hard-light.html]
+[test_2d.composite.solid.hue.html]
+[test_2d.composite.solid.lighten.html]
+[test_2d.composite.solid.luminosity.html]
+[test_2d.composite.solid.multiply.html]
+[test_2d.composite.solid.overlay.html]
+[test_2d.composite.solid.saturation.html]
+[test_2d.composite.solid.screen.html]
+[test_2d.composite.solid.soft-light.html]
+[test_2d.composite.uncovered.fill.color-burn.html]
+[test_2d.composite.uncovered.fill.color-dodge.html]
+[test_2d.composite.uncovered.fill.color.html]
+[test_2d.composite.uncovered.fill.darken.html]
+[test_2d.composite.uncovered.fill.difference.html]
+[test_2d.composite.uncovered.fill.exclusion.html]
+[test_2d.composite.uncovered.fill.hard-light.html]
+[test_2d.composite.uncovered.fill.hue.html]
+[test_2d.composite.uncovered.fill.lighten.html]
+[test_2d.composite.uncovered.fill.luminosity.html]
+[test_2d.composite.uncovered.fill.multiply.html]
+[test_2d.composite.uncovered.fill.overlay.html]
+[test_2d.composite.uncovered.fill.saturation.html]
+[test_2d.composite.uncovered.fill.screen.html]
+[test_2d.composite.uncovered.fill.soft-light.html]
+[test_2d.composite.uncovered.image.destination-in.html]
+[test_2d.composite.uncovered.image.source-in.html]
+[test_2d.composite.uncovered.image.source-out.html]
+[test_2d.drawImage.zerocanvas.html]
+[test_2d.fill.winding.html]
+[test_2d.isPointInPath.winding.html]
+[test_2d.strokeRect.zero.5.html]
+[test_bug613794.html]
+[test_bug753758.html]
+[test_bug764125.html]
+[test_bug856472.html]
+[test_bug866575.html]
+[test_bug902651.html]
+[test_canvas.html]
+[test_canvas_font_setter.html]
+[test_canvas_strokeStyle_getter.html]
+[test_drawImageIncomplete.html]
+[test_drawImage_document_domain.html]
+[test_drawImage_edge_cases.html]
+[test_isPointInStroke.html]
+[test_mozDashOffset.html]
+[test_mozGetAsFile.html]
+[test_strokeText_throw.html]
+[test_toBlob.html]
+[test_toDataURL_alpha.html]
+[test_toDataURL_lowercase_ascii.html]
+[test_toDataURL_parameters.html]
+[test_windingRuleUndefined.html]
--- a/content/canvas/test/moz.build
+++ b/content/canvas/test/moz.build
@@ -1,8 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['webgl', 'crossorigin', 'chrome']
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
--- a/content/canvas/test/webgl/Makefile.in
+++ b/content/canvas/test/webgl/Makefile.in
@@ -1,31 +1,12 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-  test_webgl_conformance_test_suite.html \
-  00_test_list.txt \
-  failing_tests_linux.txt \
-  failing_tests_linux_mesa.txt \
-  skipped_tests_linux_mesa.txt \
-  failing_tests_linux_nvidia.txt \
-  failing_tests_windows.txt \
-  skipped_tests_winxp.txt \
-  skipped_tests_win_vista.txt \
-  failing_tests_mac.txt \
-  failing_tests_mac_mtnlion.txt \
-  failing_tests_android.txt \
-  failing_tests_android_nvidia.txt \
-  failing_tests_android_x86.txt \
-  skipped_tests_android.txt \
-  skipped_tests_android_x86.txt \
-  $(NULL)
-
 include $(topsrcdir)/config/rules.mk
 
 libs::
 	$(TAR) -cf - -C $(srcdir) \
 	  resources \
 	  conformance \
 	  | $(TAR) -xf - -C $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/mochitest.ini
@@ -0,0 +1,19 @@
+[DEFAULT]
+support-files =
+  00_test_list.txt
+  failing_tests_android.txt
+  failing_tests_android_nvidia.txt
+  failing_tests_android_x86.txt
+  failing_tests_linux.txt
+  failing_tests_linux_mesa.txt
+  failing_tests_linux_nvidia.txt
+  failing_tests_mac.txt
+  failing_tests_mac_mtnlion.txt
+  failing_tests_windows.txt
+  skipped_tests_android.txt
+  skipped_tests_android_x86.txt
+  skipped_tests_linux_mesa.txt
+  skipped_tests_win_vista.txt
+  skipped_tests_winxp.txt
+
+[test_webgl_conformance_test_suite.html]
--- a/content/canvas/test/webgl/moz.build
+++ b/content/canvas/test/webgl/moz.build
@@ -1,7 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['non-conf-tests']
+
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
--- a/content/canvas/test/webgl/non-conf-tests/Makefile.in
+++ b/content/canvas/test/webgl/non-conf-tests/Makefile.in
@@ -1,13 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-  driver-info.js \
-  webgl-util.js \
-  \
-  test_webgl_available.html \
-  test_webgl_conformance.html \
-  test_webgl_request_mismatch.html \
-  $(NULL)
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/non-conf-tests/mochitest.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+support-files =
+  driver-info.js
+  webgl-util.js
+
+[test_webgl_available.html]
+[test_webgl_conformance.html]
+[test_webgl_request_mismatch.html]
--- a/content/canvas/test/webgl/non-conf-tests/moz.build
+++ b/content/canvas/test/webgl/non-conf-tests/moz.build
@@ -1,5 +1,8 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -1,126 +1,15 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Disabled due to timeouts.
 # 		test_bug563329.html
-MOCHITEST_FILES = \
-		test_bug226361.xhtml \
-		     bug226361_iframe.xhtml \
-		test_bug238987.html \
-		test_bug288392.html \
-		test_bug299673-1.html \
-		test_bug299673-2.html \
-		     bug299673.js \
-		test_bug322588.html \
-		     bug322588-popup.html \
-		test_bug328885.html \
-		test_bug336682_1.html \
-		test_bug336682.js \
-		test_bug367781.html \
-		test_bug368835.html \
-		test_bug379120.html \
-		test_bug391568.xhtml \
-		test_bug402089.html \
-		test_bug405632.html \
-		test_bug409604.html \
-		test_bug412567.html \
-		test_bug422132.html \
-		test_bug426082.html \
-		bug426082.html \
-		test_bug427537.html \
-		test_bug432698.html \
-		test_bug443985.html \
-		test_bug447736.html \
-		test_bug448602.html \
-		test_bug450876.html \
-		test_bug456273.html \
-		test_bug457672.html \
-		test_bug428988.html \
-		bug457672.html \
-		test_draggableprop.html \
-		test_bug489671.html \
-		test_bug493251.html \
-		window_bug493251.html \
-		test_bug502818.html \
-		test_bug508479.html \
-		test_bug517851.html \
-		test_bug534833.html \
-		test_bug545268.html \
-		test_bug547996-1.html \
-		test_bug547996-2.xhtml \
-		test_bug556493.html \
-		test_bug574663.html \
-		test_clickevent_on_input.html \
-		test_bug593959.html \
-		test_bug591815.html \
-		test_bug605242.html \
-		test_bug613634.html \
-		test_bug607464.html \
-		test_bug624127.html \
-		test_bug650493.html \
-		test_bug641477.html \
-		test_bug648573.html \
-		test_bug615597.html \
-		test_bug656379-1.html \
-		bug656379-1.html \
-		test_bug656379-2.html \
-		test_bug656954.html \
-		test_bug659071.html \
-		window_bug659071.html \
-		test_bug659350.html \
-		test_bug662678.html \
-		test_bug667919-1.html \
-		test_bug667612.html \
-		empty.js \
-		test_bug689564.html \
-		test_bug698929.html \
-		test_eventctors.html \
-		test_bug635465.html \
-		test_bug741666.html \
-		test_dom_keyboard_event.html \
-		test_dom_mouse_event.html \
-		test_dom_wheel_event.html \
-		test_continuous_wheel_events.html \
-		test_moz_mouse_pixel_scroll_event.html \
-		test_wheel_default_action.html \
-		window_wheel_default_action.html \
-		test_bug603008.html \
-		test_bug742376.html \
-		test_dragstart.html \
-		test_bug812744.html \
-		test_addEventListenerExtraArg.html \
-		test_focus_disabled.html \
-		test_bug847597.html \
-		test_bug855741.html \
-		test_dblclick_explicit_original_target.html \
-		test_all_synthetic_events.html \
-		test_messageEvent.html \
-		$(NULL)
-
 ifeq (,$(filter gonk,$(MOZ_WIDGET_TOOLKIT)))
 # THESE TESTS (BELOW) DO NOT RUN ON B2G
 MOCHITEST_FILES += \
 		test_bug864040.html \
 		$(NULL)
 # THESE TESTS (ABOVE) DO NOT RUN ON B2G
 endif
 
-MOCHITEST_CHROME_FILES = \
-		test_bug336682_2.xul \
-		test_bug336682.js \
-		test_bug586961.xul \
-		test_bug415498.xul \
-		bug415498-doc1.html \
-		bug415498-doc2.html \
-		test_bug591249.xul \
-		bug591249_iframe.xul \
-		bug602962.xul \
-		test_bug602962.xul \
-		test_bug617528.xul \
-		window_bug617528.xul \
-		test_bug679494.xul \
-		file_bug679494.html \
-		test_eventctors.xul \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/events/test/chrome.ini
@@ -0,0 +1,18 @@
+[DEFAULT]
+support-files =
+  bug415498-doc1.html
+  bug415498-doc2.html
+  bug591249_iframe.xul
+  bug602962.xul
+  file_bug679494.html
+  window_bug617528.xul
+
+[test_bug336682.js]
+[test_bug336682_2.xul]
+[test_bug415498.xul]
+[test_bug586961.xul]
+[test_bug591249.xul]
+[test_bug602962.xul]
+[test_bug617528.xul]
+[test_bug679494.xul]
+[test_eventctors.xul]
new file mode 100644
--- /dev/null
+++ b/content/events/test/mochitest.ini
@@ -0,0 +1,94 @@
+[DEFAULT]
+support-files =
+  bug226361_iframe.xhtml
+  bug299673.js
+  bug322588-popup.html
+  bug426082.html
+  bug457672.html
+  bug656379-1.html
+  empty.js
+  window_bug493251.html
+  window_bug659071.html
+  window_wheel_default_action.html
+
+[test_addEventListenerExtraArg.html]
+[test_all_synthetic_events.html]
+[test_bug226361.xhtml]
+[test_bug238987.html]
+[test_bug288392.html]
+[test_bug299673-1.html]
+[test_bug299673-2.html]
+[test_bug322588.html]
+[test_bug328885.html]
+[test_bug336682.js]
+[test_bug336682_1.html]
+[test_bug367781.html]
+[test_bug368835.html]
+[test_bug379120.html]
+[test_bug391568.xhtml]
+[test_bug402089.html]
+[test_bug405632.html]
+[test_bug409604.html]
+[test_bug412567.html]
+[test_bug422132.html]
+[test_bug426082.html]
+[test_bug427537.html]
+[test_bug428988.html]
+[test_bug432698.html]
+[test_bug443985.html]
+[test_bug447736.html]
+[test_bug448602.html]
+[test_bug450876.html]
+[test_bug456273.html]
+[test_bug457672.html]
+[test_bug489671.html]
+[test_bug493251.html]
+[test_bug502818.html]
+[test_bug508479.html]
+[test_bug517851.html]
+[test_bug534833.html]
+[test_bug545268.html]
+[test_bug547996-1.html]
+[test_bug547996-2.xhtml]
+[test_bug556493.html]
+[test_bug574663.html]
+[test_bug591815.html]
+[test_bug593959.html]
+[test_bug603008.html]
+[test_bug605242.html]
+[test_bug607464.html]
+[test_bug613634.html]
+[test_bug615597.html]
+[test_bug624127.html]
+[test_bug635465.html]
+[test_bug641477.html]
+[test_bug648573.html]
+[test_bug650493.html]
+[test_bug656379-1.html]
+[test_bug656379-2.html]
+[test_bug656954.html]
+[test_bug659071.html]
+[test_bug659350.html]
+[test_bug662678.html]
+[test_bug667612.html]
+[test_bug667919-1.html]
+[test_bug689564.html]
+[test_bug698929.html]
+[test_bug741666.html]
+[test_bug742376.html]
+[test_bug812744.html]
+[test_bug847597.html]
+[test_bug855741.html]
+[test_clickevent_on_input.html]
+[test_continuous_wheel_events.html]
+[test_dblclick_explicit_original_target.html]
+[test_dom_keyboard_event.html]
+[test_dom_mouse_event.html]
+[test_dom_wheel_event.html]
+[test_draggableprop.html]
+[test_dragstart.html]
+[test_eventctors.html]
+[test_focus_disabled.html]
+[test_messageEvent.html]
+[test_moz_mouse_pixel_scroll_event.html]
+[test_wheel_default_action.html]
--- a/content/events/test/moz.build
+++ b/content/events/test/moz.build
@@ -1,6 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
+MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
+
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -1,402 +1,5 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-		test_hidden.html \
-		test_bug589.html \
-		test_bug691.html \
-		nnc_lockup.gif \
-		test_bug694.html \
-		test_bug696.html \
-		test_bug1297.html \
-		test_bug1366.html \
-		test_bug1400.html \
-		test_bug2082.html \
-		test_bug3348.html \
-		test_bug6296.html \
-		test_bug24958.html \
-		bug100533_load.html \
-		bug100533_iframe.html \
-		test_bug100533.html \
-		image.png \
-		test_bug109445.html \
-		test_bug109445.xhtml \
-		test_bug143220.html \
-		test_bug182279.html \
-		test_bug237071.html \
-		bug242709_iframe.html \
-		bug242709_load.html \
-		test_bug242709.html \
-		bug277724_iframe1.html \
-		bug277724_iframe2.xhtml \
-		test_bug277724.html \
-		bug277890_iframe.html \
-		bug277890_load.html \
-		test_bug277890.html \
-		test_bug274626.html \
-		test_bug287465.html \
-		test_bug209275.xhtml \
-		file_bug209275_1.html \
-		file_bug209275_2.html \
-		file_bug209275_3.html \
-		test_bug295561.html \
-		test_bug300691-1.html \
-		test_bug300691-2.html \
-		test_bug300691-3.xhtml \
-		test_bug330705-1.html \
-		test_bug332246.html \
-		test_bug332893-1.html \
-		test_bug332893-2.html \
-		test_bug332893-3.html \
-		test_bug332893-4.html \
-		test_bug332893-5.html \
-		test_bug332893-6.html \
-		test_bug332893-7.html \
-		bug340800_iframe.txt \
-		test_bug340800.html \
-		test_bug353415-1.html \
-		test_bug353415-2.html \
-		test_bug371375.html \
-		test_bug373589.html \
-		bug372098-link-target.html \
-		test_bug372098.html \
-		test_bug375003-1.html \
-		test_bug375003-2.html \
-		test_bug383383.html \
-		test_bug383383_2.xhtml \
-		test_bug384419.html \
-		test_bug386496.html \
-		test_bug386728.html \
-		test_bug386996.html \
-		test_bug388558.html \
-		test_bug388746.html \
-		test_bug388794.html \
-		test_bug389797.html \
-		test_bug390975.html \
-		test_bug391994.html \
-		test_bug392567.html \
-		bug392567.jar       \
-		bug392567.jar^headers^ \
-		test_bug394700.html \
-		test_bug395107.html \
-		test_bug401160.xhtml \
-		test_bug405242.html \
-		test_bug406596.html \
-		test_bug417760.html \
-		file_bug417760.png \
-		test_formSubmission.html \
-		test_formSubmission2.html \
-		file_formSubmission_text.txt \
-		file_formSubmission_img.jpg \
-		test_bug421640.html \
-		test_bug424698.html \
-		test_bug428135.xhtml \
-		test_bug430351.html \
-		test_bug430392.html \
-		bug441930_iframe.html \
-		test_bug441930.html \
-		test_bug442801.html \
-		test_bug448166.html \
-		test_bug460568.html \
-		test_bug347174.html \
-		test_bug347174_write.html \
-		test_bug347174_xsl.html \
-		test_bug347174_xslp.html \
-		347174transformable.xml \
-		347174transform.xsl \
-		test_a_text.html \
-		test_anchor_href_cache_invalidation.html \
-		test_bug481335.xhtml \
-		test_bug500885.html \
-		test_bug514856.html \
-		bug514856_iframe.html \
-		test_bug518122.html \
-		test_bug519987.html \
-		test_bug579079.html \
-		test_bug523771.html \
-		form_submit_server.sjs \
-		test_bug529819.html \
-		test_bug529859.html \
-		test_bug535043.html \
-		test_bug547850.html \
-		test_bug536891.html \
-		test_bug536895.html \
-		test_bug458037.xhtml \
-		test_bug556645.html \
-		test_bug555567.html \
-		test_bug557620.html \
-		test_bug456229.html \
-		test_bug546995.html \
-		test_bug377624.html \
-		test_bug551846.html \
-		test_bug564001.html \
-		test_bug566046.html \
-		test_bug567938-1.html \
-		test_bug567938-2.html \
-		test_bug567938-3.html \
-		test_bug567938-4.html \
-		test_bug569955.html \
-		test_bug573969.html \
-		test_bug561640.html \
-		test_bug582412-1.html \
-		test_bug582412-2.html \
-		test_bug558788-1.html \
-		test_bug558788-2.html \
-		test_bug561634.html \
-		test_bug590353-1.html \
-		test_bug590353-2.html \
-		test_bug593689.html \
-		test_bug561636.html \
-		test_bug590363.html \
-		test_bug592802.html \
-		test_bug595429.html \
-		test_bug595447.html \
-		test_bug595449.html \
-		test_bug557087-1.html \
-		test_bug557087-2.html \
-		test_bug557087-3.html \
-		test_bug557087-4.html \
-		test_bug557087-5.html \
-		test_bug557087-6.html \
-		test_bug586763.html \
-		test_bug587469.html \
-		test_bug598643.html \
-		test_bug596350.html \
-		test_bug598833-1.html \
-		test_bug600155.html \
-		test_bug606817.html \
-		test_bug297761.html \
-		file_bug297761.html \
-		test_bug607145.html \
-		test_bug596511.html \
-		reflect.js \
-		test_bug611189.html \
-		test_bug613113.html \
-		test_bug605124-1.html \
-		test_bug605124-2.html \
-		test_bug605125-1.html \
-		test_bug605125-2.html \
-		test_bug612730.html \
-		test_bug613722.html \
-		test_bug613979.html \
-		test_bug615833.html \
-		test_bug601030.html \
-		test_bug610687.html \
-		test_bug618948.html \
-		test_bug623291.html \
-		test_bug619278.html \
-		test_bug622558.html \
-		test_bug622597.html \
-		test_bug636336.html \
-		test_bug610212.html \
-		test_bug633058.html \
-		test_bug641219.html \
-		test_bug643051.html \
-		test_bug583514.html \
-		test_bug560112.html \
-		test_bug586786.html \
-		test_bug646157.html \
-		test_bug649134.html \
-		test_bug658746.html \
-		test_bug659596.html \
-		test_bug659743.xml \
-		test_bug660663.html \
-		test_bug666200.html \
-		test_bug666666.html \
-		test_bug669012.html \
-		test_bug674558.html \
-		test_bug583533.html \
-		test_restore_from_parser_fragment.html \
-		test_bug615595.html \
-		test_bug617528.html \
-		test_bug660959-1.html \
-		test_bug660959-2.html \
-		test_bug660959-3.html \
-		test_checked.html \
-		test_bug677658.html \
-		test_bug677463.html \
-		test_bug682886.html \
-		test_bug717819.html \
-		test_undoManager.html \
-		file_fullscreen-utils.js \
-		file_fullscreen-api.html \
-		file_fullscreen-api-keys.html \
-		test_fullscreen-api.html \
-		file_fullscreen-plugins.html \
-		file_fullscreen-denied.html \
-		file_fullscreen-denied-inner.html \
-		file_fullscreen-hidden.html \
-		file_fullscreen-navigation.html \
-		file_fullscreen-esc-exit.html \
-		file_fullscreen-esc-exit-inner.html \
-		file_fullscreen-rollback.html \
-		file_fullscreen-svg-element.html \
-		file_fullscreen-multiple.html \
-		file_fullscreen-multiple-inner.html \
-		test_li_attributes_reflection.html \
-		test_link_attributes_reflection.html \
-		test_object_attributes_reflection.html \
-		test_embed_attributes_reflection.html \
-		test_applet_attributes_reflection.html \
-		test_ol_attributes_reflection.html \
-		test_dl_attributes_reflection.html \
-		test_ul_attributes_reflection.html \
-		test_param_attributes_reflection.html \
-		test_base_attributes_reflection.html \
-		test_dir_attributes_reflection.html \
-		test_q_attributes_reflection.html \
-		test_html_attributes_reflection.html \
-		test_bug651956.html \
-		test_bug674927.html \
-		test_bug694503.html \
-		test_object_plugin_nav.html \
-		test_bug742030.html \
-		test_bug742549.html \
-		test_bug745685.html \
-		test_bug763626.html \
-		test_bug780993.html \
-		test_bug797113.html \
-		test_bug787134.html \
-		test_bug803677.html \
-		test_bug827126.html \
-		test_bug827426.html \
-		test_bug838582.html \
-		test_bug839913.html \
-		test_bug840877.html \
-		test_bug841466.html \
-		test_iframe_sandbox_inheritance.html \
-		file_iframe_sandbox_a_if1.html \
-		file_iframe_sandbox_a_if2.html \
-		file_iframe_sandbox_a_if3.html \
-		file_iframe_sandbox_a_if4.html \
-		file_iframe_sandbox_a_if5.html \
-		file_iframe_sandbox_a_if6.html \
-		file_iframe_sandbox_a_if7.html \
-		file_iframe_sandbox_a_if8.html \
-		file_iframe_sandbox_a_if9.html \
-		file_iframe_sandbox_a_if10.html \
-		file_iframe_sandbox_a_if11.html \
-		file_iframe_sandbox_a_if12.html \
-		file_iframe_sandbox_a_if13.html \
-		file_iframe_sandbox_a_if14.html \
-		file_iframe_sandbox_a_if15.html \
-		file_iframe_sandbox_a_if16.html \
-		file_iframe_sandbox_a_if17.html \
-		file_iframe_sandbox_a_if18.html \
-		file_iframe_sandbox_a_if19.html \
-		test_iframe_sandbox_same_origin.html \
-		file_iframe_sandbox_b_if1.html \
-		file_iframe_sandbox_b_if2.html \
-		file_iframe_sandbox_b_if3.html \
-		test_iframe_sandbox_general.html \
-		file_iframe_sandbox_c_if1.html \
-		file_iframe_sandbox_c_if2.html \
-		file_iframe_sandbox_c_if3.html \
-		file_iframe_sandbox_c_if4.html \
-		file_iframe_sandbox_c_if5.html \
-		file_iframe_sandbox_c_if6.html \
-		file_iframe_sandbox_c_if7.html \
-		file_iframe_sandbox_c_if8.html \
-		file_iframe_sandbox_form_fail.html \
-		file_iframe_sandbox_form_pass.html \
-		file_iframe_sandbox_open_window_fail.html \
-		file_iframe_sandbox_pass.js \
-		file_iframe_sandbox_fail.js \
-		test_iframe_sandbox_navigation.html \
-		test_iframe_sandbox_navigation2.html \
-		file_iframe_sandbox_d_if1.html \
-		file_iframe_sandbox_d_if2.html \
-		file_iframe_sandbox_d_if3.html \
-		file_iframe_sandbox_d_if4.html \
-		file_iframe_sandbox_d_if5.html \
-		file_iframe_sandbox_d_if6.html \
-		file_iframe_sandbox_d_if7.html \
-		file_iframe_sandbox_d_if8.html \
-		file_iframe_sandbox_d_if9.html \
-		file_iframe_sandbox_d_if10.html \
-		file_iframe_sandbox_d_if11.html \
-		file_iframe_sandbox_d_if12.html \
-		file_iframe_sandbox_d_if13.html \
-		file_iframe_sandbox_d_if14.html \
-		file_iframe_sandbox_d_if15.html \
-		file_iframe_sandbox_d_if16.html \
-		file_iframe_sandbox_d_if17.html \
-		file_iframe_sandbox_d_if18.html \
-		file_iframe_sandbox_d_if19.html \
-		file_iframe_sandbox_d_if20.html \
-		file_iframe_sandbox_d_if21.html \
-		file_iframe_sandbox_d_if22.html \
-		file_iframe_sandbox_navigation_start.html \
-		file_iframe_sandbox_navigation_pass.html \
-		file_iframe_sandbox_navigation_fail.html \
-		file_iframe_sandbox_e_if1.html \
-		file_iframe_sandbox_e_if2.html \
-		file_iframe_sandbox_e_if3.html \
-		file_iframe_sandbox_e_if4.html \
-		file_iframe_sandbox_e_if5.html \
-		file_iframe_sandbox_e_if6.html \
-		file_iframe_sandbox_e_if7.html \
-		file_iframe_sandbox_e_if8.html \
-		file_iframe_sandbox_e_if9.html \
-		file_iframe_sandbox_e_if10.html \
-		file_iframe_sandbox_e_if11.html \
-		file_iframe_sandbox_e_if12.html \
-		file_iframe_sandbox_e_if13.html \
-		file_iframe_sandbox_e_if14.html \
-		file_iframe_sandbox_e_if15.html \
-		file_iframe_sandbox_e_if16.html \
-		file_iframe_sandbox_top_navigation_pass.html \
-		file_iframe_sandbox_top_navigation_fail.html \
-		file_iframe_sandbox_window_navigation_fail.html \
-		test_iframe_sandbox_plugins.html \
-		file_iframe_sandbox_f_if1.html \
-		file_iframe_sandbox_f_if2.html \
-		file_iframe_sandbox_f_if2.html^headers^ \
-		test_iframe_sandbox_workers.html \
-		file_iframe_sandbox_g_if1.html \
-		file_iframe_sandbox_worker.js \
-		test_img_attributes_reflection.html \
-		test_named_options.html \
-		test_htmlcollection.html \
-		test_formelements.html \
-		test_rowscollection.html \
-		test_map_attributes_reflection.html \
-		test_meta_attributes_reflection.html \
-		test_mod_attributes_reflection.html \
-		test_mozaudiochannel.html \
-		test_style_attributes_reflection.html \
-		test_bug629801.html \
-		test_bug839371.html \
-		test_element_prototype.html \
-		test_formData.html \
-		test_audio_wakelock.html \
-		test_video_wakelock.html \
-		wakelock.ogg \
-		wakelock.ogv \
-		test_bug869040.html \
-		test_bug870787.html \
-		test_bug879319.html \
-		allowMedia.sjs \
-		test_bug874758.html \
-		test_bug885024.html \
-		test_track.html \
-		test_track_disabled.html \
-		test_srcdoc.html \
-		file_srcdoc.html \
-		test_srcdoc-2.html \
-		file_srcdoc-2.html \
-		test_bug893537.html \
-		file_bug893537.html \
-		$(NULL)
-
-MOCHITEST_CHROME_FILES = \
-		test_allowMedia.html \
-		$(NULL)
-
-MOCHITEST_BROWSER_FILES = \
-		browser_bug649778.js \
-		file_bug649778.html \
-		file_bug649778.html^headers^ \
-		$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/browser.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+support-files =
+  file_bug649778.html
+  file_bug649778.html^headers^
+
+[browser_bug649778.js]
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/chrome.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[test_allowMedia.html]
--- a/content/html/content/test/forms/Makefile.in
+++ b/content/html/content/test/forms/Makefile.in
@@ -1,64 +1,4 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-MOCHITEST_FILES = \
-		save_restore_radio_groups.sjs \
-		test_save_restore_radio_groups.html \
-		test_set_range_text.html \
-		test_change_event.html \
-		test_mozistextfield.html \
-		test_input_attributes_reflection.html \
-		test_input_list_attribute.html \
-		test_input_email.html \
-		test_input_range_attr_order.html \
-		test_input_range_key_events.html \
-		test_input_range_mouse_and_touch_events.html \
-		test_input_range_rounding.html \
-		test_input_url.html \
-		test_pattern_attribute.html \
-		test_required_attribute.html \
-		test_novalidate_