Bug 1576188 - Test that save-as works for cross process frames. r=peterv

Differential Revision: https://phabricator.services.mozilla.com/D70388
This commit is contained in:
Andreas Farre 2020-04-23 13:56:08 +00:00
parent b9c2dd1967
commit d7b660230f
4 changed files with 202 additions and 3 deletions

View File

@ -10,6 +10,7 @@ support-files =
worker_bug1004814.js
geo_leak_test.html
dummy.html
dummy.png
test_largeAllocation.html
test_largeAllocation.html^headers^
test_largeAllocation2.html
@ -71,12 +72,10 @@ skip-if =
support-files =
set-samesite-cookies-and-redirect.sjs
mimeme.sjs
skip-if = fission
[browser_persist_image_accept.js]
[browser_persist_mixed_content_image.js]
support-files =
test_mixed_content_image.html
dummy.png
[browser_pointerlock_warning.js]
[browser_test_focus_after_modal_state.js]
skip-if = verify
@ -109,3 +108,6 @@ skip-if = webrender
support-files =
file_postMessage_parent.html
[browser_navigate_replace_browsingcontext.js]
[browser_persist_cross_origin_iframe.js]
support-files =
image.html

View File

@ -98,7 +98,7 @@ add_task(async function() {
info("done showCallback");
};
saveBrowser(browser);
await new Promise(async resolve => {
await new Promise(async (resolve, reject) => {
let dls = await Downloads.getList(Downloads.PUBLIC);
dls.addView({
onDownloadChanged(download) {
@ -106,6 +106,8 @@ add_task(async function() {
dls.removeView(this);
dls.removeFinished();
resolve();
} else if (download.error) {
reject("Download failed");
}
},
});

View File

@ -0,0 +1,193 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.org"
);
const TEST_PATH2 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
);
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
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 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);
}
files.push(file.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 (target instanceof content.HTMLIFrameElement) {
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(fp) {
let destFile = gTestDir.clone();
destFile.append("first.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
let expected = [
"/tmp/testsavedir/first.html",
"/tmp/testsavedir/first_files",
"/tmp/testsavedir/first_files/image.html",
"/tmp/testsavedir/first_files/dummy.png",
"/tmp/testsavedir/first_files/image_data",
"/tmp/testsavedir/first_files/image_data/image.html",
"/tmp/testsavedir/first_files/image_data/image_data",
"/tmp/testsavedir/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([
"/tmp/testsavedir/second.html",
"/tmp/testsavedir/second_files",
"/tmp/testsavedir/second_files/dummy.png",
"/tmp/testsavedir/second_files/image.html",
"/tmp/testsavedir/second_files/image_data",
"/tmp/testsavedir/second_files/image_data/dummy.png",
]);
MockFilePicker.displayDirectory = gTestDir;
MockFilePicker.showCallback = function(fp) {
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([
"/tmp/testsavedir/third.html",
"/tmp/testsavedir/third_files",
"/tmp/testsavedir/third_files/dummy.png",
]);
MockFilePicker.displayDirectory = gTestDir;
MockFilePicker.showCallback = function(fp) {
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: ");
});
});

View File

@ -0,0 +1,2 @@
<!doctype html>
<img src="dummy.png"></img>