Bug 1426250 - make tests actually pass valid mouse coordinates when testing Customize Mode, r?jaws
MozReview-Commit-ID: IglKedBqrWQ
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -2335,20 +2335,16 @@ CustomizeMode.prototype = {
return aElement.closest(areas.map(a => "#" + CSS.escape(a)).join(","));
},
_getDragOverNode(aEvent, aAreaElement, aAreaType, aDraggedItemId) {
let expectedParent = aAreaElement.customizationTarget || aAreaElement;
if (!expectedParent.contains(aEvent.target)) {
return expectedParent;
}
- // Our tests are stupid. Cope:
- if (!aEvent.clientX && !aEvent.clientY) {
- return aEvent.target;
- }
// Offset the drag event's position with the offset to the center of
// the thing we're dragging
let dragX = aEvent.clientX - this._dragOffset.x;
let dragY = aEvent.clientY - this._dragOffset.y;
// Ensure this is within the container
let boundsContainer = expectedParent;
let bounds = this._dwu.getBoundsWithoutFlushing(boundsContainer);
--- a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
+++ b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
@@ -9,53 +9,60 @@ const kAPIWidgetId = "feed-button";
const kPanel = CustomizableUI.AREA_FIXED_OVERFLOW_PANEL;
const kToolbar = CustomizableUI.AREA_NAVBAR;
const kVisiblePalette = "customization-palette";
function checkWrapper(id) {
is(document.querySelectorAll("#wrapper-" + id).length, 1, "There should be exactly 1 wrapper for " + id + " in the customizing window.");
}
-async function ensureVisibleIfInPalette(node) {
- if (node.parentNode.parentNode == gNavToolbox.palette) {
- node.scrollIntoView();
- window.QueryInterface(Ci.nsIInterfaceRequestor);
- let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
- await BrowserTestUtils.waitForCondition(() => {
- let nodeBounds = dwu.getBoundsWithoutFlushing(node);
- let paletteBounds = dwu.getBoundsWithoutFlushing(gNavToolbox.palette);
- return nodeBounds.top >= paletteBounds.top && nodeBounds.bottom <= paletteBounds.bottom;
- });
+async function ensureVisible(node) {
+ let isInPalette = node.parentNode.parentNode == gNavToolbox.palette;
+ if (isInPalette) {
+ node.scrollIntoView();
+ }
+ window.QueryInterface(Ci.nsIInterfaceRequestor);
+ let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
+ await BrowserTestUtils.waitForCondition(() => {
+ let nodeBounds = dwu.getBoundsWithoutFlushing(node);
+ if (isInPalette) {
+ let paletteBounds = dwu.getBoundsWithoutFlushing(gNavToolbox.palette);
+ if (!(nodeBounds.top >= paletteBounds.top && nodeBounds.bottom <= paletteBounds.bottom)) {
+ return false;
+ }
}
+ return nodeBounds.height && nodeBounds.width;
+ });
}
var move = {
"drag": async function(id, target) {
let targetNode = document.getElementById(target);
if (targetNode.customizationTarget) {
targetNode = targetNode.customizationTarget;
}
let nodeToMove = document.getElementById(id);
- await ensureVisibleIfInPalette(nodeToMove);
- simulateItemDrag(nodeToMove, targetNode);
+ await ensureVisible(nodeToMove);
+
+ simulateItemDrag(nodeToMove, targetNode, "end");
},
"dragToItem": async function(id, target) {
let targetNode = document.getElementById(target);
if (targetNode.customizationTarget) {
targetNode = targetNode.customizationTarget;
}
let items = targetNode.querySelectorAll("toolbarpaletteitem");
if (target == kPanel) {
targetNode = items[items.length - 1];
} else {
targetNode = items[0];
}
let nodeToMove = document.getElementById(id);
- await ensureVisibleIfInPalette(nodeToMove);
- simulateItemDrag(nodeToMove, targetNode);
+ await ensureVisible(nodeToMove);
+ simulateItemDrag(nodeToMove, targetNode, "start");
},
"API": function(id, target) {
if (target == kVisiblePalette) {
return CustomizableUI.removeWidgetFromArea(id);
}
return CustomizableUI.addWidgetToArea(id, target, null);
}
};
@@ -145,16 +152,21 @@ async function checkPanel(id, method) {
}
async function checkPalette(id, method) {
// Move back to palette:
await move[method](id, kVisiblePalette);
ok(CustomizableUI.inDefaultState, "Should end in default state");
let visibleChildren = gCustomizeMode.visiblePalette.children;
let expectedChild = method == "dragToItem" ? visibleChildren[0] : visibleChildren[visibleChildren.length - 1];
+ // Items dragged to the end of the palette should be the final item. That they're the penultimate
+ // item when dragged is tracked in bug 1395950. Once that's fixed, this hack can be removed.
+ if (method == "drag") {
+ expectedChild = expectedChild.previousElementSibling;
+ }
is(expectedChild.firstChild.id, id, "Widget " + id + " was moved using " + method + " and should now be wrapped in palette in customizing window.");
if (id == kXULWidgetId) {
ok(otherWin.gNavToolbox.palette.querySelector("#" + id), "Widget " + id + " should be in invisible palette in other window.");
}
checkWrapper(id);
}
// This test needs a XUL button that's in the palette by default. No such
--- a/browser/components/customizableui/test/browser_878452_drag_to_panel.js
+++ b/browser/components/customizableui/test/browser_878452_drag_to_panel.js
@@ -10,17 +10,17 @@ add_task(async function() {
await startCustomizing();
let btn = document.getElementById("feed-button");
let placements = getAreaWidgetIds(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
let lastButtonIndex = placements.length - 1;
let lastButton = placements[lastButtonIndex];
let placementsAfterInsert = placements.slice(0, lastButtonIndex).concat(["feed-button", lastButton]);
let lastButtonNode = document.getElementById(lastButton);
- simulateItemDrag(btn, lastButtonNode);
+ simulateItemDrag(btn, lastButtonNode, "start");
assertAreaPlacements(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, placementsAfterInsert);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let palette = document.getElementById("customization-palette");
simulateItemDrag(btn, palette);
CustomizableUI.removeWidgetFromArea("cui-panel-item-to-drag-to");
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
});
@@ -58,12 +58,13 @@ add_task(async function() {
simulateItemDrag(btn, panel);
assertAreaPlacements(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, placementsAfterAppend);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let palette = document.getElementById("customization-palette");
simulateItemDrag(btn, palette);
assertAreaPlacements(panel.id, []);
});
-add_task(async function asyncCleanup() {
+registerCleanupFunction(async function asyncCleanup() {
+ CustomizableUI.destroyWidget("cui-panel-item-to-drag-to");
await endCustomizing();
await resetCustomization();
});
--- a/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
+++ b/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
@@ -13,23 +13,24 @@ add_task(async function() {
skippedItem = document.createElement("toolbarbutton");
skippedItem.id = "test-skipintoolbarset-item";
skippedItem.setAttribute("label", "Test");
skippedItem.setAttribute("skipintoolbarset", "true");
skippedItem.setAttribute("removable", "true");
navbar.customizationTarget.appendChild(skippedItem);
let libraryButton = document.getElementById("library-button");
await startCustomizing();
+ await waitForElementShown(skippedItem);
ok(CustomizableUI.inDefaultState, "Should still be in default state");
- simulateItemDrag(skippedItem, libraryButton);
+ simulateItemDrag(skippedItem, libraryButton, "start");
ok(CustomizableUI.inDefaultState, "Should still be in default state");
let skippedItemWrapper = skippedItem.parentNode;
is(skippedItemWrapper.nextSibling && skippedItemWrapper.nextSibling.id,
libraryButton.parentNode.id, "Should be next to library button");
- simulateItemDrag(libraryButton, skippedItem);
+ simulateItemDrag(libraryButton, skippedItem, "start");
let libraryWrapper = libraryButton.parentNode;
is(libraryWrapper.nextSibling && libraryWrapper.nextSibling.id,
skippedItem.parentNode.id, "Should be next to skipintoolbarset item");
ok(CustomizableUI.inDefaultState, "Should still be in default state");
});
add_task(async function asyncCleanup() {
await endCustomizing();
--- a/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
+++ b/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
@@ -40,17 +40,17 @@ add_task(async function() {
// Make sure we have some hidden items at the end of the nav-bar.
navbar.insertItem(hidden1.id);
navbar.insertItem(hidden2.id);
// Drag an item and drop it onto the nav-bar customization target, but
// not over a particular item.
await startCustomizing();
let homeButton = document.getElementById("home-button");
- simulateItemDrag(homeButton, navbar.customizationTarget);
+ simulateItemDrag(homeButton, navbar.customizationTarget, "end");
await endCustomizing();
is(homeButton.previousSibling.id, lastVisible.id,
"The downloads button should be placed after the last visible item.");
await resetCustomization();
});
--- a/browser/components/customizableui/test/browser_newtab_button_customizemode.js
+++ b/browser/components/customizableui/test/browser_newtab_button_customizemode.js
@@ -27,46 +27,49 @@ function assertNewTabButton(which) {
}
}
/**
* Add and remove items *after* the new tab button in customize mode.
*/
add_task(async function addremove_after_newtab_customizemode() {
await startCustomizing();
- simulateItemDrag(document.getElementById("home-button"),
- kGlobalNewTabButton.parentNode.nextElementSibling);
+ await waitForElementShown(kGlobalNewTabButton);
+ simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton, "end");
ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
"tabs should have the adjacent newtab attribute");
await endCustomizing();
assertNewTabButton("inner");
await startCustomizing();
- simulateItemDrag(document.getElementById("home-button"),
- document.getElementById("stop-reload-button").parentNode.nextElementSibling);
+ let dropTarget = document.getElementById("stop-reload-button");
+ await waitForElementShown(dropTarget);
+ simulateItemDrag(document.getElementById("home-button"), dropTarget, "end");
ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
"tabs should still have the adjacent newtab attribute");
await endCustomizing();
assertNewTabButton("inner");
ok(CustomizableUI.inDefaultState, "Should be in default state");
});
/**
* Add and remove items *before* the new tab button in customize mode.
*/
add_task(async function addremove_before_newtab_customizemode() {
await startCustomizing();
- simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton);
+ await waitForElementShown(kGlobalNewTabButton);
+ simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton, "start");
ok(!gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
"tabs should no longer have the adjacent newtab attribute");
await endCustomizing();
assertNewTabButton("global");
await startCustomizing();
- simulateItemDrag(document.getElementById("home-button"),
- document.getElementById("stop-reload-button").parentNode.nextElementSibling);
+ let dropTarget = document.getElementById("stop-reload-button");
+ await waitForElementShown(dropTarget);
+ simulateItemDrag(document.getElementById("home-button"), dropTarget, "end");
ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
"tabs should have the adjacent newtab attribute again");
await endCustomizing();
assertNewTabButton("inner");
ok(CustomizableUI.inDefaultState, "Should be in default state");
});
/**
@@ -105,17 +108,18 @@ add_task(async function addremove_before
ok(CustomizableUI.inDefaultState, "Should be in default state");
});
/**
* Reset to defaults in customize mode to see if that doesn't break things.
*/
add_task(async function reset_before_newtab_customizemode() {
await startCustomizing();
- simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton);
+ await waitForElementShown(kGlobalNewTabButton);
+ simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton, "start");
ok(!gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
"tabs should no longer have the adjacent newtab attribute");
await endCustomizing();
assertNewTabButton("global");
await startCustomizing();
await gCustomizeMode.reset();
ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
"tabs should have the adjacent newtab attribute again");
--- a/browser/components/customizableui/test/browser_remove_customized_specials.js
+++ b/browser/components/customizableui/test/browser_remove_customized_specials.js
@@ -10,19 +10,20 @@ add_task(async function() {
await startCustomizing();
CustomizableUI.addWidgetToArea("spring", "nav-bar", 5);
await gCustomizeMode.reset();
let springs = document.querySelectorAll("#nav-bar toolbarspring");
let lastSpring = springs[springs.length - 1];
let expectedPlacements = CustomizableUI.getWidgetIdsInArea("nav-bar");
info("Placements before drag: " + expectedPlacements.join(","));
let lastItem = document.getElementById(expectedPlacements[expectedPlacements.length - 1]);
- simulateItemDrag(lastSpring, lastItem);
+ await waitForElementShown(lastItem);
+ simulateItemDrag(lastSpring, lastItem, "end");
expectedPlacements.splice(expectedPlacements.indexOf(lastSpring.id), 1);
- expectedPlacements.splice(expectedPlacements.length - 1, 0, lastSpring.id);
+ expectedPlacements.push(lastSpring.id);
let actualPlacements = CustomizableUI.getWidgetIdsInArea("nav-bar");
// Log these separately because Assert.deepEqual truncates the stringified versions...
info("Actual placements: " + actualPlacements.join(","));
info("Expected placements: " + expectedPlacements.join(","));
Assert.deepEqual(expectedPlacements, actualPlacements, "Should be able to move spring");
await gCustomizeMode.reset();
await endCustomizing();
});
--- a/browser/components/customizableui/test/head.js
+++ b/browser/components/customizableui/test/head.js
@@ -168,18 +168,32 @@ function todoAssertAreaPlacements(areaId
todo(isPassing, "The area placements for " + areaId +
" should equal the expected placements.");
}
function getAreaWidgetIds(areaId) {
return CustomizableUI.getWidgetIdsInArea(areaId);
}
-function simulateItemDrag(aToDrag, aTarget) {
- synthesizeDrop(aToDrag.parentNode, aTarget);
+function simulateItemDrag(aToDrag, aTarget, aEvent = {}) {
+ let ev = aEvent;
+ if (ev == "end" || ev == "start") {
+ let win = aTarget.ownerGlobal;
+ win.QueryInterface(Ci.nsIInterfaceRequestor);
+ const dwu = win.getInterface(Ci.nsIDOMWindowUtils);
+ let bounds = dwu.getBoundsWithoutFlushing(aTarget);
+ if (ev == "end") {
+ ev = {clientX: bounds.right - 2, clientY: bounds.bottom - 2};
+ } else {
+ ev = {clientX: bounds.left + 2, clientY: bounds.top + 2};
+ }
+ }
+ ev._domDispatchOnly = true;
+ synthesizeDrop(aToDrag.parentNode, aTarget, null, null,
+ aToDrag.ownerGlobal, aTarget.ownerGlobal, ev);
}
function endCustomizing(aWindow = window) {
if (aWindow.document.documentElement.getAttribute("customizing") != "true") {
return true;
}
return new Promise(resolve => {
function onCustomizationEnds() {
@@ -496,17 +510,21 @@ function checkContextMenu(aContextMenu,
is(menuItemDisabled, !aExpectedEntries[i][1], "disabled state for " + selector);
} catch (e) {
ok(false, "Exception when checking context menu: " + e);
}
}
}
function waitForOverflowButtonShown(win = window) {
+ let ov = win.document.getElementById("nav-bar-overflow-button");
+ let icon = win.document.getAnonymousElementByAttribute(ov, "class", "toolbarbutton-icon");
+ return waitForElementShown(icon);
+}
+function waitForElementShown(element) {
+ let win = element.ownerGlobal;
let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
return BrowserTestUtils.waitForCondition(() => {
info("Waiting for overflow button to have non-0 size");
- let ov = win.document.getElementById("nav-bar-overflow-button");
- let icon = win.document.getAnonymousElementByAttribute(ov, "class", "toolbarbutton-icon");
- let bounds = dwu.getBoundsWithoutFlushing(icon);
+ let bounds = dwu.getBoundsWithoutFlushing(element);
return bounds.width > 0 && bounds.height > 0;
});
}