Bug 1588831 - Add a mochitest for mailing lists. r=darktrojan
This commit is contained in:
Родитель
22b95b6daf
Коммит
9a8454e3aa
|
@ -9,6 +9,7 @@
|
|||
// Wrap in a block to prevent leaking to window scope.
|
||||
{
|
||||
const { MailServices } = ChromeUtils.import("resource:///modules/MailServices.jsm");
|
||||
const { MailUtils } = ChromeUtils.import("resource:///modules/MailUtils.jsm");
|
||||
|
||||
/**
|
||||
* MozCalendarEventFreebusyTimebar is a widget showing the time slot labels - dates and a number of
|
||||
|
@ -764,43 +765,7 @@
|
|||
*/
|
||||
_resolveListByName(value) {
|
||||
let entries = MailServices.headerParser.makeFromDisplayAddress(value);
|
||||
return entries.length ? this._findListInAddrBooks(entries[0].name) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds list in the address books.
|
||||
*
|
||||
* @param {String} entryName Value against which dirName is checked
|
||||
* @returns {Object} Found list or null
|
||||
*/
|
||||
_findListInAddrBooks(entryname) {
|
||||
let allAddressBooks = MailServices.ab.directories;
|
||||
|
||||
while (allAddressBooks.hasMoreElements()) {
|
||||
let abDir = null;
|
||||
try {
|
||||
abDir = allAddressBooks.getNext().QueryInterface(Ci.nsIAbDirectory);
|
||||
} catch (ex) {
|
||||
cal.WARN("[eventDialog] Error Encountered" + ex);
|
||||
}
|
||||
|
||||
if (abDir != null && abDir.supportsMailingLists) {
|
||||
let dirs = abDir.childNodes;
|
||||
while (dirs.hasMoreElements()) {
|
||||
let dir = null;
|
||||
try {
|
||||
dir = dirs.getNext().QueryInterface(Ci.nsIAbDirectory);
|
||||
} catch (ex) {
|
||||
cal.WARN("[eventDialog] Error Encountered" + ex);
|
||||
}
|
||||
|
||||
if (dir && dir.isMailList && dir.dirName == entryname) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return entries.length ? MailUtils.findListInAddressBooks(entries[0].name) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -533,4 +533,30 @@ var MailUtils = {
|
|||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds a mailing list anywhere in the address books.
|
||||
*
|
||||
* @param {string} entryName - Value against which dirName is checked.
|
||||
* @returns {nsIAbDirectory|null} - Found list or null.
|
||||
*/
|
||||
findListInAddressBooks(entryName) {
|
||||
let allAddressBooks = MailServices.ab.directories;
|
||||
|
||||
while (allAddressBooks.hasMoreElements()) {
|
||||
let abDir = allAddressBooks.getNext().QueryInterface(Ci.nsIAbDirectory);
|
||||
|
||||
if (abDir.supportsMailingLists) {
|
||||
let dirs = abDir.childNodes;
|
||||
|
||||
while (dirs.hasMoreElements()) {
|
||||
let dir = dirs.getNext().QueryInterface(Ci.nsIAbDirectory);
|
||||
if (dir.isMailList && dir.dirName == entryName) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -530,10 +530,17 @@ function SetStatusText(total) {
|
|||
).replace("#1", total);
|
||||
}
|
||||
} else {
|
||||
statusText = gAddressBookBundle.getFormattedString("totalContactStatus", [
|
||||
getSelectedDirectory().dirName,
|
||||
total,
|
||||
]);
|
||||
let selectedDirectory = getSelectedDirectory();
|
||||
// The result of getSelectedDirectory may be null, like when there's a
|
||||
// mailing list just being created in a brand new address book.
|
||||
if (selectedDirectory) {
|
||||
statusText = gAddressBookBundle.getFormattedString(
|
||||
"totalContactStatus",
|
||||
[selectedDirectory.dirName, total]
|
||||
);
|
||||
} else {
|
||||
statusText = "";
|
||||
}
|
||||
}
|
||||
|
||||
gStatusText.setAttribute("value", statusText);
|
||||
|
|
|
@ -4,17 +4,11 @@
|
|||
|
||||
let gAccount, gFolders;
|
||||
|
||||
function treeClick(tree, row, column, event) {
|
||||
let coords = tree.getCoordsForCellItem(row, tree.columns[column], "cell");
|
||||
let treeChildren = tree.lastElementChild;
|
||||
EventUtils.synthesizeMouse(
|
||||
treeChildren,
|
||||
coords.x + coords.width / 2,
|
||||
coords.y + coords.height / 2,
|
||||
event,
|
||||
window
|
||||
);
|
||||
}
|
||||
const { mailTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/mailnews/mailTestUtils.js"
|
||||
);
|
||||
|
||||
const treeClick = mailTestUtils.treeClick.bind(null, EventUtils, window);
|
||||
|
||||
async function checkEvent(extension, menuIds, contexts) {
|
||||
let [event, tab] = await extension.awaitMessage("onShown");
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[DEFAULT]
|
||||
head = head.js
|
||||
prefs =
|
||||
ldap_2.servers.osx.description=
|
||||
ldap_2.servers.osx.dirType=-1
|
||||
ldap_2.servers.osx.uri=
|
||||
mail.provider.suppress_dialog_on_startup=true
|
||||
mail.spotlight.firstRunDone=true
|
||||
mail.winsearch.firstRunDone=true
|
||||
mailnews.start_page.override_url=about:blank
|
||||
mailnews.start_page.url=about:blank
|
||||
subsuite = thunderbird
|
||||
|
||||
[browser_mailing_lists.js]
|
|
@ -0,0 +1,483 @@
|
|||
/* 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/. */
|
||||
|
||||
/* globals DisplayNameUtils, fixIterator, MailServices, MailUtils */
|
||||
|
||||
const { mailTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/mailnews/mailTestUtils.js"
|
||||
);
|
||||
|
||||
const inputs = {
|
||||
abName: "Mochitest Address Book",
|
||||
mlName: "Mochitest Mailing List",
|
||||
nickName: "Nicky",
|
||||
description: "Just a test mailing list.",
|
||||
addresses: [
|
||||
"alan@example.com",
|
||||
"betty@example.com",
|
||||
"clyde@example.com",
|
||||
"deb@example.com",
|
||||
],
|
||||
modification: " (modified)",
|
||||
};
|
||||
|
||||
const getDisplayedAddress = address => `${address} <${address}>`;
|
||||
|
||||
let global = {};
|
||||
|
||||
/**
|
||||
* Set up: create a new address book to hold the mailing list.
|
||||
*/
|
||||
add_task(async () => {
|
||||
let abWindow = await openAddressBookWindow();
|
||||
let addressBook = await createNewAddressBook(abWindow, inputs.abName);
|
||||
|
||||
let dirTree = abWindow.document.getElementById("dirTree");
|
||||
|
||||
/**
|
||||
* Click a row in the address book list (tree).
|
||||
*
|
||||
* @param {number} row - The tree row to click.
|
||||
* @param {number} clickCount - Number of clicks to synthesize.
|
||||
*/
|
||||
let dirTreeClick = (row, clickCount) => {
|
||||
mailTestUtils.treeClick(EventUtils, abWindow, dirTree, row, 0, {
|
||||
clickCount,
|
||||
});
|
||||
};
|
||||
|
||||
global = {
|
||||
abWindow,
|
||||
addressBook,
|
||||
dirTree,
|
||||
dirTreeClick,
|
||||
mailListUID: undefined,
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a new mailing list with some addresses, in the new address book.
|
||||
*/
|
||||
add_task(async () => {
|
||||
let mailingListWindowPromise = BrowserTestUtils.promiseAlertDialog(
|
||||
null,
|
||||
"chrome://messenger/content/addressbook/abMailListDialog.xul",
|
||||
// A callback that can interact with the mailing list dialog.
|
||||
async mlWindow => {
|
||||
let mlDocument = mlWindow.document;
|
||||
let mlDocElement = mlDocument.documentElement;
|
||||
|
||||
let listName = mlDocument.getElementById("ListName");
|
||||
let listNameFocusEvent = await BrowserTestUtils.waitForEvent(
|
||||
listName,
|
||||
"focus"
|
||||
);
|
||||
|
||||
let abPopup = mlDocument.getElementById("abPopup");
|
||||
let listNickName = mlDocument.getElementById("ListNickName");
|
||||
let listDescription = mlDocument.getElementById("ListDescription");
|
||||
let addressInput1 = mlDocument.getElementById("addressCol1#1");
|
||||
let addressInputsCount = mlDocument
|
||||
.getElementById("addressingWidget")
|
||||
.querySelectorAll("input").length;
|
||||
|
||||
is(
|
||||
abPopup.label,
|
||||
global.addressBook.dirName,
|
||||
"the correct address book is selected in the menu"
|
||||
);
|
||||
is(
|
||||
abPopup.value,
|
||||
global.addressBook.URI,
|
||||
"the address book selected in the menu has the correct address book URI"
|
||||
);
|
||||
is(listNameFocusEvent.type, "focus", "list name field is focused");
|
||||
is(listName.value, "", "no text in the list name field");
|
||||
is(listNickName.value, "", "no text in the list nickname field");
|
||||
is(listDescription.value, "", "no text in the description field");
|
||||
is(addressInput1.value, "", "no text in the addresses list");
|
||||
is(addressInputsCount, 1, "only one address list input exists");
|
||||
|
||||
EventUtils.sendString(inputs.mlName, mlWindow);
|
||||
|
||||
// Tab to nickname input.
|
||||
EventUtils.sendKey("TAB", mlWindow);
|
||||
EventUtils.sendString(inputs.nickName, mlWindow);
|
||||
|
||||
// Tab to description input.
|
||||
EventUtils.sendKey("TAB", mlWindow);
|
||||
EventUtils.sendString(inputs.description, mlWindow);
|
||||
|
||||
// Tab to address input and add addresses zero and one by entering
|
||||
// both of them there.
|
||||
EventUtils.sendKey("TAB", mlWindow);
|
||||
EventUtils.sendString(inputs.addresses.slice(0, 2).join(", "), mlWindow);
|
||||
|
||||
mlDocElement.getButton("accept").click();
|
||||
}
|
||||
);
|
||||
|
||||
is(
|
||||
global.dirTree.view.getCellText(2, global.dirTree.columns[0]),
|
||||
inputs.abName,
|
||||
`address book ("${inputs.abName}") is displayed in the address book list`
|
||||
);
|
||||
|
||||
// Select the address book.
|
||||
global.dirTreeClick(2, 1);
|
||||
|
||||
// Open the new mailing list dialog, the callback above interacts with it.
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
global.abWindow.document.getElementById("button-newlist"),
|
||||
{ clickCount: 1 },
|
||||
global.abWindow
|
||||
);
|
||||
|
||||
await mailingListWindowPromise;
|
||||
|
||||
// Confirm that the mailing list and addresses were saved in the backend.
|
||||
|
||||
ok(
|
||||
DisplayNameUtils.getCardForEmail(inputs.addresses[0]).card,
|
||||
"address zero was saved"
|
||||
);
|
||||
ok(
|
||||
DisplayNameUtils.getCardForEmail(inputs.addresses[1]).card,
|
||||
"address one was saved"
|
||||
);
|
||||
|
||||
let childCards = [...global.addressBook.childCards];
|
||||
|
||||
ok(
|
||||
childCards.find(card => card.primaryEmail == inputs.addresses[0]),
|
||||
"address zero was saved in the correct address book"
|
||||
);
|
||||
ok(
|
||||
childCards.find(card => card.primaryEmail == inputs.addresses[1]),
|
||||
"address one was saved in the correct address book"
|
||||
);
|
||||
|
||||
let mailList = MailUtils.findListInAddressBooks(inputs.mlName);
|
||||
|
||||
// Save the mailing list UID so we can confirm it is the same later.
|
||||
global.mailListUID = mailList.UID;
|
||||
|
||||
ok(mailList, "mailing list was created");
|
||||
ok(
|
||||
global.addressBook.hasMailListWithName(inputs.mlName),
|
||||
"mailing list was created in the correct address book"
|
||||
);
|
||||
is(mailList.dirName, inputs.mlName, "mailing list name was saved");
|
||||
is(
|
||||
mailList.listNickName,
|
||||
inputs.nickName,
|
||||
"mailing list nick name was saved"
|
||||
);
|
||||
is(
|
||||
mailList.description,
|
||||
inputs.description,
|
||||
"mailing list description was saved"
|
||||
);
|
||||
|
||||
let listCards = [...fixIterator(mailList.addressLists, Ci.nsIAbCard)];
|
||||
|
||||
ok(
|
||||
listCards[0].hasEmailAddress(inputs.addresses[0]),
|
||||
"address zero was saved in the mailing list"
|
||||
);
|
||||
ok(
|
||||
listCards[1].hasEmailAddress(inputs.addresses[1]),
|
||||
"address one was saved in the mailing list"
|
||||
);
|
||||
is(listCards.length, 2, "two cards exist in the mailing list");
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the mailing list dialog and modify the mailing list.
|
||||
*/
|
||||
add_task(async () => {
|
||||
let mailingListWindowPromise = BrowserTestUtils.promiseAlertDialog(
|
||||
null,
|
||||
"chrome://messenger/content/addressbook/abEditListDialog.xul",
|
||||
// A callback that can interact with the mailing list dialog.
|
||||
async mlWindow => {
|
||||
let mlDocument = mlWindow.document;
|
||||
let mlDocElement = mlDocument.documentElement;
|
||||
|
||||
// The address input nodes are not there yet when the dialog window is
|
||||
// loaded, so wait until they exist.
|
||||
await mailTestUtils.awaitElementExistence(
|
||||
MutationObserver,
|
||||
mlDocument,
|
||||
"addressingWidget",
|
||||
"addressCol1#3"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.waitForEvent(
|
||||
mlDocument.getElementById("addressCol1#3"),
|
||||
"focus"
|
||||
);
|
||||
|
||||
let listName = mlDocument.getElementById("ListName");
|
||||
let listNickName = mlDocument.getElementById("ListNickName");
|
||||
let listDescription = mlDocument.getElementById("ListDescription");
|
||||
let addressInput1 = mlDocument.getElementById("addressCol1#1");
|
||||
let addressInput2 = mlDocument.getElementById("addressCol1#2");
|
||||
|
||||
is(listName.value, inputs.mlName, "list name is displayed correctly");
|
||||
is(
|
||||
listNickName.value,
|
||||
inputs.nickName,
|
||||
"list nickname is displayed correctly"
|
||||
);
|
||||
is(
|
||||
listDescription.value,
|
||||
inputs.description,
|
||||
"list description is displayed correctly"
|
||||
);
|
||||
is(
|
||||
addressInput1 && addressInput1.value,
|
||||
getDisplayedAddress(inputs.addresses[0]),
|
||||
"address zero is displayed correctly"
|
||||
);
|
||||
is(
|
||||
addressInput2 && addressInput2.value,
|
||||
getDisplayedAddress(inputs.addresses[1]),
|
||||
"address one is displayed correctly"
|
||||
);
|
||||
|
||||
let textInputs = mlDocument.querySelectorAll(".textbox-addressingWidget");
|
||||
is(textInputs.length, 3, "no extraneous addresses are displayed");
|
||||
|
||||
// Add addresses two and three.
|
||||
EventUtils.sendString(inputs.addresses.slice(2, 4).join(", "), mlWindow);
|
||||
EventUtils.sendKey("RETURN", mlWindow);
|
||||
await new Promise(resolve => mlWindow.setTimeout(resolve));
|
||||
|
||||
// Delete the address in the second row (address one).
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
addressInput2,
|
||||
{ clickCount: 1 },
|
||||
mlWindow
|
||||
);
|
||||
EventUtils.synthesizeKey("a", { accelKey: true }, mlWindow);
|
||||
EventUtils.sendKey("BACK_SPACE", mlWindow);
|
||||
|
||||
// Modify the list's name, nick name, and description fields.
|
||||
let modifyField = id => {
|
||||
EventUtils.synthesizeMouseAtCenter(id, { clickCount: 1 }, mlWindow);
|
||||
EventUtils.sendKey("END", mlWindow);
|
||||
EventUtils.sendString(inputs.modification, mlWindow);
|
||||
};
|
||||
modifyField(listName);
|
||||
modifyField(listNickName);
|
||||
modifyField(listDescription);
|
||||
|
||||
mlDocElement.getButton("accept").click();
|
||||
}
|
||||
);
|
||||
|
||||
is(
|
||||
global.dirTree.view.getCellText(2, global.dirTree.columns[0]),
|
||||
inputs.abName,
|
||||
`address book ("${inputs.abName}") is displayed in the address book list`
|
||||
);
|
||||
|
||||
// Double-click on the address book name to reveal the mailing list.
|
||||
global.dirTreeClick(2, 2);
|
||||
|
||||
is(
|
||||
global.dirTree.view.getCellText(3, global.dirTree.columns[0]),
|
||||
inputs.mlName,
|
||||
`mailing list ("${inputs.mlName}") is displayed in the address book list`
|
||||
);
|
||||
|
||||
// Open the mailing list dialog, the callback above interacts with it.
|
||||
global.dirTreeClick(3, 2);
|
||||
|
||||
await mailingListWindowPromise;
|
||||
|
||||
// Confirm that the mailing list and addresses were saved in the backend.
|
||||
|
||||
ok(
|
||||
DisplayNameUtils.getCardForEmail(inputs.addresses[2]).card,
|
||||
"address two was saved"
|
||||
);
|
||||
ok(
|
||||
DisplayNameUtils.getCardForEmail(inputs.addresses[3]).card,
|
||||
"address three was saved"
|
||||
);
|
||||
|
||||
let childCards = [...global.addressBook.childCards];
|
||||
|
||||
ok(
|
||||
childCards.find(card => card.primaryEmail == inputs.addresses[2]),
|
||||
"address two was saved in the correct address book"
|
||||
);
|
||||
ok(
|
||||
childCards.find(card => card.primaryEmail == inputs.addresses[3]),
|
||||
"address three was saved in the correct address book"
|
||||
);
|
||||
|
||||
let mailList = MailUtils.findListInAddressBooks(
|
||||
inputs.mlName + inputs.modification
|
||||
);
|
||||
|
||||
is(mailList && mailList.UID, global.mailListUID, "mailing list still exists");
|
||||
|
||||
ok(
|
||||
global.addressBook.hasMailListWithName(inputs.mlName + inputs.modification),
|
||||
"mailing list is still in the correct address book"
|
||||
);
|
||||
is(
|
||||
mailList.dirName,
|
||||
inputs.mlName + inputs.modification,
|
||||
"modified mailing list name was saved"
|
||||
);
|
||||
is(
|
||||
mailList.listNickName,
|
||||
inputs.nickName + inputs.modification,
|
||||
"modified mailing list nick name was saved"
|
||||
);
|
||||
is(
|
||||
mailList.description,
|
||||
inputs.description + inputs.modification,
|
||||
"modified mailing list description was saved"
|
||||
);
|
||||
|
||||
let listCards = [...fixIterator(mailList.addressLists, Ci.nsIAbCard)];
|
||||
|
||||
ok(
|
||||
listCards[0].hasEmailAddress(inputs.addresses[0]),
|
||||
"address zero was saved in the mailing list (is still there)"
|
||||
);
|
||||
ok(
|
||||
listCards[1].hasEmailAddress(inputs.addresses[2]),
|
||||
"address two was saved in the mailing list"
|
||||
);
|
||||
ok(
|
||||
listCards[2].hasEmailAddress(inputs.addresses[3]),
|
||||
"address three was saved in the mailing list"
|
||||
);
|
||||
|
||||
let hasAddressOne = listCards.find(card =>
|
||||
card.hasEmailAddress(inputs.addresses[1])
|
||||
);
|
||||
|
||||
ok(!hasAddressOne, "address one was deleted from the mailing list");
|
||||
|
||||
is(listCards.length, 3, "three cards exist in the mailing list");
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the mailing list dialog and confirm the changes are displayed.
|
||||
*/
|
||||
add_task(async () => {
|
||||
let mailingListWindowPromise = BrowserTestUtils.promiseAlertDialog(
|
||||
null,
|
||||
"chrome://messenger/content/addressbook/abEditListDialog.xul",
|
||||
// A callback that can interact with the mailing list dialog.
|
||||
async mailingListWindow => {
|
||||
let mlDocument = mailingListWindow.document;
|
||||
let mlDocElement = mlDocument.documentElement;
|
||||
|
||||
// The address input nodes are not there yet when the dialog window is
|
||||
// loaded, so wait until they exist.
|
||||
await mailTestUtils.awaitElementExistence(
|
||||
MutationObserver,
|
||||
mlDocument,
|
||||
"addressingWidget",
|
||||
"addressCol1#4"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.waitForEvent(
|
||||
mlDocument.getElementById("addressCol1#4"),
|
||||
"focus"
|
||||
);
|
||||
|
||||
let listName = mlDocument.getElementById("ListName");
|
||||
let listNickName = mlDocument.getElementById("ListNickName");
|
||||
let listDescription = mlDocument.getElementById("ListDescription");
|
||||
let addressInput1 = mlDocument.getElementById("addressCol1#1");
|
||||
let addressInput2 = mlDocument.getElementById("addressCol1#2");
|
||||
let addressInput3 = mlDocument.getElementById("addressCol1#3");
|
||||
|
||||
is(
|
||||
listName.value,
|
||||
inputs.mlName + inputs.modification,
|
||||
"modified list name is displayed correctly"
|
||||
);
|
||||
is(
|
||||
listNickName.value,
|
||||
inputs.nickName + inputs.modification,
|
||||
"modified list nickname is displayed correctly"
|
||||
);
|
||||
is(
|
||||
listDescription.value,
|
||||
inputs.description + inputs.modification,
|
||||
"modified list description is displayed correctly"
|
||||
);
|
||||
is(
|
||||
addressInput1 && addressInput1.value,
|
||||
getDisplayedAddress(inputs.addresses[0]),
|
||||
"address zero is displayed correctly (is still there)"
|
||||
);
|
||||
is(
|
||||
addressInput2 && addressInput2.value,
|
||||
getDisplayedAddress(inputs.addresses[2]),
|
||||
"address two is displayed correctly"
|
||||
);
|
||||
is(
|
||||
addressInput3 && addressInput3.value,
|
||||
getDisplayedAddress(inputs.addresses[3]),
|
||||
"address three is displayed correctly"
|
||||
);
|
||||
|
||||
let textInputs = mlDocument.querySelectorAll(".textbox-addressingWidget");
|
||||
is(textInputs.length, 4, "no extraneous addresses are displayed");
|
||||
|
||||
mlDocElement.getButton("cancel").click();
|
||||
}
|
||||
);
|
||||
|
||||
is(
|
||||
global.dirTree.view.getCellText(3, global.dirTree.columns[0]),
|
||||
inputs.mlName,
|
||||
`mailing list ("${inputs.mlName}") is displayed in the address book list`
|
||||
);
|
||||
|
||||
// Open the mailing list dialog, the callback above interacts with it.
|
||||
global.dirTreeClick(3, 2);
|
||||
|
||||
await mailingListWindowPromise;
|
||||
});
|
||||
|
||||
/**
|
||||
* Tear down: delete the address book and close the address book window.
|
||||
*/
|
||||
add_task(async () => {
|
||||
let mailingListWindowPromise = BrowserTestUtils.promiseAlertDialog(
|
||||
"accept",
|
||||
"chrome://global/content/commonDialog.xul"
|
||||
);
|
||||
|
||||
is(
|
||||
global.dirTree.view.getCellText(2, global.dirTree.columns[0]),
|
||||
inputs.abName,
|
||||
`address book ("${inputs.abName}") is displayed in the address book list`
|
||||
);
|
||||
|
||||
global.dirTreeClick(2, 1);
|
||||
EventUtils.sendKey("DELETE", global.abWindow);
|
||||
|
||||
await mailingListWindowPromise;
|
||||
|
||||
let addressBook = [...MailServices.ab.directories].find(
|
||||
directory => directory.dirName == inputs.abName
|
||||
);
|
||||
|
||||
ok(!addressBook, "address book was deleted");
|
||||
|
||||
global.abWindow.close();
|
||||
});
|
|
@ -0,0 +1,55 @@
|
|||
/* 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/. */
|
||||
|
||||
/* globals MailServices */
|
||||
|
||||
async function openAddressBookWindow() {
|
||||
let addressBookWindowPromise = BrowserTestUtils.domWindowOpened(
|
||||
null,
|
||||
async win => {
|
||||
// This test function waits until the "load" event has happened.
|
||||
await BrowserTestUtils.waitForEvent(win, "load");
|
||||
|
||||
return (
|
||||
win.document.documentURI ==
|
||||
"chrome://messenger/content/addressbook/addressbook.xul"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const addressBookButton = document.getElementById("button-address");
|
||||
EventUtils.synthesizeMouseAtCenter(addressBookButton, { clickCount: 1 });
|
||||
|
||||
let abWindow = await addressBookWindowPromise;
|
||||
|
||||
await new Promise(resolve => abWindow.setTimeout(resolve));
|
||||
|
||||
ok(abWindow && abWindow instanceof Window, "address book window was opened");
|
||||
|
||||
return abWindow;
|
||||
}
|
||||
|
||||
async function createNewAddressBook(abWindow, abName) {
|
||||
let newAddressBookPromise = BrowserTestUtils.promiseAlertDialog(
|
||||
null,
|
||||
"chrome://messenger/content/addressbook/abAddressBookNameDialog.xul",
|
||||
abNameDialog => {
|
||||
EventUtils.sendString(abName, abNameDialog);
|
||||
abNameDialog.document.documentElement.getButton("accept").click();
|
||||
}
|
||||
);
|
||||
|
||||
// Using the UI was unreliable so just call the function.
|
||||
abWindow.AbNewAddressBook();
|
||||
|
||||
await newAddressBookPromise;
|
||||
|
||||
let addressBook = [...MailServices.ab.directories].find(
|
||||
directory => directory.dirName == abName
|
||||
);
|
||||
|
||||
ok(addressBook, "a new address book was created");
|
||||
|
||||
return addressBook;
|
||||
}
|
|
@ -7,3 +7,7 @@ XPCSHELL_TESTS_MANIFESTS += [
|
|||
'unit/xpcshell-jsaddrbook.ini',
|
||||
'unit/xpcshell-mdbaddrbook.ini',
|
||||
]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
'browser/browser.ini',
|
||||
]
|
||||
|
|
|
@ -548,4 +548,61 @@ var mailTestUtils = {
|
|||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Click on a particular cell in a tree. `window` is not defined here in this
|
||||
* file, so we can't provide it as a default argument. Similarly, we pass in
|
||||
* `EventUtils` as an argument because importing it here does not work
|
||||
* because `window` is not defined.
|
||||
*
|
||||
* @param {Object} EventUtils - The EventUtils object.
|
||||
* @param {Window} win - The window the tree is in.
|
||||
* @param {Element} tree - The tree element.
|
||||
* @param {number} row - The tree row to click on.
|
||||
* @param {number} column - The tree column to click on.
|
||||
* @param {Object} event - The mouse event to synthesize, e.g. `{ clickCount: 2 }`.
|
||||
*/
|
||||
treeClick(EventUtils, win, tree, row, column, event) {
|
||||
let coords = tree.getCoordsForCellItem(row, tree.columns[column], "cell");
|
||||
let treeChildren = tree.lastElementChild;
|
||||
EventUtils.synthesizeMouse(
|
||||
treeChildren,
|
||||
coords.x + coords.width / 2,
|
||||
coords.y + coords.height / 2,
|
||||
event,
|
||||
win
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* For waiting until an element exists in a given document. Pass in the
|
||||
* `MutationObserver` as an argument because importing it here does not work
|
||||
* because `window` is not defined here.
|
||||
*
|
||||
* @param {Object} MutationObserver - The MutationObserver object.
|
||||
* @param {Document} doc - Document that contains the elements.
|
||||
* @param {string} observedNodeId - Id of the element to observe.
|
||||
* @param {string} awaitedNodeId - Id of the element that will soon exist.
|
||||
* @return {Promise.<undefined>} - A promise fulfilled when the element exists.
|
||||
*/
|
||||
awaitElementExistence(MutationObserver, doc, observedNodeId, awaitedNodeId) {
|
||||
return new Promise(resolve => {
|
||||
let outerObserver = new MutationObserver((mutationsList, observer) => {
|
||||
for (let mutation of mutationsList) {
|
||||
if (mutation.type == "childList" && mutation.addedNodes.length) {
|
||||
let element = doc.getElementById(awaitedNodeId);
|
||||
|
||||
if (element) {
|
||||
observer.disconnect();
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let nodeToObserve = doc.getElementById(observedNodeId);
|
||||
outerObserver.observe(nodeToObserve, { childList: true });
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче