From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mail/test/browser/import/browser.ini | 14 + .../test/browser/import/browser_exportProfile.js | 97 +++++++ .../test/browser/import/browser_importProfile.js | 323 +++++++++++++++++++++ 3 files changed, 434 insertions(+) create mode 100644 comm/mail/test/browser/import/browser.ini create mode 100644 comm/mail/test/browser/import/browser_exportProfile.js create mode 100644 comm/mail/test/browser/import/browser_importProfile.js (limited to 'comm/mail/test/browser/import') diff --git a/comm/mail/test/browser/import/browser.ini b/comm/mail/test/browser/import/browser.ini new file mode 100644 index 0000000000..319e841379 --- /dev/null +++ b/comm/mail/test/browser/import/browser.ini @@ -0,0 +1,14 @@ +[DEFAULT] +prefs = + mail.provider.suppress_dialog_on_startup=true + mail.spellcheck.inline=false + mail.spotlight.firstRunDone=true + mail.winsearch.firstRunDone=true + mailnews.database.global.indexer.enabled=false + mailnews.start_page.override_url=about:blank + mailnews.start_page.url=about:blank + mail.import.in_new_tab=true +subsuite = thunderbird + +[browser_exportProfile.js] +[browser_importProfile.js] diff --git a/comm/mail/test/browser/import/browser_exportProfile.js b/comm/mail/test/browser/import/browser_exportProfile.js new file mode 100644 index 0000000000..d3537d266c --- /dev/null +++ b/comm/mail/test/browser/import/browser_exportProfile.js @@ -0,0 +1,97 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +const { MockFilePicker } = ChromeUtils.importESModule( + "resource://testing-common/MockFilePicker.sys.mjs" +); + +add_task(async function testProfileExport() { + const profileDir = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "profile-tmp" + ); + const zipFile = PathUtils.join(profileDir, "export.zip"); + const filePath = Services.io + .newURI(PathUtils.toFileURI(zipFile)) + .QueryInterface(Ci.nsIFileURL); + MockFilePicker.init(window); + MockFilePicker.setFiles([filePath.file]); + registerCleanupFunction(async () => { + await IOUtils.remove(profileDir, { + recursive: true, + }); + MockFilePicker.cleanup(); + }); + + const tab = await new Promise(resolve => { + const tab = window.openTab("contentTab", { + url: "about:import", + onLoad(event, browser) { + browser.contentWindow.showTab("tab-export", true); + resolve(tab); + }, + }); + }); + const importDocument = tab.browser.contentDocument; + const exportPane = importDocument.getElementById("tabPane-export"); + + ok( + BrowserTestUtils.is_visible(importDocument.getElementById("exportDocs")), + "Export docs link is visible" + ); + ok( + BrowserTestUtils.is_hidden(importDocument.getElementById("importDocs")), + "Import docs link is hidden" + ); + + await BrowserTestUtils.synthesizeMouseAtCenter( + "#exportButton", + {}, + tab.browser + ); + const progressPane = exportPane.querySelector(".progressPane"); + await BrowserTestUtils.waitForMutationCondition( + exportPane, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(progressPane) + ); + ok( + BrowserTestUtils.is_hidden(importDocument.getElementById("exportButton")), + "Export button is hidden while export is in progress" + ); + + const finish = exportPane.querySelector(".progressFinish"); + await BrowserTestUtils.waitForMutationCondition( + exportPane, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(finish) + ); + ok( + BrowserTestUtils.is_visible(progressPane), + "When export succeeds and finish is shown, progress is still displayed" + ); + + const tabClosedPromise = BrowserTestUtils.waitForEvent( + tab.tabNode, + "TabClose" + ); + // Using BrowserTestUtils fails, because clicking the button destroys the + // context, which means the actor from BTU gets destroyed before it can report + // that it emitted the event. + await EventUtils.synthesizeMouseAtCenter( + finish, + {}, + tab.browser.contentWindow + ); + await tabClosedPromise; + + const exportZipStat = await IOUtils.stat(zipFile); + info(exportZipStat.size); + ok(exportZipStat.size > 10, "Zip is not empty"); +}); diff --git a/comm/mail/test/browser/import/browser_importProfile.js b/comm/mail/test/browser/import/browser_importProfile.js new file mode 100644 index 0000000000..0e07a3ca30 --- /dev/null +++ b/comm/mail/test/browser/import/browser_importProfile.js @@ -0,0 +1,323 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +const { MockFilePicker } = ChromeUtils.importESModule( + "resource://testing-common/MockFilePicker.sys.mjs" +); + +function checkSteps(importDocument, currentStep, totalSteps) { + const stepNav = importDocument.getElementById("stepNav"); + is(stepNav.childElementCount, totalSteps, "Expected amount of steps"); + ok( + stepNav + .querySelector(`*:nth-child(${currentStep})`) + .classList.contains("current"), + `Expected step ${currentStep} is active` + ); +} + +function checkVisiblePane(importDocument, activePaneId, activeStepId) { + const panes = importDocument.querySelectorAll(".tabPane"); + for (const pane of panes) { + if (pane.id === activePaneId) { + ok(BrowserTestUtils.is_visible(pane), `Pane ${activePaneId} is visible`); + const steps = pane.querySelectorAll("section"); + for (const step of steps) { + if (step.id === activeStepId) { + ok( + BrowserTestUtils.is_visible(step), + `Step ${activeStepId} is visible` + ); + } else { + ok(BrowserTestUtils.is_hidden(step), `Step ${step.id} is hidden`); + } + } + } else { + ok(BrowserTestUtils.is_hidden(pane), `Pane ${pane.id} is not visible`); + } + } +} + +add_setup(() => { + MockFilePicker.init(window); + registerCleanupFunction(() => { + MockFilePicker.cleanup(); + }); +}); + +add_task(async function testProfileImport() { + const profileDir = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "profile-tmp" + ); + await IOUtils.writeUTF8( + PathUtils.join(profileDir, "prefs.js"), + [ + ["mail.smtpserver.smtp1.username", "smtp-user-1"], + ["mail.smtpservers", "smtp1"], + ["mail.identity.id1.smtpServer", "smtp1"], + ["mail.server.server2.type", "none"], + ["mail.server.server6.type", "imap"], + ["mail.account.account1.server", "server2"], + ["mail.account.account2.server", "server6"], + ["mail.account.account2.identities", "id1"], + ["mail.accountmanager.accounts", "account2,account1"], + ] + .map( + ([name, value]) => + `user_pref(${JSON.stringify(name)}, ${JSON.stringify(value)});` + ) + .join("\n") + ); + const filePath = Services.io + .newURI(PathUtils.toFileURI(profileDir)) + .QueryInterface(Ci.nsIFileURL); + MockFilePicker.setFiles([filePath.file]); + registerCleanupFunction(async () => { + await IOUtils.remove(profileDir, { + recursive: true, + }); + }); + + const tab = await new Promise(resolve => { + const tab = window.openTab("contentTab", { + url: "about:import", + onLoad() { + resolve(tab); + }, + }); + }); + const importDocument = tab.browser.contentDocument; + + ok( + BrowserTestUtils.is_hidden(importDocument.getElementById("exportDocs")), + "Export docs link is hidden" + ); + ok( + BrowserTestUtils.is_visible(importDocument.getElementById("importDocs")), + "Import docs link is visible" + ); + + checkSteps(importDocument, 1, 4); + checkVisiblePane(importDocument, "tabPane-start", "start-sources"); + ok( + importDocument.querySelector('#start-sources input[value="Thunderbird"]') + .value, + "Thunderbird profile is selected by default" + ); + ok( + BrowserTestUtils.is_hidden( + importDocument.getElementById("startBackButton") + ), + "Back button is hidden in first step" + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#tabPane-start .continue", + {}, + tab.browser + ); + const appPane = importDocument.getElementById("tabPane-app"); + await BrowserTestUtils.waitForMutationCondition( + appPane, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(appPane) + ); + + checkSteps(importDocument, 2, 4); + checkVisiblePane(importDocument, "tabPane-app", "app-profiles"); + ok( + BrowserTestUtils.is_visible( + importDocument.getElementById("profileBackButton") + ), + "Back button is visible" + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + '#filePickerList [value="file-picker-dir"]', + {}, + tab.browser + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#profileNextButton", + {}, + tab.browser + ); + const itemsStep = importDocument.getElementById("app-items"); + await BrowserTestUtils.waitForMutationCondition( + itemsStep, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(itemsStep) + ); + + checkSteps(importDocument, 3, 4); + checkVisiblePane(importDocument, "tabPane-app", "app-items"); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#profileNextButton", + {}, + tab.browser + ); + const summaryStep = importDocument.getElementById("app-summary"); + await BrowserTestUtils.waitForMutationCondition( + summaryStep, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(summaryStep) + ); + + checkSteps(importDocument, 4, 4); + checkVisiblePane(importDocument, "tabPane-app", "app-summary"); + ok( + BrowserTestUtils.is_hidden( + importDocument.getElementById("profileNextButton") + ), + "Can't advance from summary step" + ); + + await BrowserTestUtils.synthesizeMouseAtCenter( + "#appStartImport", + {}, + tab.browser + ); + + const progressPane = importDocument.querySelector( + "#app-summary .progressPane" + ); + await BrowserTestUtils.waitForMutationCondition( + appPane, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(progressPane) + ); + ok( + BrowserTestUtils.is_hidden(importDocument.getElementById("appStartImport")), + "Import button is hidden while import is in progress" + ); + + const finish = importDocument.querySelector("#app-summary .progressFinish"); + await BrowserTestUtils.waitForMutationCondition( + appPane, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(finish) + ); + ok( + BrowserTestUtils.is_visible(progressPane), + "When import succeeds and finish is shown, progress is still displayed" + ); + + // We close the tab ourselves instead of hitting the finish button, since + // restarting Thunderbird within the test is a headache. + document.getElementById("tabmail").closeTab(tab); +}); + +add_task(async function testImportLargeZIP() { + // Writing the fake zip and deleting it can take some time. + requestLongerTimeout(2); + const profileDir = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "profile-tmp" + ); + const profileZip = PathUtils.join(profileDir, "profile.zip"); + // This block makes sure the ZIP file's fake contents go out of scope once + // written out. + { + const halfAGigabyte = new Uint8Array(2 ** 29); + await IOUtils.write(profileZip, halfAGigabyte); + info("ZIP is 0.5 GB big now"); + for (let i = 0; i < 3; ++i) { + await IOUtils.write(profileZip, halfAGigabyte, { mode: "append" }); + info(`ZIP is ${(i + 2) * 0.5} GB big now`); + } + } + await IOUtils.write( + profileZip, + new Uint8Array(2), // These are extra bytes beyond 2 GB + { + mode: "append", + } + ); + const filePath = Services.io + .newURI(PathUtils.toFileURI(profileZip)) + .QueryInterface(Ci.nsIFileURL); + MockFilePicker.setFiles([filePath.file]); + registerCleanupFunction(async () => { + await IOUtils.remove(profileDir, { + recursive: true, + }); + }); + + const tab = await new Promise(resolve => { + const tab = window.openTab("contentTab", { + url: "about:import", + onLoad() { + resolve(tab); + }, + }); + }); + const importDocument = tab.browser.contentDocument; + + checkSteps(importDocument, 1, 4); + checkVisiblePane(importDocument, "tabPane-start", "start-sources"); + ok( + importDocument.querySelector('#start-sources input[value="Thunderbird"]') + .value, + "Thunderbird profile is selected by default" + ); + ok( + BrowserTestUtils.is_hidden( + importDocument.getElementById("startBackButton") + ), + "Back button is hidden in first step" + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#tabPane-start .continue", + {}, + tab.browser + ); + const appPane = importDocument.getElementById("tabPane-app"); + await BrowserTestUtils.waitForMutationCondition( + appPane, + { + attributes: true, + }, + () => BrowserTestUtils.is_visible(appPane) + ); + + checkSteps(importDocument, 2, 4); + checkVisiblePane(importDocument, "tabPane-app", "app-profiles"); + ok( + BrowserTestUtils.is_visible( + importDocument.getElementById("profileBackButton") + ), + "Back button is visible" + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#appFilePickerZip", + {}, + tab.browser + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#profileNextButton", + {}, + tab.browser + ); + + const notificationBox = importDocument.getElementById("errorNotifications"); + await BrowserTestUtils.waitForMutationCondition( + notificationBox, + { + childList: true, + }, + () => notificationBox.childElementCount > 0 + ); + + document.getElementById("tabmail").closeTab(tab); +}); -- cgit v1.2.3