michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: var MockFilePicker = SpecialPowers.MockFilePicker; michael@0: MockFilePicker.init(window); michael@0: michael@0: /** michael@0: * Test for bug 471962 : michael@0: * When saving an inner frame as file only, the POST data of the outer page is michael@0: * sent to the address of the inner page. michael@0: * michael@0: * Test for bug 485196 : michael@0: * Web page generated by POST is retried as GET when Save Frame As used, and the michael@0: * page is no longer in the cache. michael@0: */ michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: michael@0: gBrowser.selectedTab = gBrowser.addTab(); michael@0: michael@0: gBrowser.loadURI("http://mochi.test:8888/browser/toolkit/content/tests/browser/data/post_form_outer.sjs"); michael@0: michael@0: registerCleanupFunction(function () { michael@0: gBrowser.removeCurrentTab(); michael@0: }); michael@0: michael@0: gBrowser.addEventListener("pageshow", function pageShown(event) { michael@0: if (event.target.location == "about:blank") michael@0: return; michael@0: gBrowser.removeEventListener("pageshow", pageShown); michael@0: michael@0: // Submit the form in the outer page, then wait for both the outer michael@0: // document and the inner frame to be loaded again. michael@0: gBrowser.addEventListener("DOMContentLoaded", handleOuterSubmit); michael@0: gBrowser.contentDocument.getElementById("postForm").submit(); michael@0: }); michael@0: michael@0: var framesLoaded = 0; michael@0: var innerFrame; michael@0: michael@0: function handleOuterSubmit() { michael@0: if (++framesLoaded < 2) michael@0: return; michael@0: michael@0: gBrowser.removeEventListener("DOMContentLoaded", handleOuterSubmit); michael@0: michael@0: innerFrame = gBrowser.contentDocument.getElementById("innerFrame"); michael@0: michael@0: // Submit the form in the inner page. michael@0: gBrowser.addEventListener("DOMContentLoaded", handleInnerSubmit); michael@0: innerFrame.contentDocument.getElementById("postForm").submit(); michael@0: } michael@0: michael@0: function handleInnerSubmit() { michael@0: gBrowser.removeEventListener("DOMContentLoaded", handleInnerSubmit); michael@0: michael@0: // Create the folder the page will be saved into. michael@0: var destDir = createTemporarySaveDirectory(); michael@0: var file = destDir.clone(); michael@0: file.append("no_default_file_name"); michael@0: MockFilePicker.returnFiles = [file]; michael@0: MockFilePicker.showCallback = function(fp) { michael@0: MockFilePicker.filterIndex = 1; // kSaveAsType_URL michael@0: }; michael@0: michael@0: mockTransferCallback = onTransferComplete; michael@0: mockTransferRegisterer.register(); michael@0: michael@0: registerCleanupFunction(function () { michael@0: mockTransferRegisterer.unregister(); michael@0: MockFilePicker.cleanup(); michael@0: destDir.remove(true); michael@0: }); michael@0: michael@0: var docToSave = innerFrame.contentDocument; michael@0: // We call internalSave instead of saveDocument to bypass the history michael@0: // cache. michael@0: internalSave(docToSave.location.href, docToSave, null, null, michael@0: docToSave.contentType, false, null, null, michael@0: docToSave.referrer ? makeURI(docToSave.referrer) : null, michael@0: docToSave, false, null); michael@0: } michael@0: michael@0: function onTransferComplete(downloadSuccess) { michael@0: ok(downloadSuccess, "The inner frame should have been downloaded successfully"); michael@0: michael@0: // Read the entire saved file. michael@0: var file = MockFilePicker.returnFiles[0]; michael@0: var fileContents = readShortFile(file); michael@0: michael@0: // Check if outer POST data is found (bug 471962). michael@0: is(fileContents.indexOf("inputfield=outer"), -1, michael@0: "The saved inner frame does not contain outer POST data"); michael@0: michael@0: // Check if inner POST data is found (bug 485196). michael@0: isnot(fileContents.indexOf("inputfield=inner"), -1, michael@0: "The saved inner frame was generated using the correct POST data"); michael@0: michael@0: finish(); michael@0: } michael@0: } michael@0: michael@0: Cc["@mozilla.org/moz/jssubscript-loader;1"] michael@0: .getService(Ci.mozIJSSubScriptLoader) michael@0: .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js", michael@0: this); michael@0: michael@0: function createTemporarySaveDirectory() { michael@0: var saveDir = Cc["@mozilla.org/file/directory_service;1"] michael@0: .getService(Ci.nsIProperties) michael@0: .get("TmpD", Ci.nsIFile); michael@0: saveDir.append("testsavedir"); michael@0: if (!saveDir.exists()) michael@0: saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); michael@0: return saveDir; michael@0: } michael@0: michael@0: /** michael@0: * Reads the contents of the provided short file (up to 1 MiB). michael@0: * michael@0: * @param aFile michael@0: * nsIFile object pointing to the file to be read. michael@0: * michael@0: * @return michael@0: * String containing the raw octets read from the file. michael@0: */ michael@0: function readShortFile(aFile) { michael@0: var inputStream = Cc["@mozilla.org/network/file-input-stream;1"] michael@0: .createInstance(Ci.nsIFileInputStream); michael@0: inputStream.init(aFile, -1, 0, 0); michael@0: try { michael@0: var scrInputStream = Cc["@mozilla.org/scriptableinputstream;1"] michael@0: .createInstance(Ci.nsIScriptableInputStream); michael@0: scrInputStream.init(inputStream); michael@0: try { michael@0: // Assume that the file is much shorter than 1 MiB. michael@0: return scrInputStream.read(1048576); michael@0: } michael@0: finally { michael@0: // Close the scriptable stream after reading, even if the operation michael@0: // failed. michael@0: scrInputStream.close(); michael@0: } michael@0: } michael@0: finally { michael@0: // Close the stream after reading, if it is still open, even if the read michael@0: // operation failed. michael@0: inputStream.close(); michael@0: } michael@0: }