Bug 486342 - Write a browser-chrome test suite for the various "Save As" functions in Toolkit's "contentAreaUtils.js"; r=sdwilsh
authorPaolo Amadini <paolo.02.prg@amadzone.org>
Sun, 23 Aug 2009 16:52:23 +0200
changeset 31767 ecb8b1a47a6235d9448d6391027350bf338f7ae1
parent 31766 d417a85ce9f7fb1ef7fab824762bf4b8cdf02daf
child 31769 e455909e2a17bf3a60b320ecdd2d52178a0c9713
push idunknown
push userunknown
push dateunknown
reviewerssdwilsh
bugs486342
milestone1.9.3a1pre
Bug 486342 - Write a browser-chrome test suite for the various "Save As" functions in Toolkit's "contentAreaUtils.js"; r=sdwilsh
toolkit/content/tests/browser/Makefile.in
toolkit/content/tests/browser/browser_bug471962.js
toolkit/content/tests/browser/bug471962_testpage_inner.sjs
toolkit/content/tests/browser/bug471962_testpage_outer.sjs
toolkit/content/tests/browser/common/Makefile.in
toolkit/content/tests/browser/common/_loadAll.js
toolkit/content/tests/browser/common/mockFilePicker.js
toolkit/content/tests/browser/common/mockObjects.js
toolkit/content/tests/browser/common/mockTransferForContinuing.js
toolkit/content/tests/browser/common/testRunner.js
toolkit/content/tests/browser/common/toolkitFunctions.js
toolkit/content/tests/browser/data/Makefile.in
toolkit/content/tests/browser/data/post_form_inner.sjs
toolkit/content/tests/browser/data/post_form_outer.sjs
--- a/toolkit/content/tests/browser/Makefile.in
+++ b/toolkit/content/tests/browser/Makefile.in
@@ -37,21 +37,25 @@
 
 DEPTH          = ../../../..
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
 relativesrcdir = toolkit/content/tests/browser
 
 include $(DEPTH)/config/autoconf.mk
+
+DIRS = \
+  common \
+  data \
+  $(NULL)
+
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
-  bug471962_testpage_inner.sjs \
-  bug471962_testpage_outer.sjs \
   browser_bug471962.js \
   $(NULL)
 
 # browser_keyevents_during_autoscrolling.js cannot start the autoscrolling by
 # synthesizeMouse with middle button on linux, therefore, disable it temporarily
 ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 _BROWSER_FILES += browser_keyevents_during_autoscrolling.js
 endif
