summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js')
-rw-r--r--toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js532
1 files changed, 532 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js b/toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js
new file mode 100644
index 0000000000..22db484e16
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/browser_staticPartition_saveAs.js
@@ -0,0 +1,532 @@
+/**
+ * Bug 1641270 - A test case for ensuring the save channel will use the correct
+ * cookieJarSettings when doing the saving and the cache would
+ * work as expected.
+ */
+
+"use strict";
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
+ this
+);
+
+const TEST_IMAGE_URL = TEST_DOMAIN + TEST_PATH + "file_saveAsImage.sjs";
+const TEST_VIDEO_URL = TEST_DOMAIN + TEST_PATH + "file_saveAsVideo.sjs";
+const TEST_PAGEINFO_URL = TEST_DOMAIN + TEST_PATH + "file_saveAsPageInfo.html";
+
+let MockFilePicker = SpecialPowers.MockFilePicker;
+MockFilePicker.init(window);
+
+const tempDir = createTemporarySaveDirectory();
+MockFilePicker.displayDirectory = tempDir;
+
+function createTemporarySaveDirectory() {
+ let saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
+ saveDir.append("testsavedir");
+ saveDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+ return saveDir;
+}
+
+function createPromiseForTransferComplete(aDesirableFileName) {
+ return new Promise(resolve => {
+ MockFilePicker.showCallback = fp => {
+ info("MockFilePicker showCallback");
+
+ let fileName = fp.defaultString;
+ let destFile = tempDir.clone();
+ destFile.append(fileName);
+
+ if (aDesirableFileName) {
+ is(fileName, aDesirableFileName, "The default file name is correct.");
+ }
+
+ MockFilePicker.setFiles([destFile]);
+ MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
+
+ MockFilePicker.showCallback = null;
+ mockTransferCallback = function (downloadSuccess) {
+ ok(downloadSuccess, "File should have been downloaded successfully");
+ mockTransferCallback = () => {};
+ resolve();
+ };
+ };
+ });
+}
+
+function createPromiseForObservingChannel(aURL, aPartitionKey) {
+ return new Promise(resolve => {
+ let observer = (aSubject, aTopic) => {
+ if (aTopic === "http-on-modify-request") {
+ let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
+ let reqLoadInfo = httpChannel.loadInfo;
+
+ // Make sure this is the request which we want to check.
+ if (!httpChannel.URI.spec.endsWith(aURL)) {
+ return;
+ }
+
+ info(`Checking loadInfo for URI: ${httpChannel.URI.spec}\n`);
+ is(
+ reqLoadInfo.cookieJarSettings.partitionKey,
+ aPartitionKey,
+ "The loadInfo has the correct partition key"
+ );
+
+ Services.obs.removeObserver(observer, "http-on-modify-request");
+ resolve();
+ }
+ };
+
+ Services.obs.addObserver(observer, "http-on-modify-request");
+ });
+}
+
+add_setup(async function () {
+ info("Setting MockFilePicker.");
+ mockTransferRegisterer.register();
+
+ registerCleanupFunction(function () {
+ mockTransferRegisterer.unregister();
+ MockFilePicker.cleanup();
+ tempDir.remove(true);
+ });
+});
+
+add_task(async function testContextMenuSaveImage() {
+ let uuidGenerator = Services.uuid;
+
+ for (let networkIsolation of [true, false]) {
+ for (let partitionPerSite of [true, false]) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.network_state", networkIsolation],
+ ["privacy.dynamic_firstparty.use_site", partitionPerSite],
+ ],
+ });
+
+ // We use token to separate the caches.
+ let token = uuidGenerator.generateUUID().toString();
+ const testImageURL = `${TEST_IMAGE_URL}?token=${token}`;
+
+ info(`Open a new tab for testing "Save image as" in context menu.`);
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ TEST_TOP_PAGE
+ );
+
+ info(`Insert the testing image into the tab.`);
+ await SpecialPowers.spawn(
+ tab.linkedBrowser,
+ [testImageURL],
+ async url => {
+ let img = content.document.createElement("img");
+ let loaded = new content.Promise(resolve => {
+ img.onload = resolve;
+ });
+ content.document.body.appendChild(img);
+ img.setAttribute("id", "image1");
+ img.src = url;
+ await loaded;
+ }
+ );
+
+ info("Open the context menu.");
+ let popupShownPromise = BrowserTestUtils.waitForEvent(
+ document,
+ "popupshown"
+ );
+
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#image1",
+ {
+ type: "contextmenu",
+ button: 2,
+ },
+ tab.linkedBrowser
+ );
+
+ await popupShownPromise;
+
+ let partitionKey = partitionPerSite
+ ? "(http,example.net)"
+ : "example.net";
+
+ let transferCompletePromise = createPromiseForTransferComplete();
+ let observerPromise = createPromiseForObservingChannel(
+ testImageURL,
+ partitionKey
+ );
+
+ let saveElement = document.getElementById("context-saveimage");
+ info("Triggering the save process.");
+ saveElement.doCommand();
+
+ info("Waiting for the channel.");
+ await observerPromise;
+
+ info("Wait until the save is finished.");
+ await transferCompletePromise;
+
+ info("Close the context menu.");
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ let popupHiddenPromise = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popuphidden"
+ );
+ contextMenu.hidePopup();
+ await popupHiddenPromise;
+
+ // Check if there will be only one network request. The another one should
+ // be from cache.
+ let res = await fetch(`${TEST_IMAGE_URL}?token=${token}&result`);
+ let res_text = await res.text();
+ is(res_text, "1", "The image should be loaded only once.");
+
+ BrowserTestUtils.removeTab(tab);
+ }
+ }
+});
+
+add_task(async function testContextMenuSaveVideo() {
+ let uuidGenerator = Services.uuid;
+
+ for (let networkIsolation of [true, false]) {
+ for (let partitionPerSite of [true, false]) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.network_state", networkIsolation],
+ ["privacy.dynamic_firstparty.use_site", partitionPerSite],
+ ],
+ });
+
+ // We use token to separate the caches.
+ let token = uuidGenerator.generateUUID().toString();
+ const testVideoURL = `${TEST_VIDEO_URL}?token=${token}`;
+
+ info(`Open a new tab for testing "Save Video as" in context menu.`);
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ TEST_TOP_PAGE
+ );
+
+ info(`Insert the testing video into the tab.`);
+ await SpecialPowers.spawn(
+ tab.linkedBrowser,
+ [testVideoURL],
+ async url => {
+ let video = content.document.createElement("video");
+ let loaded = new content.Promise(resolve => {
+ video.onloadeddata = resolve;
+ });
+ content.document.body.appendChild(video);
+ video.setAttribute("id", "video1");
+ video.src = url;
+ await loaded;
+ }
+ );
+
+ info("Open the context menu.");
+ let popupShownPromise = BrowserTestUtils.waitForEvent(
+ document,
+ "popupshown"
+ );
+
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#video1",
+ {
+ type: "contextmenu",
+ button: 2,
+ },
+ tab.linkedBrowser
+ );
+
+ await popupShownPromise;
+
+ let partitionKey = partitionPerSite
+ ? "(http,example.net)"
+ : "example.net";
+
+ // We also check the default file name, see Bug 1679325.
+ let transferCompletePromise = createPromiseForTransferComplete(
+ "file_saveAsVideo.webm"
+ );
+ let observerPromise = createPromiseForObservingChannel(
+ testVideoURL,
+ partitionKey
+ );
+
+ let saveElement = document.getElementById("context-savevideo");
+ info("Triggering the save process.");
+ saveElement.doCommand();
+
+ info("Waiting for the channel.");
+ await observerPromise;
+
+ info("Wait until the save is finished.");
+ await transferCompletePromise;
+
+ info("Close the context menu.");
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ let popupHiddenPromise = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popuphidden"
+ );
+ contextMenu.hidePopup();
+ await popupHiddenPromise;
+
+ // Check if there will be only one network request. The another one should
+ // be from cache.
+ let res = await fetch(`${TEST_VIDEO_URL}?token=${token}&result`);
+ let res_text = await res.text();
+ is(res_text, "1", "The video should be loaded only once.");
+
+ BrowserTestUtils.removeTab(tab);
+ }
+ }
+});
+
+add_task(async function testSavePageInOfflineMode() {
+ for (let networkIsolation of [true, false]) {
+ for (let partitionPerSite of [true, false]) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.network_state", networkIsolation],
+ ["privacy.dynamic_firstparty.use_site", partitionPerSite],
+ ],
+ });
+
+ let partitionKey = partitionPerSite
+ ? "(http,example.net)"
+ : "example.net";
+
+ info(`Open a new tab which loads an image`);
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ TEST_IMAGE_URL
+ );
+
+ info("Toggle on the offline mode");
+ BrowserOffline.toggleOfflineStatus();
+
+ info("Open file menu and trigger 'Save Page As'");
+ let menubar = document.getElementById("main-menubar");
+ let filePopup = document.getElementById("menu_FilePopup");
+
+ // We only use the shortcut keys to open the file menu in Windows and Linux.
+ // Mac doesn't have a shortcut to only open the file menu. Instead, we directly
+ // trigger the save in MAC without any UI interactions.
+ if (Services.appinfo.OS !== "Darwin") {
+ let menubarActive = BrowserTestUtils.waitForEvent(
+ menubar,
+ "DOMMenuBarActive"
+ );
+ EventUtils.synthesizeKey("KEY_F10");
+ await menubarActive;
+
+ let popupShownPromise = BrowserTestUtils.waitForEvent(
+ filePopup,
+ "popupshown"
+ );
+ // In window, it still needs one extra down key to open the file menu.
+ if (Services.appinfo.OS === "WINNT") {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+ await popupShownPromise;
+ }
+
+ let transferCompletePromise = createPromiseForTransferComplete();
+ let observerPromise = createPromiseForObservingChannel(
+ TEST_IMAGE_URL,
+ partitionKey
+ );
+
+ info("Triggering the save process.");
+ let fileSavePageAsElement = document.getElementById("menu_savePage");
+ fileSavePageAsElement.doCommand();
+
+ info("Waiting for the channel.");
+ await observerPromise;
+
+ info("Wait until the save is finished.");
+ await transferCompletePromise;
+
+ // Close the file menu.
+ if (Services.appinfo.OS !== "Darwin") {
+ let popupHiddenPromise = BrowserTestUtils.waitForEvent(
+ filePopup,
+ "popuphidden"
+ );
+ filePopup.hidePopup();
+ await popupHiddenPromise;
+ }
+
+ info("Toggle off the offline mode");
+ BrowserOffline.toggleOfflineStatus();
+
+ // Clean up
+ BrowserTestUtils.removeTab(tab);
+
+ // Clean up the cache count on the server side.
+ await fetch(`${TEST_IMAGE_URL}?result`);
+ await new Promise(resolve => {
+ Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value =>
+ resolve()
+ );
+ });
+ }
+ }
+});
+
+add_task(async function testPageInfoMediaSaveAs() {
+ for (let networkIsolation of [true, false]) {
+ for (let partitionPerSite of [true, false]) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.network_state", networkIsolation],
+ ["privacy.dynamic_firstparty.use_site", partitionPerSite],
+ ],
+ });
+
+ let partitionKey = partitionPerSite
+ ? "(http,example.net)"
+ : "example.net";
+
+ info(
+ `Open a new tab for testing "Save AS" in the media panel of the page info.`
+ );
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ TEST_PAGEINFO_URL
+ );
+
+ info("Open the media panel of the pageinfo.");
+ let pageInfo = BrowserPageInfo(
+ gBrowser.selectedBrowser.currentURI.spec,
+ "mediaTab"
+ );
+
+ await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init");
+
+ let imageTree = pageInfo.document.getElementById("imagetree");
+ let imageRowsNum = imageTree.view.rowCount;
+
+ is(imageRowsNum, 2, "There should be two media items here.");
+
+ for (let i = 0; i < imageRowsNum; i++) {
+ imageTree.view.selection.select(i);
+ imageTree.ensureRowIsVisible(i);
+ imageTree.focus();
+
+ // Wait until the preview is loaded.
+ let preview = pageInfo.document.getElementById("thepreviewimage");
+ let mediaType = pageInfo.gImageView.data[i][1]; // COL_IMAGE_TYPE
+ if (mediaType == "Image") {
+ await BrowserTestUtils.waitForEvent(preview, "load");
+ } else if (mediaType == "Video") {
+ await BrowserTestUtils.waitForEvent(preview, "canplaythrough");
+ }
+
+ let url = pageInfo.gImageView.data[i][0]; // COL_IMAGE_ADDRESS
+ info(`Start to save the media item with URL: ${url}`);
+
+ let transferCompletePromise = createPromiseForTransferComplete();
+
+ // Observe the channel and check if it has the correct partitionKey.
+ let observerPromise = createPromiseForObservingChannel(
+ url,
+ partitionKey
+ );
+
+ info("Triggering the save process.");
+ let saveElement = pageInfo.document.getElementById("imagesaveasbutton");
+ saveElement.doCommand();
+
+ info("Waiting for the channel.");
+ await observerPromise;
+
+ info("Wait until the save is finished.");
+ await transferCompletePromise;
+ }
+
+ pageInfo.close();
+ BrowserTestUtils.removeTab(tab);
+ }
+ }
+});
+
+add_task(async function testPageInfoMediaMultipleSelectedSaveAs() {
+ for (let networkIsolation of [true, false]) {
+ for (let partitionPerSite of [true, false]) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.partition.network_state", networkIsolation],
+ ["privacy.dynamic_firstparty.use_site", partitionPerSite],
+ ],
+ });
+
+ let partitionKey = partitionPerSite
+ ? "(http,example.net)"
+ : "example.net";
+
+ info(
+ `Open a new tab for testing "Save AS" in the media panel of the page info.`
+ );
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ TEST_PAGEINFO_URL
+ );
+
+ info("Open the media panel of the pageinfo.");
+ let pageInfo = BrowserPageInfo(
+ gBrowser.selectedBrowser.currentURI.spec,
+ "mediaTab"
+ );
+
+ await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init");
+
+ // Make sure the preview image is loaded in order to avoid interfering
+ // following tests.
+ let preview = pageInfo.document.getElementById("thepreviewimage");
+ await BrowserTestUtils.waitForCondition(() => {
+ return preview.complete;
+ });
+
+ let imageTree = pageInfo.document.getElementById("imagetree");
+ let imageRowsNum = imageTree.view.rowCount;
+
+ is(imageRowsNum, 2, "There should be two media items here.");
+
+ imageTree.view.selection.selectAll();
+ imageTree.focus();
+
+ let url = pageInfo.gImageView.data[0][0]; // COL_IMAGE_ADDRESS
+ info(`Start to save the media item with URL: ${url}`);
+
+ let transferCompletePromise = createPromiseForTransferComplete();
+ let observerPromises = [];
+
+ // Observe all channels and check if they have the correct partitionKey.
+ for (let i = 0; i < imageRowsNum; ++i) {
+ let observerPromise = createPromiseForObservingChannel(
+ url,
+ partitionKey
+ );
+ observerPromises.push(observerPromise);
+ }
+
+ info("Triggering the save process.");
+ let saveElement = pageInfo.document.getElementById("imagesaveasbutton");
+ saveElement.doCommand();
+
+ info("Waiting for the all channels.");
+ await Promise.all(observerPromises);
+
+ info("Wait until the save is finished.");
+ await transferCompletePromise;
+
+ pageInfo.close();
+ BrowserTestUtils.removeTab(tab);
+ }
+ }
+});