async function promiseLibraryClosed(organizer) { if (organizer.closed) { return;
} // Wait for the Organizer window to actually be closed.
let promiseClosed = BrowserTestUtils.domWindowClosed(organizer);
organizer.close();
await promiseClosed;
}
function checkLibraryPaneVisibility(library, selectedPane) { // Make sure right view is shown if (selectedPane == "Downloads") { Assert.ok(
library.ContentTree.view.hidden, "Bookmark/History tree is hidden"
); Assert.ok(
!library.document.getElementById("downloadsListBox").hidden, "Downloads are shown"
);
} else { Assert.ok(
!library.ContentTree.view.hidden, "Bookmark/History tree is shown"
); Assert.ok(
library.document.getElementById("downloadsListBox").hidden, "Downloads are hidden"
);
}
// Check currentView getter Assert.ok(!library.ContentArea.currentView.hidden, "Current view is shown");
}
async function synthesizeClickOnSelectedTreeCell(aTree, aOptions) { if (aTree.view.selection.count < 1) { thrownew Error("The test node should be successfully selected");
}
await TestUtils.waitForCondition(
() => aTree.getBoundingClientRect().width > 0, "Tree should have non-zero width before clicking"
); // Get selection rowID.
let min = {},
max = {};
aTree.view.selection.getRangeAt(0, min, max);
let rowID = min.value;
aTree.ensureRowIsVisible(rowID); // Calculate the click coordinates. var rect = aTree.getCoordsForCellItem(rowID, aTree.columns[0], "text"); var x = rect.x + rect.width / 2; var y = rect.y + rect.height / 2; if (aTree.id == "bookmarks-view" || aTree.id == "historyTree") { // We are purposefully keeping the main <tree> element unlabeled, because in // this specific case, the on-screen label for either "Bookmarks" or // "History" sidebar is positioned closely to the tree, visually and in DOM. // We want to avoid making a screen reader user to listen to a redundant // announcement, therefore no accessible name is provided to the container // and we account for this in a11y-checks:
AccessibilityUtils.setEnv({
labelRule: false,
});
} // Simulate the click.
EventUtils.synthesizeMouse(
aTree.body,
x,
y,
aOptions || {},
aTree.documentGlobal
);
AccessibilityUtils.resetEnv();
}
/** *Executesataskafteropeningthebookmarksdialog,thencancelsthedialog. * *@param{boolean}autoCancel *whethertoautomaticallycancelthedialogattheendofthetask *@param{Function}openFn *generatorfunctioncausingthedialogtoopen *@param{Function}taskFn *thetasktoexecuteoncethedialogisopen *@param{Function}closeFn *Afunctiontobeusedtowaitforpendingworkwhenthedialogis *closing.Itispassedthedialogwindowhandleandshouldreturnapromise. *@returns{string}guid *Bookmarkguid
*/ var withBookmarksDialog = async function (autoCancel, openFn, taskFn, closeFn) {
let dialogUrl = "chrome://browser/content/places/bookmarkProperties.xhtml";
let closed = false; // We can't show the in-window prompt for windows which don't have // gDialogBox, like the library (Places:Organizer) window.
let hasDialogBox = !!Services.wm.getMostRecentWindow("").gDialogBox;
let dialogPromise; if (hasDialogBox) {
dialogPromise = BrowserTestUtils.promiseAlertDialogOpen(null, dialogUrl, {
isSubDialog: true,
});
} else {
dialogPromise = BrowserTestUtils.domWindowOpenedAndLoaded(null, win => { return win.document.documentURI.startsWith(dialogUrl);
}).then(win => {
ok(
win.location.href.startsWith(dialogUrl), "The bookmark properties dialog is open: " + win.location.href
); // This is needed for the overlay. return SimpleTest.promiseFocus(win).then(() => win);
});
}
let dialogClosePromise = dialogPromise.then(win => { if (!hasDialogBox) { return BrowserTestUtils.domWindowClosed(win);
}
let container = win.top.document.getElementById("window-modal-dialog"); return BrowserTestUtils.waitForEvent(container, "close").then(() => { return BrowserTestUtils.waitForMutationCondition(
container,
{ childList: true, attributes: true },
() => !container.hasChildNodes() && !container.open
);
});
});
dialogClosePromise.then(() => {
closed = true;
});
info("withBookmarksDialog: opening the dialog"); // The dialog might be modal and could block our events loop, so executeSoon.
executeSoon(openFn);
info("withBookmarksDialog: waiting for the dialog");
let dialogWin = await dialogPromise;
// Ensure overlay is loaded
info("waiting for the overlay to be loaded");
await dialogWin.document.mozSubdialogReady;
// Check the first input is focused.
let doc = dialogWin.document;
let elt = doc.querySelector('input:not([hidden="true"])');
ok(elt, "There should be an input to focus.");
if (elt) {
info("waiting for focus on the first textfield");
await TestUtils.waitForCondition(
() => doc.activeElement == elt, "The first non collapsed input should have been focused"
);
}
info("withBookmarksDialog: executing the task");
let closePromise = () => Promise.resolve(); if (closeFn) {
closePromise = closeFn(dialogWin);
}
let guid; try {
await taskFn(dialogWin);
} finally { if (!closed && autoCancel) {
info("withBookmarksDialog: canceling the dialog");
doc.getElementById("bookmarkpropertiesdialog").cancelDialog();
await closePromise;
}
guid = await PlacesUIUtils.lastBookmarkDialogDeferred.promise; // Give the dialog a little time to close itself.
await dialogClosePromise;
} return guid;
};
/** *Opensthecontextualmenuontheelementpointedbythegivenselector. * *@param{object}browser *Theassociatedbrowserelement. *@param{object}selector *Validselectorsyntax *@returns{Promise} *ReturnsaPromisethatresolvesoncethecontextmenuhasbeen *opened.
*/ var openContextMenuForContentSelector = async function (browser, selector) {
info("wait for the context menu");
let contextPromise = BrowserTestUtils.waitForEvent(
document.getElementById("contentAreaContextMenu"), "popupshown"
);
await SpecialPowers.spawn(browser, [{ selector }], async function (args) {
let doc = content.document;
let elt = doc.querySelector(args.selector);
dump(`openContextMenuForContentSelector: found ${elt}\n`);
/* Open context menu so chrome can access the element */
EventUtils.synthesizeMouseAtCenter(
elt,
{ type: "contextmenu", button: 2, clickCount: 1, buttons: 0 },
content
);
});
await contextPromise;
};
/** *Fillsabookmarksdialogtextfieldensuringtocauseexpectededitevents. * *@param{string}id *idofthetextfield *@param{string}text *texttofillin *@param{object}win *dialogwindow *@param{boolean}[blur] *whethertoblurattheend.
*/ function fillBookmarkTextField(id, text, win, blur = true) {
let elt = win.document.getElementById(id);
elt.focus();
elt.select(); if (!text) {
EventUtils.synthesizeKey("VK_DELETE", {}, win);
} else { for (let c of text.split("")) {
EventUtils.synthesizeKey(c, {}, win);
}
} if (blur) {
elt.blur();
}
}
/** *Executesataskafteropeningthebookmarksorhistorysidebar.Takescare *ofclosingthesidebaroncedone. * *@param{string}type *either"bookmarks"or"history". *@param{Function}taskFn *Thetasktoexecuteoncethesidebarisready.WillgetthePlaces *treeviewasinput. *@param{Window}[win] *Thewindowtoopenthesidebarin,elseusesthedefaultwindow.
*/ var withSidebarTree = async function (type, taskFn, win = window) {
let sidebar = win.document.getElementById("sidebar");
info("withSidebarTree: waiting sidebar load");
let sidebarLoadedPromise = new Promise(resolve => {
sidebar.addEventListener( "load", function () {
executeSoon(resolve);
},
{ capture: true, once: true }
);
});
let sidebarId =
type == "bookmarks" ? "viewBookmarksSidebar" : "viewHistorySidebar";
win.SidebarController.show(sidebarId);
await sidebarLoadedPromise;
let treeId = type == "bookmarks" ? "bookmarks-view" : "historyTree";
let tree = sidebar.contentDocument.getElementById(treeId);
// Need to executeSoon since the tree is initialized on sidebar load.
info("withSidebarTree: executing the task"); try {
await taskFn(tree);
} finally {
win.SidebarController.hide();
}
};
/** *ExecutesataskafteropeningtheLibraryonagivenroot.Takescare *ofclosingthelibraryoncedone. * *@param{string}hierarchy *Theleftpanehierarchytoopen. *@param{Function}taskFn *ThetasktoexecuteoncetheLibraryisready. *Willget{left,right}treesasargument. *@param{Window}[win] *Thewindowtousetoopenthelibrary.
*/ var withLibraryWindow = async function (hierarchy, taskFn, win = window) {
let library = await promiseLibrary(hierarchy, win);
let left = library.document.getElementById("placesList");
let right = library.document.getElementById("placeContent");
info("withLibrary: executing the task"); try {
await taskFn({ left, right });
} finally {
await promiseLibraryClosed(library);
}
};
function promisePlacesInitComplete() { const gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"].getService(
Ci.nsIObserver
);
let placesInitCompleteObserved = TestUtils.topicObserved( "places-browser-init-complete"
);
// Necessary to avoid intermittent failures in verify-fission where default // bookmarks may or may not have been imported yet.
await promisePlacesInitComplete();
await PlacesUtils.bookmarks.eraseEverything();
let toolbar = document.getElementById("PersonalToolbar");
let wasCollapsed = toolbar.collapsed; if (wasCollapsed) {
await promiseSetToolbarVisibility(toolbar, true);
await BrowserTestUtils.waitForEvent(
toolbar, "BookmarksToolbarVisibilityUpdated"
);
}
registerCleanupFunction(async () => { if (wasCollapsed) {
await promiseSetToolbarVisibility(toolbar, false);
} try {
await PlacesUtils.bookmarks.remove(bm);
} catch (ex) { // The bookmark may have been removed already.
}
});
await waitForBookmarksToolbarElements(1);
}
/** *EnsureNbookmarksarevisibleontheBookmarksToolbar. * *@param{integer}expectedCountThenumberofbookmarkstowaitfor. *@returns{Promise}resolvedwhentheconditionissatisfied.
*/ function waitForBookmarksToolbarElements(expectedCount) {
let container = document.getElementById("PlacesToolbarItems"); if (container.childElementCount == expectedCount) { return Promise.resolve();
} returnnew Promise(resolve => {
info("Waiting for bookmarks");
let mut = new MutationObserver(() => { if (container.childElementCount == expectedCount) {
resolve();
mut.disconnect();
}
});
mut.observe(container, { childList: true });
});
}
// Identify a bookmark node in the Bookmarks Toolbar by its guid. function getToolbarNodeForItemGuid(itemGuid, win = window) {
let children = win.document.getElementById("PlacesToolbarItems").childNodes; for (let child of children) { if (itemGuid === child._placesNode.bookmarkGuid) { return child;
}
} returnnull;
}
// Open the bookmarks Star UI by clicking the star button on the address bar.
async function clickBookmarkStar(win = window) {
let shownPromise = promisePopupShown(
win.document.getElementById("editBookmarkPanel")
);
win.BookmarkingUI.star.click();
await shownPromise;
// Additionally await for the async init to complete.
let menuList = win.document.getElementById("editBMPanel_folderMenuList");
await BrowserTestUtils.waitForMutationCondition(
menuList,
{ attributes: true },
() => !!menuList.getAttribute("selectedGuid"), "Should select the menu folder item"
);
}
// Close the bookmarks Star UI by clicking the "Done" button.
async function hideBookmarksPanel(win = window) {
let hiddenPromise = promisePopupHidden(
win.document.getElementById("editBookmarkPanel")
); // Confirm and close the dialog.
win.document.getElementById("editBookmarkPanelDoneButton").click();
await hiddenPromise;
}
// Create a temporary folder, set it as the default folder, // then remove the folder. This is used to ensure that the // default folder gets reset properly.
async function createAndRemoveDefaultFolder() {
let tempFolder = await PlacesUtils.bookmarks.insertTree({
guid: PlacesUtils.bookmarks.unfiledGuid,
children: [
{
title: "temp folder",
type: PlacesUtils.bookmarks.TYPE_FOLDER,
},
],
});
// Given a moz-input-search element, fill it with the query `query`. function setSearch(searchBox, query) { returnnew Promise(resolve => {
searchBox.addEventListener("MozInputSearch:search", resolve, {
once: true,
});
searchBox.select(); if (query) {
EventUtils.sendString(query, searchBox.documentGlobal);
} else {
searchBox.clear();
}
});
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.