--- a/toolkit/content/tests/browser/browser_bug471962.js
+++ b/toolkit/content/tests/browser/browser_bug471962.js
@@ -29,297 +29,116 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-function test()
-{
-  const Cc = Components.classes;
-  const Ci = Components.interfaces;
-  const Cu = Components.utils;
-  const Cr = Components.results;
-  const Cm = Components.manager;
+/**
+ * Test for bug 471962 <https://bugzilla.mozilla.org/show_bug.cgi?id=471962>:
+ * When saving an inner frame as file only, the POST data of the outer page is
+ * sent to the address of the inner page.
+ */
+function test() {
+
+  // --- Testing support library ---
 
-  Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+  // Import the toolkit test support library in the scope of the current test.
+  // This operation also defines the common constants Cc, Ci, Cu, Cr and Cm.
+  Components.classes["@mozilla.org/moz/jssubscript-loader;1"].
+   getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript(
+   "chrome://mochikit/content/browser/toolkit/content/tests/browser/common/_loadAll.js",
+   this);
 
-  // --- Mock nsIFilePicker implementation ---
+  // --- Test implementation ---
+
+  const kBaseUrl =
+        "http://localhost:8888/browser/toolkit/content/tests/browser/data/";
 
-  var componentRegistrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-
-  var originalFilePickerFactory;
-  var mockFilePickerFactory;
-  var destFile;
+  function FramePostData_TestGenerator() {
+    // Display the outer page, and wait for it to be loaded. Loading the URI
+    // doesn't generally raise any exception, but if an error page is
+    // displayed, an exception will occur later during the test.
+    gBrowser.addEventListener("pageshow", testRunner.continueTest, false);
+    gBrowser.loadURI(kBaseUrl + "post_form_outer.sjs");
+    yield;
+    gBrowser.removeEventListener("pageshow", testRunner.continueTest, false);
 
-  // Note: The original class name is platform-dependent, however it is not
-  // important that we restore the exact class name when we restore the
-  // original factory.
-  const kFilePickerCID = "{bd57cee8-1dd1-11b2-9fe7-95cf4709aea3}";
-  const kFilePickerContractID = "@mozilla.org/filepicker;1";
-  const kFilePickerPossibleClassName = "File Picker";
+    try {
+      // Submit the form in the outer page, then wait for both the outer
+      // document and the inner frame to be loaded again.
+      gBrowser.addEventListener("DOMContentLoaded",
+                                testRunner.continueAfterTwoEvents, false);
+      try {
+        gBrowser.contentDocument.getElementById("postForm").submit();
+        yield;
+      }
+      finally {
+        // Remove the event listener, even if an exception occurred for any
+        // reason (for example, the requested element does not exist). 
+        gBrowser.removeEventListener("DOMContentLoaded",
+                                     testRunner.continueAfterTwoEvents, false);
+      }
+
+      // Save a reference to the inner frame in the reloaded page for later.
+      var innerFrame = gBrowser.contentDocument.getElementById("innerFrame");
 
-  function registerMockFilePickerFactory() {
-    // This file picker implementation is tailored for this test and returns
-    // the file specified in destFile, and a filter index of kSaveAsType_URL.
-    // The file is overwritten if it exists.
-    var mockFilePicker = {
-      QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
-      init: function(aParent, aTitle, aMode) { },
-      appendFilters: function(aFilterMask) { },
-      appendFilter: function(aTitle, aFilter) { },
-      defaultString: "",
-      defaultExtension: "",
-      set filterIndex() { },
-      get filterIndex() {
-        return 1; // kSaveAsType_URL
-      },
-      displayDirectory: null,
-      get file() {
-        return destFile.clone();
-      },
-      get fileURL() {
-        return Cc["@mozilla.org/network/io-service;1"].
-               getService(Ci.nsIIOService).newFileURI(destFile);
-      },
-      get files() {
-        throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-      },
-      show: function() {
-        // Assume we overwrite the file if it exists
-        return (destFile.exists() ?
-                Ci.nsIFilePicker.returnReplace :
-                Ci.nsIFilePicker.returnOK);
+      // Submit the form in the inner page.
+      gBrowser.addEventListener("DOMContentLoaded",
+                                testRunner.continueTest, false);
+      try {
+        innerFrame.contentDocument.getElementById("postForm").submit();
+        yield;
       }
-    };
+      finally {
+        // Remove the event listener, even if an exception occurred for any
+        // reason (for example, the requested element does not exist). 
+        gBrowser.removeEventListener("DOMContentLoaded",
+                                     testRunner.continueTest, false);
+      }
 
-    mockFilePickerFactory = {
-      createInstance: function(aOuter, aIid) {
-        if (aOuter != null)
-          throw Cr.NS_ERROR_NO_AGGREGATION;
-        return mockFilePicker.QueryInterface(aIid);
-      }
-    };
-
-    // Preserve the original factory
-    originalFilePickerFactory = Cm.getClassObject(Cc[kFilePickerContractID],
-                                                  Ci.nsIFactory);
+      // Create the folder the page will be saved into.
+      var destDir = createTemporarySaveDirectory();
+      try {
+        // Call the appropriate save function defined in contentAreaUtils.js.
+        mockFilePickerSettings.destDir = destDir;
+        mockFilePickerSettings.filterIndex = 1; // kSaveAsType_URL
+        callSaveWithMockObjects(function() {
+          var docToSave = innerFrame.contentDocument;
+          // We call internalSave instead of saveDocument to bypass the history
+          // cache.
+          internalSave(docToSave.location.href, docToSave, null, null,
+                       docToSave.contentType, false, null, null,
+                       docToSave.referrer ? makeURI(docToSave.referrer) : null,
+                       false, null);
+        });
 
-    // Register the mock factory
-    componentRegistrar.registerFactory(
-      Components.ID(kFilePickerCID),
-      "Mock File Picker Implementation",
-      kFilePickerContractID,
-      mockFilePickerFactory
-    );
-  }
+        // Wait for the download to finish, and exit if it wasn't successful.
+        var downloadSuccess = yield;
+        if (!downloadSuccess)
+          throw "Unexpected failure, the inner frame couldn't be saved!";
+
+        // Read the entire saved file.
+        var fileContents = readShortFile(mockFilePickerResults.selectedFile);
 
-  function unregisterMockFilePickerFactory() {
-    // Free references to the mock factory
-    componentRegistrar.unregisterFactory(
-      Components.ID(kFilePickerCID),
-      mockFilePickerFactory
-    );
-
-    // Restore the original factory
-    componentRegistrar.registerFactory(
-      Components.ID(kFilePickerCID),
-      kFilePickerPossibleClassName,
-      kFilePickerContractID,
-      originalFilePickerFactory
-    );
+        // Check if outer POST data is found.
+        const searchPattern = "inputfield=outer";
+        ok(fileContents.indexOf(searchPattern) === -1,
+           "The saved inner frame does not contain outer POST data");
+      }
+      finally {
+        // Clean up the saved file.
+        destDir.remove(true);
+      }
+    }
+    finally {
+      // Replace the current tab with a clean one.
+      gBrowser.addTab();
+      gBrowser.removeCurrentTab();
+    }
   }
 
-  // --- Mock nsITransfer implementation ---
-
-  var originalTransferFactory;
-  var mockTransferFactory;
-  var downloadIsSuccessful = true;
-
-  const kDownloadCID = "{e3fa9d0a-1dd1-11b2-bdef-8c720b597445}";
-  const kTransferContractID = "@mozilla.org/transfer;1";
-  const kDownloadClassName = "Download";
-
-  function registerMockTransferFactory() {
-    // This "transfer" object implementation is tailored for this test, and
-    // continues the test when the download is completed.
-    var mockTransfer = {
-      QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
-                                             Ci.nsIWebProgressListener2,
-                                             Ci.nsITransfer]),
-
-      // --- nsIWebProgressListener interface functions ---
-
-      onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
-        // If at least one notification reported an error, the download failed
-        if (aStatus != Cr.NS_OK)
-          downloadIsSuccessful = false;
-
-        // If the download is finished
-        if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
-            (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK))
-          // Continue the test, reporting the success or failure condition
-          onDownloadFinished(downloadIsSuccessful);
-      },
-      onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress,
-       aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) { },
-      onLocationChange: function(aWebProgress, aRequest, aLocation) { },
-      onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {
-        // If at least one notification reported an error, the download failed
-        if (aStatus != Cr.NS_OK)
-          downloadIsSuccessful = false;
-      },
-      onSecurityChange: function(aWebProgress, aRequest, aState) { },
-
-      // --- nsIWebProgressListener2 interface functions ---
-
-      onProgressChange64: function(aWebProgress, aRequest, aCurSelfProgress,
-       aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) { },
-      onRefreshAttempted: function(aWebProgress, aRefreshURI, aMillis,
-       aSameURI) { },
-
-      // --- nsITransfer interface functions ---
-
-      init: function(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime,
-       aTempFile, aCancelable) { }
-    };
-
-    mockTransferFactory = {
-      createInstance: function(aOuter, aIid) {
-        if (aOuter != null)
-          throw Cr.NS_ERROR_NO_AGGREGATION;
-        return mockTransfer.QueryInterface(aIid);
-      }
-    };
-
-    // Preserve the original factory
-    originalTransferFactory = Cm.getClassObject(Cc[kTransferContractID],
-                                                Ci.nsIFactory);
-
-    // Register the mock factory
-    componentRegistrar.registerFactory(
-      Components.ID(kDownloadCID),
-      "Mock Transfer Implementation",
-      kTransferContractID,
-      mockTransferFactory
-    );
-  }
-
-  function unregisterMockTransferFactory() {
-    // Free references to the mock factory
-    componentRegistrar.unregisterFactory(
-      Components.ID(kDownloadCID),
-      mockTransferFactory
-    );
-
-    // Restore the original factory
-    componentRegistrar.registerFactory(
-      Components.ID(kDownloadCID),
-      kDownloadClassName,
-      kTransferContractID,
-      originalTransferFactory
-    );
-  }
-
-  // --- Test procedure ---
-
-  var innerFrame;
+  // --- Run the test ---
 
