Revision control
Copy as Markdown
Other Tools
/* 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
"use strict";
const { click_account_tree_row, get_account_tree_row, openAccountSettings } =
ChromeUtils.importESModule(
);
let accountsTab;
let imapAccount;
add_setup(async function () {
imapAccount = MailServices.accounts.createAccount();
imapAccount.incomingServer = MailServices.accounts.createIncomingServer(
"user",
"imap-l10n.invalid",
"imap"
);
imapAccount.incomingServer.prettyName = "IMAP Localization";
const identity = MailServices.accounts.createIdentity();
identity.email = "imap-l10n@example.invalid";
imapAccount.addIdentity(identity);
registerCleanupFunction(() => {
if (accountsTab) {
document.getElementById("tabmail").closeTab(accountsTab);
}
imapAccount.incomingServer.closeCachedConnections();
MailServices.accounts.removeAccount(imapAccount);
});
accountsTab = await openAccountSettings();
});
/**
* Opens the advanced settings subdialog from the selected account's server pane.
*
* @param {nsIMsgAccount} account - The account whose settings to show.
* @param {string} buttonId - The advanced settings button ID.
* @returns {Promise<Document>} The initialized subdialog document.
*/
async function openAdvancedSettings(account, buttonId) {
const row = get_account_tree_row(account.key, "am-server.xhtml", accountsTab);
await click_account_tree_row(accountsTab, row);
const managerDoc = accountsTab.browser.contentDocument;
const paneDoc = managerDoc.getElementById("contentFrame").contentDocument;
const opened = BrowserTestUtils.waitForEvent(
managerDoc.getElementById("dialogStack"),
"dialogopen"
);
const button = paneDoc.getElementById(buttonId);
button.scrollIntoView({ block: "center" });
EventUtils.synthesizeMouseAtCenter(button, {}, paneDoc.defaultView);
await opened;
const doc =
accountsTab.browser.contentWindow.gSubDialog._topDialog._frame
.contentDocument;
await doc.l10n.ready;
return doc;
}
/**
* Checks the assigned Fluent IDs and rendered text or attributes in a dialog.
*
* @param {Document} doc - The advanced settings document.
* @param {Array<[string, string, string[]]>} entries - Selectors, message IDs,
* and translated attribute names. An empty attribute list checks text content.
*/
async function checkLocalization(doc, entries) {
const messages = await doc.l10n.formatMessages(
entries.map(([, id]) => ({ id }))
);
for (const [index, [selector, id, attributes]] of entries.entries()) {
const element = doc.querySelector(selector);
Assert.ok(element, `${id} should have a target element`);
Assert.equal(
doc.l10n.getAttributes(element).id,
id,
`${id} should be assigned to its target element`
);
Assert.ok(
BrowserTestUtils.isVisible(element),
`${id} should be visible for this protocol`
);
const message = messages[index];
if (attributes.length) {
for (const name of attributes) {
const expected = message.attributes.find(
attr => attr.name == name
).value;
Assert.ok(expected, `${id}.${name} should have a translated value`);
Assert.equal(
element.getAttribute(name),
expected,
`${id} should apply its translated ${name} attribute`
);
}
} else {
Assert.ok(message.value, `${id} should have translated text`);
Assert.equal(
element.textContent,
message.value,
`${id} should display its translated text`
);
}
}
Assert.equal(
doc.l10n.getAttributes(doc.querySelector("title")).id,
"account-settings-advanced-server-title",
"The advanced dialog should use its localized title"
);
const title = await doc.l10n.formatValue(
"account-settings-advanced-server-title"
);
Assert.equal(
doc.title,
title,
"The advanced dialog title should be localized"
);
}
/**
* Cancels the advanced settings dialog and waits for it to close.
*
* @param {Document} doc - The advanced settings document.
*/
async function closeAdvancedSettings(doc) {
const closed = BrowserTestUtils.waitForEvent(
accountsTab.browser.contentDocument.getElementById("dialogStack"),
"dialogclose"
);
doc.querySelector("dialog").cancelDialog();
await closed;
}
add_task(async function test_imapLocalization() {
const doc = await openAdvancedSettings(
imapAccount,
"server.imapAdvancedButton"
);
Assert.ok(
BrowserTestUtils.isHidden(doc.getElementById("pop3Panel")),
"The POP settings should be hidden for IMAP"
);
await checkLocalization(doc, [
[
"#serverDirectoryLabel",
"account-settings-imap-server-directory",
["value", "accesskey"],
],
[
"#usingSubscription",
"account-settings-imap-show-subscribed-folders",
["label", "accesskey"],
],
[
"#dualUseFolders",
"account-settings-imap-dual-use-folders",
["label", "accesskey"],
],
[
"#maximumConnectionsNumberLabel",
"account-settings-imap-maximum-connections",
["value", "accesskey"],
],
[
"#imapPanel > description",
"account-settings-imap-namespace-description",
[],
],
[
"#personalNamespaceLabel",
"account-settings-imap-personal-namespace",
["value", "accesskey"],
],
[
"#publicNamespaceLabel",
"account-settings-imap-public-namespace",
["value", "accesskey"],
],
[
"#otherUsersNamespaceLabel",
"account-settings-imap-other-users-namespace",
["value", "accesskey"],
],
[
"#overrideNamespaces",
"account-settings-imap-override-namespaces",
["label", "accesskey"],
],
]);
const directory = doc.getElementById("serverDirectory");
directory.value = "Custom Directory";
const usingSubscription = doc.getElementById("usingSubscription");
usingSubscription.checked = !usingSubscription.checked;
const expectedChecked = usingSubscription.checked;
await doc.l10n.translateFragment(doc.documentElement);
Assert.equal(
directory.value,
"Custom Directory",
"Retranslation should preserve the edited server directory"
);
Assert.equal(
usingSubscription.checked,
expectedChecked,
"Retranslation should preserve the subscription setting"
);
await closeAdvancedSettings(doc);
});
add_task(async function test_popLocalization() {
const doc = await openAdvancedSettings(
MailServices.accounts.getAccount("account2"),
"server.popAdvancedButton"
);
Assert.ok(
BrowserTestUtils.isHidden(doc.getElementById("imapPanel")),
"The IMAP settings should be hidden for POP"
);
await checkLocalization(doc, [
[
'#pop3Panel > label[control="folderStorage"]',
"account-settings-pop-inbox-description",
[],
],
[
"#deferToCurrentAccount",
"account-settings-pop-inbox-current-account",
["label", "accesskey"],
],
[
"#deferToOtherAccount",
"account-settings-pop-inbox-other-account",
["label", "accesskey"],
],
[
"#deferGetNewMail",
"account-settings-pop-include-server",
["label", "accesskey"],
],
]);
Assert.equal(
doc.getElementById("folderStorage").value,
"currentAccount",
"The account should initially keep its own inbox"
);
Assert.ok(
doc.getElementById("deferredServerFolderPicker").disabled,
"The other account picker should initially be disabled"
);
await closeAdvancedSettings(doc);
});