summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/preferences/test/browser/browser_cloudfile.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/preferences/test/browser/browser_cloudfile.js')
-rw-r--r--comm/mail/components/preferences/test/browser/browser_cloudfile.js796
1 files changed, 796 insertions, 0 deletions
diff --git a/comm/mail/components/preferences/test/browser/browser_cloudfile.js b/comm/mail/components/preferences/test/browser/browser_cloudfile.js
new file mode 100644
index 0000000000..9f395f9ab8
--- /dev/null
+++ b/comm/mail/components/preferences/test/browser/browser_cloudfile.js
@@ -0,0 +1,796 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+/* eslint-env webextensions */
+
+let { cloudFileAccounts } = ChromeUtils.import(
+ "resource:///modules/cloudFileAccounts.jsm"
+);
+let { MockRegistrar } = ChromeUtils.importESModule(
+ "resource://testing-common/MockRegistrar.sys.mjs"
+);
+
+function ManagementScript() {
+ browser.test.onMessage.addListener((message, assertMessage, browserStyle) => {
+ if (message !== "check-style") {
+ return;
+ }
+ function verifyButton(buttonElement, expected) {
+ let buttonStyle = window.getComputedStyle(buttonElement);
+ let buttonBackgroundColor = buttonStyle.backgroundColor;
+ if (browserStyle && expected.hasBrowserStyleClass) {
+ browser.test.assertEq(
+ "rgb(9, 150, 248)",
+ buttonBackgroundColor,
+ assertMessage
+ );
+ } else {
+ browser.test.assertTrue(
+ buttonBackgroundColor !== "rgb(9, 150, 248)",
+ assertMessage
+ );
+ }
+ }
+
+ function verifyCheckboxOrRadio(element, expected) {
+ let style = window.getComputedStyle(element);
+ let styledBackground = element.checked
+ ? "rgb(9, 150, 248)"
+ : "rgb(255, 255, 255)";
+ if (browserStyle && expected.hasBrowserStyleClass) {
+ browser.test.assertEq(
+ styledBackground,
+ style.backgroundColor,
+ assertMessage
+ );
+ } else {
+ browser.test.assertTrue(
+ style.backgroundColor != styledBackground,
+ assertMessage
+ );
+ }
+ }
+
+ let normalButton = document.getElementById("normalButton");
+ let browserStyleButton = document.getElementById("browserStyleButton");
+ verifyButton(normalButton, { hasBrowserStyleClass: false });
+ verifyButton(browserStyleButton, { hasBrowserStyleClass: true });
+
+ let normalCheckbox1 = document.getElementById("normalCheckbox1");
+ let normalCheckbox2 = document.getElementById("normalCheckbox2");
+ let browserStyleCheckbox = document.getElementById("browserStyleCheckbox");
+ verifyCheckboxOrRadio(normalCheckbox1, { hasBrowserStyleClass: false });
+ verifyCheckboxOrRadio(normalCheckbox2, { hasBrowserStyleClass: false });
+ verifyCheckboxOrRadio(browserStyleCheckbox, {
+ hasBrowserStyleClass: true,
+ });
+
+ let normalRadio1 = document.getElementById("normalRadio1");
+ let normalRadio2 = document.getElementById("normalRadio2");
+ let browserStyleRadio = document.getElementById("browserStyleRadio");
+ verifyCheckboxOrRadio(normalRadio1, { hasBrowserStyleClass: false });
+ verifyCheckboxOrRadio(normalRadio2, { hasBrowserStyleClass: false });
+ verifyCheckboxOrRadio(browserStyleRadio, { hasBrowserStyleClass: true });
+
+ browser.test.notifyPass("management-ui-browser_style");
+ });
+ browser.test.sendMessage("management-ui-ready");
+}
+
+let extension;
+async function startExtension(browser_style) {
+ let cloud_file = {
+ name: "Mochitest",
+ management_url: "management.html",
+ };
+
+ switch (browser_style) {
+ case "true":
+ cloud_file.browser_style = true;
+ break;
+ case "false":
+ cloud_file.browser_style = false;
+ break;
+ }
+
+ extension = ExtensionTestUtils.loadExtension({
+ async background() {
+ browser.test.onMessage.addListener(async message => {
+ if (message != "set-configured") {
+ return;
+ }
+ let accounts = await browser.cloudFile.getAllAccounts();
+ for (let account of accounts) {
+ await browser.cloudFile.updateAccount(account.id, {
+ configured: true,
+ });
+ }
+ browser.test.sendMessage("ready");
+ });
+ },
+ files: {
+ "management.html": `<html>
+ <body>
+ <a id="a" href="https://www.example.com/">Click me!</a>
+ <button id="normalButton" name="button" class="default">Default</button>
+ <button id="browserStyleButton" name="button" class="browser-style default">Default</button>
+
+ <input id="normalCheckbox1" type="checkbox"/>
+ <input id="normalCheckbox2" type="checkbox"/><label>Checkbox</label>
+ <div class="browser-style">
+ <input id="browserStyleCheckbox" type="checkbox"><label for="browserStyleCheckbox">Checkbox</label>
+ </div>
+
+ <input id="normalRadio1" type="radio"/>
+ <input id="normalRadio2" type="radio"/><label>Radio</label>
+ <div class="browser-style">
+ <input id="browserStyleRadio" checked="" type="radio"><label for="browserStyleRadio">Radio</label>
+ </div>
+ </body>
+ <script src="management.js" type="text/javascript"></script>
+ </html>`,
+ "management.js": ManagementScript,
+ },
+ manifest: {
+ cloud_file,
+ applications: { gecko: { id: "cloudfile@mochitest" } },
+ },
+ });
+
+ info("Starting extension");
+ await extension.startup();
+
+ if (accountIsConfigured) {
+ extension.sendMessage("set-configured");
+ await extension.awaitMessage("ready");
+ }
+}
+
+add_task(async () => {
+ // Register a fake provider representing a built-in provider. We don't
+ // currently ship any built-in providers, but if we did, we should check
+ // if they are present before doing this. Built-in providers can be
+ // problematic for artifact builds.
+ cloudFileAccounts.registerProvider("Fake-Test", {
+ displayName: "XYZ Fake",
+ type: "ext-fake@extensions.thunderbird.net",
+ });
+ registerCleanupFunction(() => {
+ cloudFileAccounts.unregisterProvider("Fake-Test");
+ });
+});
+
+let accountIsConfigured = false;
+
+// Mock the prompt service. We're going to be asked if we're sure
+// we want to remove an account, so let's say yes.
+
+/** @implements {nsIPromptService} */
+let mockPromptService = {
+ confirmCount: 0,
+ confirm() {
+ this.confirmCount++;
+ return true;
+ },
+ QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]),
+};
+/** @implements {nsIExternalProtocolService} */
+let mockExternalProtocolService = {
+ _loadedURLs: [],
+ externalProtocolHandlerExists(aProtocolScheme) {},
+ getApplicationDescription(aScheme) {},
+ getProtocolHandlerInfo(aProtocolScheme) {},
+ getProtocolHandlerInfoFromOS(aProtocolScheme, aFound) {},
+ isExposedProtocol(aProtocolScheme) {},
+ loadURI(aURI, aWindowContext) {
+ this._loadedURLs.push(aURI.spec);
+ },
+ setProtocolHandlerDefaults(aHandlerInfo, aOSHandlerExists) {},
+ urlLoaded(aURL) {
+ return this._loadedURLs.includes(aURL);
+ },
+ QueryInterface: ChromeUtils.generateQI(["nsIExternalProtocolService"]),
+};
+
+let originalPromptService = Services.prompt;
+Services.prompt = mockPromptService;
+
+let mockExternalProtocolServiceCID = MockRegistrar.register(
+ "@mozilla.org/uriloader/external-protocol-service;1",
+ mockExternalProtocolService
+);
+
+registerCleanupFunction(() => {
+ Services.prompt = originalPromptService;
+ MockRegistrar.unregister(mockExternalProtocolServiceCID);
+});
+
+add_task(async function addRemoveAccounts() {
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ // Load the preferences tab.
+
+ let { prefsDocument, prefsWindow } = await openNewPrefsTab(
+ "paneCompose",
+ "compositionAttachmentsCategory"
+ );
+
+ // Check everything is as it should be.
+
+ let accountList = prefsDocument.getElementById("cloudFileView");
+ is(accountList.itemCount, 0);
+
+ let buttonList = prefsDocument.getElementById("addCloudFileAccountButtons");
+ ok(!buttonList.hidden);
+ is(buttonList.childElementCount, 1);
+ is(
+ buttonList.children[0].getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+
+ let menuButton = prefsDocument.getElementById("addCloudFileAccount");
+ ok(menuButton.hidden);
+ is(menuButton.itemCount, 1);
+ is(
+ menuButton.getItemAtIndex(0).getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+
+ let removeButton = prefsDocument.getElementById("removeCloudFileAccount");
+ ok(removeButton.disabled);
+
+ let cloudFileDefaultPanel = prefsDocument.getElementById(
+ "cloudFileDefaultPanel"
+ );
+ ok(!cloudFileDefaultPanel.hidden);
+
+ let browserWrapper = prefsDocument.getElementById("cloudFileSettingsWrapper");
+ is(browserWrapper.childElementCount, 0);
+
+ // Register our test provider.
+
+ await startExtension();
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(buttonList.childElementCount, 2);
+ is(
+ buttonList.children[0].getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+ is(buttonList.children[1].getAttribute("value"), "ext-cloudfile@mochitest");
+ is(
+ buttonList.children[1].style.listStyleImage,
+ `url("chrome://messenger/content/extension.svg")`
+ );
+
+ is(menuButton.itemCount, 2);
+ is(
+ menuButton.getItemAtIndex(0).getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+ is(
+ menuButton.getItemAtIndex(1).getAttribute("value"),
+ "ext-cloudfile@mochitest"
+ );
+ is(
+ menuButton.getItemAtIndex(1).getAttribute("image"),
+ "chrome://messenger/content/extension.svg"
+ );
+
+ // Create a new account.
+
+ EventUtils.synthesizeMouseAtCenter(
+ buttonList.children[1],
+ { clickCount: 1 },
+ prefsWindow
+ );
+ is(cloudFileAccounts.accounts.length, 1);
+ is(cloudFileAccounts.configuredAccounts.length, 0);
+
+ let account = cloudFileAccounts.accounts[0];
+ let accountKey = account.accountKey;
+ is(cloudFileAccounts.accounts[0].type, "ext-cloudfile@mochitest");
+
+ // Check prefs were updated.
+
+ is(
+ Services.prefs.getCharPref(
+ `mail.cloud_files.accounts.${accountKey}.displayName`
+ ),
+ "Mochitest"
+ );
+ is(
+ Services.prefs.getCharPref(`mail.cloud_files.accounts.${accountKey}.type`),
+ "ext-cloudfile@mochitest"
+ );
+
+ // Check UI was updated.
+
+ is(accountList.itemCount, 1);
+ is(accountList.selectedIndex, 0);
+ ok(!removeButton.disabled);
+
+ let accountListItem = accountList.selectedItem;
+ is(accountListItem.getAttribute("value"), accountKey);
+ is(
+ accountListItem.querySelector(".typeIcon:not(.configuredWarning)").src,
+ "chrome://messenger/content/extension.svg"
+ );
+ is(accountListItem.querySelector("label").value, "Mochitest");
+ is(accountListItem.querySelector(".configuredWarning").hidden, false);
+
+ ok(cloudFileDefaultPanel.hidden);
+ is(browserWrapper.childElementCount, 1);
+
+ let browser = browserWrapper.firstElementChild;
+ if (
+ browser.webProgress?.isLoadingDocument ||
+ browser.currentURI?.spec == "about:blank"
+ ) {
+ await BrowserTestUtils.browserLoaded(browser);
+ }
+ is(
+ browser.currentURI.pathQueryRef,
+ `/management.html?accountId=${accountKey}`
+ );
+ await extension.awaitMessage("management-ui-ready");
+
+ let tabmail = document.getElementById("tabmail");
+ let tabCount = tabmail.tabInfo.length;
+ BrowserTestUtils.synthesizeMouseAtCenter("a", {}, browser);
+ // It might take a moment to get to the external protocol service.
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 500));
+ ok(
+ mockExternalProtocolService.urlLoaded("https://www.example.com/"),
+ "Link click sent to external protocol service."
+ );
+ is(tabmail.tabInfo.length, tabCount, "No new tab opened");
+
+ // Rename the account.
+
+ EventUtils.synthesizeMouseAtCenter(
+ accountListItem,
+ { clickCount: 1 },
+ prefsWindow
+ );
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(
+ prefsDocument.activeElement.closest("input"),
+ accountListItem.querySelector("input")
+ );
+ ok(accountListItem.querySelector("label").hidden);
+ ok(!accountListItem.querySelector("input").hidden);
+ is(accountListItem.querySelector("input").value, "Mochitest");
+ EventUtils.synthesizeKey("VK_RIGHT", undefined, prefsWindow);
+ EventUtils.synthesizeKey("!", undefined, prefsWindow);
+ EventUtils.synthesizeKey("VK_RETURN", undefined, prefsWindow);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(prefsDocument.activeElement, accountList);
+ ok(!accountListItem.querySelector("label").hidden);
+ is(accountListItem.querySelector("label").value, "Mochitest!");
+ ok(accountListItem.querySelector("input").hidden);
+ is(
+ Services.prefs.getCharPref(
+ `mail.cloud_files.accounts.${accountKey}.displayName`
+ ),
+ "Mochitest!"
+ );
+
+ // Start to rename the account, but bail out.
+
+ EventUtils.synthesizeMouseAtCenter(
+ accountListItem,
+ { clickCount: 1 },
+ prefsWindow
+ );
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(
+ prefsDocument.activeElement.closest("input"),
+ accountListItem.querySelector("input")
+ );
+ EventUtils.synthesizeKey("O", undefined, prefsWindow);
+ EventUtils.synthesizeKey("o", undefined, prefsWindow);
+ EventUtils.synthesizeKey("p", undefined, prefsWindow);
+ EventUtils.synthesizeKey("s", undefined, prefsWindow);
+ EventUtils.synthesizeKey("VK_ESCAPE", undefined, prefsWindow);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(prefsDocument.activeElement, accountList);
+ ok(!accountListItem.querySelector("label").hidden);
+ is(accountListItem.querySelector("label").value, "Mochitest!");
+ ok(accountListItem.querySelector("input").hidden);
+ is(
+ Services.prefs.getCharPref(
+ `mail.cloud_files.accounts.${accountKey}.displayName`
+ ),
+ "Mochitest!"
+ );
+
+ // Configure the account.
+
+ account.configured = true;
+ accountIsConfigured = true;
+ cloudFileAccounts.emit("accountConfigured", account);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(accountListItem.querySelector(".configuredWarning").hidden, true);
+ is(cloudFileAccounts.accounts.length, 1);
+ is(cloudFileAccounts.configuredAccounts.length, 1);
+
+ // Remove the test provider. The list item, button, and browser should disappear.
+
+ info("Stopping extension");
+ await extension.unload();
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(buttonList.childElementCount, 1);
+ is(
+ buttonList.children[0].getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+ is(menuButton.itemCount, 1);
+ is(
+ menuButton.getItemAtIndex(0).getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+ is(accountList.itemCount, 0);
+ ok(!cloudFileDefaultPanel.hidden);
+ is(browserWrapper.childElementCount, 0);
+
+ // Re-add the test provider.
+
+ await startExtension();
+
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 1);
+ is(cloudFileAccounts.configuredAccounts.length, 1);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(buttonList.childElementCount, 2);
+ is(
+ buttonList.children[0].getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+ is(buttonList.children[1].getAttribute("value"), "ext-cloudfile@mochitest");
+
+ is(menuButton.itemCount, 2);
+ is(
+ menuButton.getItemAtIndex(0).getAttribute("value"),
+ "ext-fake@extensions.thunderbird.net"
+ );
+ is(
+ menuButton.getItemAtIndex(1).getAttribute("value"),
+ "ext-cloudfile@mochitest"
+ );
+
+ is(accountList.itemCount, 1);
+ is(accountList.selectedIndex, -1);
+ ok(removeButton.disabled);
+
+ accountListItem = accountList.getItemAtIndex(0);
+ is(
+ Services.prefs.getCharPref(
+ `mail.cloud_files.accounts.${accountKey}.displayName`
+ ),
+ "Mochitest!"
+ );
+
+ EventUtils.synthesizeMouseAtCenter(
+ accountList.getItemAtIndex(0),
+ { clickCount: 1 },
+ prefsWindow
+ );
+ ok(!removeButton.disabled);
+ EventUtils.synthesizeMouseAtCenter(
+ removeButton,
+ { clickCount: 1 },
+ prefsWindow
+ );
+ is(mockPromptService.confirmCount, 1);
+
+ ok(
+ !Services.prefs.prefHasUserValue(
+ `mail.cloud_files.accounts.${accountKey}.displayName`
+ )
+ );
+ ok(
+ !Services.prefs.prefHasUserValue(
+ `mail.cloud_files.accounts.${accountKey}.type`
+ )
+ );
+
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ info("Stopping extension");
+ await extension.unload();
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ // Close the preferences tab.
+
+ await closePrefsTab();
+});
+
+async function subtestBrowserStyle(assertMessage, expected) {
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ // Load the preferences tab.
+
+ let { prefsDocument, prefsWindow } = await openNewPrefsTab(
+ "paneCompose",
+ "compositionAttachmentsCategory"
+ );
+
+ // Minimal check everything is as it should be.
+
+ let accountList = prefsDocument.getElementById("cloudFileView");
+ is(accountList.itemCount, 0);
+
+ let buttonList = prefsDocument.getElementById("addCloudFileAccountButtons");
+ ok(!buttonList.hidden);
+
+ let browserWrapper = prefsDocument.getElementById("cloudFileSettingsWrapper");
+ is(browserWrapper.childElementCount, 0);
+
+ // Register our test provider.
+
+ await startExtension(expected.browser_style);
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ await new Promise(resolve => prefsWindow.requestAnimationFrame(resolve));
+
+ is(buttonList.childElementCount, 2);
+ is(buttonList.children[1].getAttribute("value"), "ext-cloudfile@mochitest");
+
+ // Create a new account.
+
+ EventUtils.synthesizeMouseAtCenter(
+ buttonList.children[1],
+ { clickCount: 1 },
+ prefsWindow
+ );
+ is(cloudFileAccounts.accounts.length, 1);
+ is(cloudFileAccounts.configuredAccounts.length, 0);
+
+ let account = cloudFileAccounts.accounts[0];
+ let accountKey = account.accountKey;
+ is(cloudFileAccounts.accounts[0].type, "ext-cloudfile@mochitest");
+
+ // Minimal check UI was updated.
+
+ is(accountList.itemCount, 1);
+ is(accountList.selectedIndex, 0);
+
+ let accountListItem = accountList.selectedItem;
+ is(accountListItem.getAttribute("value"), accountKey);
+
+ is(browserWrapper.childElementCount, 1);
+ let browser = browserWrapper.firstElementChild;
+ if (
+ browser.webProgress?.isLoadingDocument ||
+ browser.currentURI?.spec == "about:blank"
+ ) {
+ await BrowserTestUtils.browserLoaded(browser);
+ }
+ is(
+ browser.currentURI.pathQueryRef,
+ `/management.html?accountId=${accountKey}`
+ );
+ await extension.awaitMessage("management-ui-ready");
+
+ // Test browser_style
+
+ extension.sendMessage(
+ "check-style",
+ assertMessage,
+ expected.browser_style == "true"
+ );
+ await extension.awaitFinish("management-ui-browser_style");
+
+ // Remove the account
+
+ accountListItem = accountList.getItemAtIndex(0);
+ EventUtils.synthesizeMouseAtCenter(
+ accountList.getItemAtIndex(0),
+ { clickCount: 1 },
+ prefsWindow
+ );
+
+ let removeButton = prefsDocument.getElementById("removeCloudFileAccount");
+ ok(!removeButton.disabled);
+ EventUtils.synthesizeMouseAtCenter(
+ removeButton,
+ { clickCount: 1 },
+ prefsWindow
+ );
+ is(mockPromptService.confirmCount, expected.confirmCount);
+
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ info("Stopping extension");
+ await extension.unload();
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ // Close the preferences tab.
+
+ await closePrefsTab();
+}
+
+add_task(async function test_without_setting_browser_style() {
+ await subtestBrowserStyle(
+ "Expected correct style when browser_style is excluded",
+ {
+ confirmCount: 2,
+ browser_style: "default",
+ }
+ );
+});
+
+add_task(async function test_with_browser_style_set_to_true() {
+ await subtestBrowserStyle(
+ "Expected correct style when browser_style is set to `true`",
+ {
+ confirmCount: 3,
+ browser_style: "true",
+ }
+ );
+});
+
+add_task(async function test_with_browser_style_set_to_false() {
+ await subtestBrowserStyle(
+ "Expected no style when browser_style is set to `false`",
+ {
+ confirmCount: 4,
+ browser_style: "false",
+ }
+ );
+});
+
+add_task(async function accountListOverflow() {
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ // Register our test provider.
+
+ await startExtension();
+
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ // Load the preferences tab.
+
+ let { prefsDocument, prefsWindow } = await openNewPrefsTab(
+ "paneCompose",
+ "compositionAttachmentsCategory"
+ );
+
+ let accountList = prefsDocument.getElementById("cloudFileView");
+ is(accountList.itemCount, 0);
+
+ let buttonList = prefsDocument.getElementById("addCloudFileAccountButtons");
+ ok(!buttonList.hidden);
+ is(buttonList.childElementCount, 2);
+ is(buttonList.children[0].getAttribute("value"), "ext-cloudfile@mochitest");
+
+ let menuButton = prefsDocument.getElementById("addCloudFileAccount");
+ ok(menuButton.hidden);
+
+ // Add new accounts until the list overflows. The list of buttons should be hidden
+ // and the button with the drop-down should appear.
+
+ let count = 0;
+ do {
+ let readyPromise = extension.awaitMessage("management-ui-ready");
+ EventUtils.synthesizeMouseAtCenter(
+ buttonList.children[0],
+ { clickCount: 1 },
+ prefsWindow
+ );
+ await readyPromise;
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(r => setTimeout(r, 500));
+ if (buttonList.hidden) {
+ break;
+ }
+ } while (++count < 25);
+
+ ok(count < 24); // If count reaches 25, we have a problem.
+ ok(!menuButton.hidden);
+
+ // Remove the added accounts. The list of buttons should not reappear and the
+ // button with the drop-down should remain.
+
+ let removeButton = prefsDocument.getElementById("removeCloudFileAccount");
+ do {
+ EventUtils.synthesizeMouseAtCenter(
+ accountList.getItemAtIndex(0),
+ { clickCount: 1 },
+ prefsWindow
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ removeButton,
+ { clickCount: 1 },
+ prefsWindow
+ );
+ await new Promise(resolve => setTimeout(resolve));
+ } while (--count > 0);
+
+ ok(buttonList.hidden);
+ ok(!menuButton.hidden);
+
+ // Close the preferences tab.
+
+ await closePrefsTab();
+ info("Stopping extension");
+ await extension.unload();
+ Services.prefs.deleteBranch("mail.cloud_files.accounts");
+});
+
+add_task(async function accountListOrder() {
+ is(cloudFileAccounts.providers.length, 1);
+ is(cloudFileAccounts.accounts.length, 0);
+
+ for (let [key, displayName] of [
+ ["someKey1", "carl's Account"],
+ ["someKey2", "Amber's Account"],
+ ["someKey3", "alice's Account"],
+ ["someKey4", "Bob's Account"],
+ ]) {
+ Services.prefs.setCharPref(
+ `mail.cloud_files.accounts.${key}.type`,
+ "ext-cloudfile@mochitest"
+ );
+ Services.prefs.setCharPref(
+ `mail.cloud_files.accounts.${key}.displayName`,
+ displayName
+ );
+ }
+
+ // Register our test provider.
+
+ await startExtension();
+
+ is(cloudFileAccounts.providers.length, 2);
+ is(cloudFileAccounts.accounts.length, 4);
+
+ let { prefsDocument } = await openNewPrefsTab(
+ "paneCompose",
+ "compositionAttachmentsCategory"
+ );
+
+ let accountList = prefsDocument.getElementById("cloudFileView");
+ is(accountList.itemCount, 4);
+
+ is(accountList.getItemAtIndex(0).value, "someKey3");
+ is(accountList.getItemAtIndex(1).value, "someKey2");
+ is(accountList.getItemAtIndex(2).value, "someKey4");
+ is(accountList.getItemAtIndex(3).value, "someKey1");
+
+ await closePrefsTab();
+ info("Stopping extension");
+ await extension.unload();
+ Services.prefs.deleteBranch("mail.cloud_files.accounts");
+});