-  function startTest() {
-    waitForExplicitFinish();
-
-    // Display the outer page
-    gBrowser.addEventListener("pageshow", onPageShow, false);
-    gBrowser.loadURI("http://localhost:8888/browser/toolkit/content/tests/browser/bug471962_testpage_outer.sjs");
-  }
-
-  function onPageShow() {
-    gBrowser.removeEventListener("pageshow", onPageShow, false);
-
-    // Submit the form in the outer page, then wait for both the outer
-    //  document and the inner frame to be loaded again
-    gBrowser.addEventListener("DOMContentLoaded", waitForTwoReloads, false);
-    gBrowser.contentDocument.getElementById("postForm").submit();
-  }
-
-  var isFirstReload = true;
-
-  function waitForTwoReloads() {
-    // The first time this function is called, do nothing
-    if (isFirstReload) {
-      isFirstReload = false;
-      return;
-    }
-
-    // The second time, go on with the normal test flow
-    gBrowser.removeEventListener("DOMContentLoaded", waitForTwoReloads, false);
-
-    // Save a reference to the inner frame in the reloaded page for later
-    innerFrame = gBrowser.contentDocument.getElementById("innerFrame");
-
-    // Submit the form in the inner page
-    gBrowser.addEventListener("DOMContentLoaded", onInnerSubmitted, false);
-    innerFrame.contentDocument.getElementById("postForm").submit();
-  }
-
-  function onInnerSubmitted() {
-    gBrowser.removeEventListener("DOMContentLoaded", onInnerSubmitted, false);
-
-    // Determine the path where the inner page will be saved
-    destFile = Cc["@mozilla.org/file/directory_service;1"].
-     getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
-    destFile.append("testsave_bug471962.html");
-
-    // Call the internal save function defined in contentAreaUtils.js, while
-    // replacing the file picker component with a mock implementation that
-    // returns the path of the temporary file, and the download component with
-    // an implementation that does not depend on the download manager
-    registerMockFilePickerFactory();
-    registerMockTransferFactory();
-    var docToSave = innerFrame.contentDocument;
-    // We call internalSave instead of saveDocument to bypass the history cache
-    internalSave(docToSave.location.href, docToSave, null, null,
-                 docToSave.contentType, false, null, null,
-                 docToSave.referrer ? makeURI(docToSave.referrer) : null,
-                 false, null);
-    unregisterMockTransferFactory();
-    unregisterMockFilePickerFactory();
-  }
-
-  function onDownloadFinished(aSuccess) {
-    // Abort the test if the download wasn't successful
-    if (!aSuccess) {
-      ok(false, "Unexpected failure, the inner frame couldn't be saved!");
-      finish();
-      return;
-    }
-
-    // Read the entire file
-    var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
-                      createInstance(Ci.nsIFileInputStream);
-    inputStream.init(destFile, -1, 0, 0);
-    var scrInputStream = Cc["@mozilla.org/scriptableinputstream;1"].
-                         createInstance(Ci.nsIScriptableInputStream);
-    scrInputStream.init(inputStream);
-    var fileContents = scrInputStream.
-                       read(1048576); // The file is much shorter than 1 MB
-    scrInputStream.close();
-    inputStream.close();
-
-    // Check if outer POST data is found
-    const searchPattern = "inputfield=outer";
-    ok(fileContents.indexOf(searchPattern) === -1,
-       "The saved inner frame does not contain outer POST data");
-
-    // Replace the current tab with a clean one
-    gBrowser.addTab();
-    gBrowser.removeCurrentTab();
-
-    // Clean up and exit
-    destFile.remove(false);
-    finish();
-  }
-
-  // Start the test now that all the inner functions are defined
-  startTest();
+  testRunner.runTest(FramePostData_TestGenerator);
 }
