diff options
Diffstat (limited to 'comm/mail/components/preferences/test/browser/browser_cloudfile.js')
-rw-r--r-- | comm/mail/components/preferences/test/browser/browser_cloudfile.js | 796 |
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"); +}); |