Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace(
);
const TEST_PATH2 = getRootDirectory(gTestPath).replace(
);
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window.browsingContext);
registerCleanupFunction(async function () {
info("Running the cleanup code");
MockFilePicker.cleanup();
if (gTestDir && gTestDir.exists()) {
// On Windows, sometimes nsIFile.remove() throws, probably because we're
// still writing to the directory we're trying to remove, despite
// waiting for the download to complete. Just retry a bit later...
let succeeded = false;
while (!succeeded) {
try {
gTestDir.remove(true);
succeeded = true;
} catch (ex) {
await new Promise(requestAnimationFrame);
}
}
}
});
let gTestDir = null;
function createTemporarySaveDirectory() {
var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
saveDir.append("testsavedir");
if (!saveDir.exists()) {
saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
}
return saveDir;
}
function canonicalizeExtension(str) {
return str.replace(/\.htm$/, ".html");
}
function checkContents(dir, expected, str) {
let stack = [dir];
let files = [];
while (stack.length) {
for (let file of stack.pop().directoryEntries) {
if (file.isDirectory()) {
stack.push(file);
}
let path = canonicalizeExtension(file.getRelativePath(dir));
files.push(path);
}
}
SimpleTest.isDeeply(
files.sort(),
expected.sort(),
str + "Should contain downloaded files in correct place."
);
}
async function addFrame(browser, path, selector) {
await SpecialPowers.spawn(
browser,
[path, selector],
async function (path, selector) {
let document = content.document;
let target = document.querySelector(selector);
if (content.HTMLIFrameElement.isInstance(target)) {
document = target.contentDocument;
target = document.body;
}
let element = document.createElement("iframe");
element.src = path;
await new Promise(resolve => {
element.onload = resolve;
target.appendChild(element);
});
}
);
}
async function handleResult(expected, str) {
let dls = await Downloads.getList(Downloads.PUBLIC);
return new Promise((resolve, reject) => {
dls.addView({
onDownloadChanged(download) {
if (download.succeeded) {
checkContents(gTestDir, expected, str);
dls.removeView(this);
dls.removeFinished();
resolve();
} else if (download.error) {
reject("Download failed");
}
},
});
});
}
add_task(async function () {
await BrowserTestUtils.withNewTab(
TEST_PATH + "image.html",
async function (browser) {
await addFrame(browser, TEST_PATH + "image.html", "body");
await addFrame(browser, TEST_PATH2 + "image.html", "body>iframe");
gTestDir = createTemporarySaveDirectory();
MockFilePicker.displayDirectory = gTestDir;
MockFilePicker.showCallback = function () {
let destFile = gTestDir.clone();
destFile.append("first.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
let expected = [
"first.html",
"first_files",
"first_files/image.html",
"first_files/dummy.png",
"first_files/image_data",
"first_files/image_data/image.html",
"first_files/image_data/image_data",
"first_files/image_data/image_data/dummy.png",
];
// This saves the top-level document contained in `browser`
saveBrowser(browser);
await handleResult(expected, "Check toplevel: ");
// Instead of deleting previously saved files, we update our list
// of expected files for the next part of the test. To not clash
// we make sure to save to a different file name.
expected = expected.concat([
"second.html",
"second_files",
"second_files/dummy.png",
"second_files/image.html",
"second_files/image_data",
"second_files/image_data/dummy.png",
]);
MockFilePicker.showCallback = function () {
let destFile = gTestDir.clone();
destFile.append("second.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
// This saves the sub-document of the iframe contained in the
// top-level document, as indicated by passing a child browsing
// context as target for the save.
saveBrowser(browser, false, browser.browsingContext.children[0]);
await handleResult(expected, "Check subframe: ");
// Instead of deleting previously saved files, we update our list
// of expected files for the next part of the test. To not clash
// we make sure to save to a different file name.
expected = expected.concat([
"third.html",
"third_files",
"third_files/dummy.png",
]);
MockFilePicker.showCallback = function () {
let destFile = gTestDir.clone();
destFile.append("third.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
// This saves the sub-document of the iframe contained in the
// first sub-document, as indicated by passing a child browsing
// context as target for the save. That frame is special, because
// it's cross-process.
saveBrowser(
browser,
false,
browser.browsingContext.children[0].children[0]
);
await handleResult(expected, "Check subframe: ");
}
);
});