copy from toolkit/content/tests/browser/Makefile.in
copy to toolkit/content/tests/browser/common/Makefile.in
--- a/toolkit/content/tests/browser/Makefile.in
+++ b/toolkit/content/tests/browser/common/Makefile.in
@@ -30,31 +30,29 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH          = ../../../..
+DEPTH          = ../../../../..
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
-relativesrcdir = toolkit/content/tests/browser
+relativesrcdir = toolkit/content/tests/browser/common
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-_BROWSER_FILES = \
-  bug471962_testpage_inner.sjs \
-  bug471962_testpage_outer.sjs \
-  browser_bug471962.js \
+# If you add files here, add them to "_loadAll.js" too.
+_COMMON_FILES = \
+  _loadAll.js \
+  mockFilePicker.js \
+  mockObjects.js \
+  mockTransferForContinuing.js \
+  testRunner.js \
+  toolkitFunctions.js \
   $(NULL)
 
-# browser_keyevents_during_autoscrolling.js cannot start the autoscrolling by
-# synthesizeMouse with middle button on linux, therefore, disable it temporarily
-ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-_BROWSER_FILES += browser_keyevents_during_autoscrolling.js
-endif
-
-libs:: $(_BROWSER_FILES)
+libs:: $(_COMMON_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/common/_loadAll.js
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XUL Toolkit Testing Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Paolo Amadini <http://www.amadzone.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This file loads the entire library of testing objects and functions.
+ */
+
+// Define the shortcuts required by the included files.
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+const Cm = Components.manager;
+
+// Execute the following code while keeping the current scope clean.
+void(function (scriptScope) {
+  const kBaseUrl =
+    "chrome://mochikit/content/browser/toolkit/content/tests/browser/common/";
+
+  // If you add files here, add them to "Makefile.in" too.
+  var scriptNames = [
+    "mockObjects.js",
+    "testRunner.js",
+
+    // To be included after the files above.
+    "mockFilePicker.js",
+    "mockTransferForContinuing.js",
+    "toolkitFunctions.js",
+  ];
+
+  // Include all the required scripts.
+  var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+                     getService(Ci.mozIJSSubScriptLoader);
+  for (let [, scriptName] in Iterator(scriptNames)) {
+    // Ensure that the subscript is loaded in the scope where this script is
+    // being executed, which is not necessarily the global scope.
+    scriptLoader.loadSubScript(kBaseUrl + scriptName, scriptScope);
+  }
+}(this));
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/common/mockFilePicker.js
@@ -0,0 +1,116 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XUL Toolkit Testing Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Paolo Amadini <http://www.amadzone.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+var mockFilePickerSettings = {
+  /**
+   * File object pointing to the directory where the files will be saved.
+   * The files will be saved with the default name, and will be overwritten
+   * if they exist.
+   */
+  destDir: null,
+
+  /**
+   * Index of the filter to be returned by the file picker, or -1 to return
+   * the filter proposed by the caller.
+   */
+  filterIndex: -1
+};
+
+var mockFilePickerResults = {
+  /**
+   * File object corresponding to the last automatically selected file.
+   */
+  selectedFile: null,
+
+  /**
+   * Index of the filter that was set on the file picker by the caller.
+   */
+  proposedFilterIndex: -1
+};
+
+/**
+ * This file picker implementation uses the global settings defined in
+ * mockFilePickerSettings, and updates the mockFilePickerResults object
+ * when its "show" method is called.
+ */
+function MockFilePicker() { };
+MockFilePicker.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
+  init: function(aParent, aTitle, aMode) { },
+  appendFilters: function(aFilterMask) { },
+  appendFilter: function(aTitle, aFilter) { },
+  defaultString: "",
+  defaultExtension: "",
+  filterIndex: 0,
+  displayDirectory: null,
+  file: null,
+  get fileURL() {
+    return Cc["@mozilla.org/network/io-service;1"].
+           getService(Ci.nsIIOService).newFileURI(this.file);
+  },
+  get files() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  show: function MFP_show() {
+    // Select the destination file with the specified default file name. If the
+    // default file name was never specified or was set to an empty string by
+    // the caller, ensure that a fallback file name is used.
+    this.file = mockFilePickerSettings.destDir.clone();
+    this.file.append(this.defaultString || "no_default_file_name");
+    // Store the current file picker settings for testing them later.
+    mockFilePickerResults.selectedFile = this.file.clone();
+    mockFilePickerResults.proposedFilterIndex = this.filterIndex;
+    // Select a different file filter if required.
+    if (mockFilePickerSettings.filterIndex != -1)
+      this.filterIndex = mockFilePickerSettings.filterIndex;
+    // Assume we overwrite the file if it exists.
+    return (this.file.exists() ?
+            Ci.nsIFilePicker.returnReplace :
+            Ci.nsIFilePicker.returnOK);
+  }
+};
+
+// Create an instance of a MockObjectRegisterer whose methods can be used to
+// temporarily replace the default "@mozilla.org/filepicker;1" object factory
+// with one that provides the mock implementation above. To activate the mock
+// object factory, call the "register" method. Starting from that moment, all
+// the file picker objects that are requested will be mock objects, until the
+// "unregister" method is called.
+var mockFilePickerRegisterer =
+  new MockObjectRegisterer("@mozilla.org/filepicker;1",
+                           MockFilePicker);
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/common/mockObjects.js
@@ -0,0 +1,130 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XUL Toolkit Testing Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Paolo Amadini <http://www.amadzone.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Allows registering a mock XPCOM component, that temporarily replaces the
+ *  original one when an object implementing a given ContractID is requested
+ *  using createInstance.
+ *
+ * @param aContractID
+ *        The ContractID of the component to replace, for example
+ *        "@mozilla.org/filepicker;1".
+ *
+ * @param aReplacementCtor
+ *        The constructor function for the JavaScript object that will be
+ *        created every time createInstance is called. This object must
+ *        implement QueryInterface and provide the XPCOM interfaces required by
+ *        the specified ContractID (for example
+ *        Components.interfaces.nsIFilePicker).
+ */
+function MockObjectRegisterer(aContractID, aReplacementCtor)
+{
+  this._contractID = aContractID;
+  this._replacementCtor = aReplacementCtor;
+}
+
+MockObjectRegisterer.prototype = {
+  /**
+   * Replaces the current factory with one that returns a new mock object.
+   *
+   * After register() has been called, it is mandatory to call unregister() to
+   * restore the original component. Usually, you should use a try-catch block
+   * to ensure that unregister() is called.
+   */
+  register: function MOR_register() {
+    if (this._originalFactory)
+      throw new Exception("Invalid object state when calling register()");
+
+    // Define a factory that creates a new object using the given constructor.
+    var providedConstructor = this._replacementCtor;
+    this._mockFactory = {
+      createInstance: function MF_createInstance(aOuter, aIid) {
+        if (aOuter != null)
+          throw Cr.NS_ERROR_NO_AGGREGATION;
+        return new providedConstructor().QueryInterface(aIid);
+      }
+    };
+
+    // Preserve the original factory.
+    this._originalFactory = Cm.getClassObjectByContractID(this._contractID,
+                                                          Ci.nsIFactory);
+
+    // Replace the original factory with the mock one.
+    var classInfo = this._originalFactory.QueryInterface(Ci.nsIClassInfo);
+    var componentRegistrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    componentRegistrar.registerFactory(classInfo.classID,
+                                       "Mock " + classInfo.classDescription,
+                                       this._contractID,
+                                       this._mockFactory);
+  },
+
+  /**
+   * Restores the original factory.
+   */
+  unregister: function MOR_unregister() {
+    if (!this._originalFactory)
+      throw new Exception("Invalid object state when calling unregister()");
+
+    // Free references to the mock factory.
+    var classInfo = this._originalFactory.QueryInterface(Ci.nsIClassInfo);
+    var componentRegistrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    componentRegistrar.unregisterFactory(classInfo.classID,
+                                         this._mockFactory);
+
+    // Restore the original factory.
+    componentRegistrar.registerFactory(classInfo.classID,
+                                       classInfo.classDescription,
+                                       this._contractID,
+                                       this._originalFactory);
+
+    // Allow registering a mock factory again later.
+    this._originalFactory = null;
+    this._mockFactory = null;
+  },
+
+  // --- Private methods and properties ---
+
+  /**
+   * The original nsIFactory for the component being replaced, or null when the
+   *  original component is in place.
+   */
+  _originalFactory: null,
+
+  /**
+   * The nsIFactory that was automatically generated by this object.
+   */
+  _mockFactory: null
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/common/mockTransferForContinuing.js
@@ -0,0 +1,107 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XUL Toolkit Testing Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Paolo Amadini <http://www.amadzone.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+/**
+ * This "transfer" object implementation continues the currently running test
+ * when the download is completed, reporting true for success or false for
+ * failure as the first argument of the testRunner.continueTest function.
+ */
+function MockTransferForContinuing()
+{
+  this._downloadIsSuccessful = true;
+}
+
+MockTransferForContinuing.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([
+    Ci.nsIWebProgressListener,
+    Ci.nsIWebProgressListener2,
+    Ci.nsITransfer,
+  ]),
+
+  //////////////////////////////////////////////////////////////////////////////
+  //// nsIWebProgressListener
+
+  onStateChange: function MTFC_onStateChange(aWebProgress, aRequest,
+                                             aStateFlags, aStatus) {
+    // If at least one notification reported an error, the download failed.
+    if (!Components.isSuccessCode(aStatus))
+      this._downloadIsSuccessful = false;
+
+    // If the download is finished
+    if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
+        (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK))
+      // Continue the test, reporting the success or failure condition.
+      testRunner.continueTest(this._downloadIsSuccessful);
+  },
+  onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress,
+                             aMaxSelfProgress, aCurTotalProgress,
+                             aMaxTotalProgress) { },
+  onLocationChange: function(aWebProgress, aRequest, aLocation) { },
+  onStatusChange: function MTFC_onStatusChange(aWebProgress, aRequest, aStatus,
+                                               aMessage) {
+    // If at least one notification reported an error, the download failed.
+    if (!Components.isSuccessCode(aStatus))
+      this._downloadIsSuccessful = false;
+  },
+  onSecurityChange: function(aWebProgress, aRequest, aState) { },
+
+  //////////////////////////////////////////////////////////////////////////////
+  //// nsIWebProgressListener2
+
+  onProgressChange64: function(aWebProgress, aRequest, aCurSelfProgress,
+                               aMaxSelfProgress, aCurTotalProgress,
+                               aMaxTotalProgress) { },
+  onRefreshAttempted: function(aWebProgress, aRefreshURI, aMillis,
+                               aSameURI) { },
+
+  //////////////////////////////////////////////////////////////////////////////
+  //// nsITransfer
+
+  init: function(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime,
+                 aTempFile, aCancelable) { }
+};
+
+// Create an instance of a MockObjectRegisterer whose methods can be used to
+// temporarily replace the default "@mozilla.org/transfer;1" object factory with
+// one that provides the mock implementation above. To activate the mock object
+// factory, call the "register" method. Starting from that moment, all the
+// transfer objects that are requested will be mock objects, until the
+// "unregister" method is called.
+var mockTransferForContinuingRegisterer =
+  new MockObjectRegisterer("@mozilla.org/transfer;1",
+                           MockTransferForContinuing);
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/common/testRunner.js
@@ -0,0 +1,171 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XUL Toolkit Testing Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Paolo Amadini <http://www.amadzone.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Runs a browser-chrome test defined through a generator function.
+ *
+ * This object is a singleton, initialized automatically when this script is
+ * included. Every browser-chrome test file includes a new copy of this script.
+ */
+var testRunner = {
+  _testIterator: null,
+  _lastEventResult: undefined,
+  _testRunning: false,
+  _eventRaised: false,
+
+  // --- Main test runner ---
+
+  /**
+   * Runs the test described by the provided generator function asynchronously.
+   *
+   * Calling yield in the generator will cause it to wait until continueTest is
+   * called. The parameter provided to continueTest will be the return value of
+   * the yield operator.
+   *
+   * @param aGenerator
+   *        Test generator function. The function will be called with no
+   *        arguments to retrieve its iterator.
+   */
+  runTest: function TR_runTest(aGenerator) {
+    waitForExplicitFinish();
+    testRunner._testIterator = aGenerator();
+    testRunner.continueTest();
+  },
+
+  /**
+   * Continues the currently running test.
+   *
+   * @param aEventResult
+   *        This will be the return value of the yield operator in the test.
+   */
+  continueTest: function TR_continueTest(aEventResult) {
+    // Store the last event result, or set it to undefined.
+    testRunner._lastEventResult = aEventResult;
+
+    // Never reenter the main loop, but notify that the event has been raised.
+    if (testRunner._testRunning) {
+      testRunner._eventRaised = true;
+      return;
+    }
+
+    // Enter the main iteration loop.
+    testRunner._testRunning = true;
+    try {
+      do {
+        // Call the iterator, but don't leave the loop if the expected event is
+        // raised during the execution of the generator.
+        testRunner._eventRaised = false;
+        testRunner._testIterator.send(testRunner._lastEventResult);
+      } while (testRunner._eventRaised);
+    }
+    catch (e) {
+      // This block catches exceptions raised by the generator, including the
+      // normal StopIteration exception. Unexpected exceptions are reported as
+      // test failures.
+      if (!(e instanceof StopIteration))
+        ok(false, e);
+      // In any case, stop the tests in this file.
+      finish();
+    }
+
+    // Wait for the next event or finish.
+    testRunner._testRunning = false;
+  },
+
+  // --- Auxiliary functions ---
+
+  _isFirstEvent: true,
+
+  /**
+   * Continues the running test every second time this function is called.
+   */
+  continueAfterTwoEvents: function TR_continueAfterTwoEvents() {
+    if (testRunner._isFirstEvent) {
+      testRunner._isFirstEvent = false;
+      return;
+    }
+    testRunner._isFirstEvent = true;
+    testRunner.continueTest();
+  },
+
+  // --- Support for multiple tests ---
+
+  /**
+   * This generator function yields each value obtained by the given generators,
+   * in the order they are specified in the array.
+   *
+   * @param aArrayOfGenerators
+   *        Array of generator functions. The functions will be called with no
+   *        arguments to retrieve their iterators.
+   *
+   * @return
+   *        The iterator generated by this generator function.
+   */
+  chainGenerator: function TR_chainGenerator(aArrayOfGenerators) {
+    // Obtain each iterator in turn.
+    for (let [, curGenerator] in Iterator(aArrayOfGenerators)) {
+      var curIterator = curGenerator();
+      // Call each iterator until it completes, while ensuring propagation of
+      // both the the values provided to and returned by the yield operator.
+      try {
+        var value = undefined;
+        while (true) {
+          value = yield curIterator.send(value);
+        }
+      }
+      catch(e if e instanceof StopIteration) {
+        // The iterator has finished providing all the values.
+      }
+    }
+  },
+
+  /**
+   * Runs multiple tests.
+   *
+   * This function operates asynchronously. Because of this, it should be called
+   * by the last line of a test script.
+   *
+   * @param aArrayOfTestGenerators
+   *        Array containing references to the test generator functions to run.
+   *
+   * @see #runTest
+   */
+  runTests: function TR_runTests(aArrayOfTestGenerators) {
+    testRunner.runTest(function() {
+      return testRunner.chainGenerator(aArrayOfTestGenerators);
+    });
+  }
+};
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/browser/common/toolkitFunctions.js
@@ -0,0 +1,114 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla XUL Toolkit Testing Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Paolo Amadini <http://www.amadzone.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Provides a temporary save directory.
+ *
+ * @return
+ *        nsIFile pointing to the new or existing directory.
+ */
+function createTemporarySaveDirectory() {
+  var saveDir = Cc["@mozilla.org/file/directory_service;1"].
+                getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
+  saveDir.append("testsavedir");
+  if (!saveDir.exists())
+    saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
+  return saveDir;
+}
+
+/**
+ * Calls the provided save function while replacing the file picker component
+ * with a mock implementation that returns a temporary file path and custom
+ * filters, and the download component with an implementation that does not
+ * depend on the download manager.
+ *
+ * @param aSaveFunction
+ *        The function to call. This is usually the subject of the entire test
+ *        being run.
+ */
+function callSaveWithMockObjects(aSaveFunction) {
+  // Call the provided function while the mock object factories are in place and
+  // ensure that, even in case of exceptions during the function's execution,
+  // the mock object factories are unregistered before proceeding with the other
+  // tests in the suite.
+  mockFilePickerRegisterer.register();
+  try {
+    mockTransferForContinuingRegisterer.register();
+    try {
+      aSaveFunction();
+    }
+    finally {
+      mockTransferForContinuingRegisterer.unregister();
+    }
+  }
+  finally {
+    mockFilePickerRegisterer.unregister();
+  }
+}
+
+/**
+ * Reads the contents of the provided short file (up to 1 MiB).
+ *
+ * @param aFile
+ *        nsIFile object pointing to the file to be read.
+ *
+ * @return
+ *        String containing the raw octets read from the file.
+ */
+function readShortFile(aFile) {
+  var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
+                    createInstance(Ci.nsIFileInputStream);
+  inputStream.init(aFile, -1, 0, 0);
+  try {
+    var scrInputStream = Cc["@mozilla.org/scriptableinputstream;1"].
+                         createInstance(Ci.nsIScriptableInputStream);
+    scrInputStream.init(inputStream);
+    try {
+      // Assume that the file is much shorter than 1 MiB.
+      return scrInputStream.read(1048576);
+    }
+    finally {
+      // Close the scriptable stream after reading, even if the operation
+      // failed.
+      scrInputStream.close();
+    }
+  }
+  finally {
+    // Close the stream after reading, if it is still open, even if the read
+    // operation failed.
+    inputStream.close();
+  }
+}
copy from toolkit/content/tests/browser/Makefile.in
copy to toolkit/content/tests/browser/data/Makefile.in
--- a/toolkit/content/tests/browser/Makefile.in
+++ b/toolkit/content/tests/browser/data/Makefile.in
@@ -30,31 +30,24 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH          = ../../../..
+DEPTH          = ../../../../..
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
-relativesrcdir = toolkit/content/tests/browser
+relativesrcdir = toolkit/content/tests/browser/data
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-_BROWSER_FILES = \
-  bug471962_testpage_inner.sjs \
-  bug471962_testpage_outer.sjs \
-  browser_bug471962.js \
+_DATA_FILES = \
+  post_form_inner.sjs \
+  post_form_outer.sjs \
   $(NULL)
 
-# browser_keyevents_during_autoscrolling.js cannot start the autoscrolling by
-# synthesizeMouse with middle button on linux, therefore, disable it temporarily
-ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-_BROWSER_FILES += browser_keyevents_during_autoscrolling.js
-endif
-
-libs:: $(_BROWSER_FILES)
+libs:: $(_DATA_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
rename from toolkit/content/tests/browser/bug471962_testpage_inner.sjs
rename to toolkit/content/tests/browser/data/post_form_inner.sjs
--- a/toolkit/content/tests/browser/bug471962_testpage_inner.sjs
+++ b/toolkit/content/tests/browser/data/post_form_inner.sjs
@@ -48,17 +48,17 @@ function handleRequest(request, response
     Inner POST data: ';
 
   var bodyStream = new BinaryInputStream(request.bodyInputStream);
   var bytes = [], avail = 0;
   while ((avail = bodyStream.available()) > 0)
    body += String.fromCharCode.apply(String, bodyStream.readByteArray(avail));
 
   body +=
-    '<form id="postForm" action="bug471962_testpage_inner.sjs" method="post">\
+    '<form id="postForm" action="post_form_inner.sjs" method="post">\
      <input type="text" name="inputfield" value="inner">\
      <input type="submit">\
      </form>\
      </body>\
      </html>';
 
   response.bodyOutputStream.write(body, body.length);
 }
rename from toolkit/content/tests/browser/bug471962_testpage_outer.sjs
rename to toolkit/content/tests/browser/data/post_form_outer.sjs
--- a/toolkit/content/tests/browser/bug471962_testpage_outer.sjs
+++ b/toolkit/content/tests/browser/data/post_form_outer.sjs
@@ -48,20 +48,20 @@ function handleRequest(request, response
     Outer POST data: ';
 
   var bodyStream = new BinaryInputStream(request.bodyInputStream);
   var bytes = [], avail = 0;
   while ((avail = bodyStream.available()) > 0)
    body += String.fromCharCode.apply(String, bodyStream.readByteArray(avail));
 
   body +=
-    '<form id="postForm" action="bug471962_testpage_outer.sjs" method="post">\
+    '<form id="postForm" action="post_form_outer.sjs" method="post">\
      <input type="text" name="inputfield" value="outer">\
      <input type="submit">\
      </form>\
      \
-     <iframe id="innerFrame" src="bug471962_testpage_inner.sjs" width="400" height="200">\
+     <iframe id="innerFrame" src="post_form_inner.sjs" width="400" height="200">\
      \
      </body>\
      </html>';
 
   response.bodyOutputStream.write(body, body.length);
 }