diff options
Diffstat (limited to 'browser/components/customizableui/test/browser_976792_insertNodeInWindow.js')
-rw-r--r-- | browser/components/customizableui/test/browser_976792_insertNodeInWindow.js | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js b/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js new file mode 100644 index 0000000000..5325b322dd --- /dev/null +++ b/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js @@ -0,0 +1,597 @@ +/* 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/. */ + +"use strict"; + +const kToolbarName = "test-insertNodeInWindow-placements-toolbar"; +const kTestWidgetPrefix = "test-widget-for-insertNodeInWindow-placements-"; + +/* +Tries to replicate the situation of having a placement list like this: + +exists-1,trying-to-insert-this,doesn't-exist,exists-2 +*/ +add_task(async function() { + let testWidgetExists = [true, false, false, true]; + let widgetIds = []; + for (let i = 0; i < testWidgetExists.length; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + if (testWidgetExists[i]) { + let spec = { + id, + type: "button", + removable: true, + label: "test", + tooltiptext: "" + i, + }; + CustomizableUI.createWidget(spec); + } + } + + let toolbarNode = createToolbarWithPlacements(kToolbarName, widgetIds); + assertAreaPlacements(kToolbarName, widgetIds); + + let btnId = kTestWidgetPrefix + 1; + let btn = createDummyXULButton(btnId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(btnId, window); + + is( + btn.parentNode.id, + kToolbarName, + "New XUL widget should be placed inside new toolbar" + ); + + is( + btn.previousElementSibling.id, + toolbarNode.firstElementChild.id, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + btn.remove(); + removeCustomToolbars(); + await resetCustomization(); +}); + +/* +Tests nodes get placed inside the toolbar's overflow as expected. Replicates a +situation similar to: + +exists-1,exists-2,overflow-1,trying-to-insert-this,overflow-2 +*/ +add_task(async function() { + let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR); + + let widgetIds = []; + for (let i = 0; i < 5; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + let spec = { + id, + type: "button", + removable: true, + label: "insertNodeInWindow test", + tooltiptext: "" + i, + }; + CustomizableUI.createWidget(spec); + CustomizableUI.addWidgetToArea(id, "nav-bar"); + } + + for (let id of widgetIds) { + document.getElementById(id).style.minWidth = "200px"; + } + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition( + () => + navbar.hasAttribute("overflowing") && + !navbar.querySelector("#" + widgetIds[0]) + ); + + let testWidgetId = kTestWidgetPrefix + 3; + + CustomizableUI.destroyWidget(testWidgetId); + + let btn = createDummyXULButton(testWidgetId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window); + + ok( + navbar.overflowable.isInOverflowList(btn), + "New XUL widget should be placed inside overflow of toolbar" + ); + is( + btn.previousElementSibling.id, + kTestWidgetPrefix + 2, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + is( + btn.nextElementSibling.id, + kTestWidgetPrefix + 4, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName); + btn.remove(); + await resetCustomization(); + await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing")); +}); + +/* +Tests nodes get placed inside the toolbar's overflow as expected. Replicates a +placements situation similar to: + +exists-1,exists-2,overflow-1,doesn't-exist,trying-to-insert-this,overflow-2 +*/ +add_task(async function() { + let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR); + + let widgetIds = []; + for (let i = 0; i < 5; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + let spec = { + id, + type: "button", + removable: true, + label: "insertNodeInWindow test", + tooltiptext: "" + i, + }; + CustomizableUI.createWidget(spec); + CustomizableUI.addWidgetToArea(id, "nav-bar"); + } + + for (let id of widgetIds) { + document.getElementById(id).style.minWidth = "200px"; + } + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition( + () => + navbar.hasAttribute("overflowing") && + !navbar.querySelector("#" + widgetIds[0]) + ); + + let testWidgetId = kTestWidgetPrefix + 3; + + CustomizableUI.destroyWidget(kTestWidgetPrefix + 2); + CustomizableUI.destroyWidget(testWidgetId); + + let btn = createDummyXULButton(testWidgetId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window); + + ok( + navbar.overflowable.isInOverflowList(btn), + "New XUL widget should be placed inside overflow of toolbar" + ); + is( + btn.previousElementSibling.id, + kTestWidgetPrefix + 1, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + is( + btn.nextElementSibling.id, + kTestWidgetPrefix + 4, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName); + btn.remove(); + await resetCustomization(); + await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing")); +}); + +/* +Tests nodes get placed inside the toolbar's overflow as expected. Replicates a +placements situation similar to: + +exists-1,exists-2,overflow-1,doesn't-exist,trying-to-insert-this,doesn't-exist +*/ +add_task(async function() { + let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR); + + let widgetIds = []; + for (let i = 0; i < 5; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + let spec = { + id, + type: "button", + removable: true, + label: "insertNodeInWindow test", + tooltiptext: "" + i, + }; + CustomizableUI.createWidget(spec); + CustomizableUI.addWidgetToArea(id, "nav-bar"); + } + + for (let id of widgetIds) { + document.getElementById(id).style.minWidth = "200px"; + } + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition( + () => + navbar.hasAttribute("overflowing") && + !navbar.querySelector("#" + widgetIds[0]) + ); + + let testWidgetId = kTestWidgetPrefix + 3; + + CustomizableUI.destroyWidget(kTestWidgetPrefix + 2); + CustomizableUI.destroyWidget(testWidgetId); + CustomizableUI.destroyWidget(kTestWidgetPrefix + 4); + + let btn = createDummyXULButton(testWidgetId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window); + + ok( + navbar.overflowable.isInOverflowList(btn), + "New XUL widget should be placed inside overflow of toolbar" + ); + is( + btn.previousElementSibling.id, + kTestWidgetPrefix + 1, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + is( + btn.nextElementSibling, + null, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName); + btn.remove(); + await resetCustomization(); + await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing")); +}); + +/* +Tests nodes get placed inside the toolbar's overflow as expected. Replicates a +placements situation similar to: + +exists-1,exists-2,overflow-1,can't-overflow,trying-to-insert-this,overflow-2 +*/ +add_task(async function() { + let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR); + + let widgetIds = []; + for (let i = 5; i >= 0; i--) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + let spec = { + id, + type: "button", + removable: true, + label: "insertNodeInWindow test", + tooltiptext: "" + i, + }; + CustomizableUI.createWidget(spec); + CustomizableUI.addWidgetToArea(id, "nav-bar", 0); + } + + for (let i = 10; i < 15; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + let spec = { + id, + type: "button", + removable: true, + label: "insertNodeInWindow test", + tooltiptext: "" + i, + }; + CustomizableUI.createWidget(spec); + CustomizableUI.addWidgetToArea(id, "nav-bar"); + } + + for (let id of widgetIds) { + document.getElementById(id).style.minWidth = "200px"; + } + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + // Wait for all the widgets to overflow. We can't just wait for the + // `overflowing` attribute because we leave time for layout flushes + // inbetween, so it's possible for the timeout to run before the + // navbar has "settled" + await TestUtils.waitForCondition(() => { + return ( + navbar.hasAttribute("overflowing") && + CustomizableUI.getCustomizationTarget( + navbar + ).lastElementChild.getAttribute("overflows") == "false" + ); + }); + + // Find last widget that doesn't allow overflowing + let nonOverflowing = CustomizableUI.getCustomizationTarget(navbar) + .lastElementChild; + is( + nonOverflowing.getAttribute("overflows"), + "false", + "Last child is expected to not allow overflowing" + ); + isnot( + nonOverflowing.getAttribute("skipintoolbarset"), + "true", + "Last child is expected to not be skipintoolbarset" + ); + + let testWidgetId = kTestWidgetPrefix + 10; + CustomizableUI.destroyWidget(testWidgetId); + + let btn = createDummyXULButton(testWidgetId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window); + + ok( + navbar.overflowable.isInOverflowList(btn), + "New XUL widget should be placed inside overflow of toolbar" + ); + is( + btn.nextElementSibling.id, + kTestWidgetPrefix + 11, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName); + btn.remove(); + await resetCustomization(); + await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing")); +}); + +/* +Tests nodes get placed inside the toolbar's overflow as expected. Replicates a +placements situation similar to: + +exists-1,exists-2,overflow-1,trying-to-insert-this,can't-overflow,overflow-2 +*/ +add_task(async function() { + let widgetIds = []; + let missingId = 2; + let nonOverflowableId = 3; + for (let i = 0; i < 5; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + if (i != missingId) { + // Setting min-width to make the overflow state not depend on styling of the button and/or + // screen width + let spec = { + id, + type: "button", + removable: true, + label: "test", + tooltiptext: "" + i, + onCreated(node) { + node.style.minWidth = "200px"; + if (id == kTestWidgetPrefix + nonOverflowableId) { + node.setAttribute("overflows", false); + } + }, + }; + info("Creating: " + id); + CustomizableUI.createWidget(spec); + } + } + + let toolbarNode = createOverflowableToolbarWithPlacements( + kToolbarName, + widgetIds + ); + assertAreaPlacements(kToolbarName, widgetIds); + ok( + !toolbarNode.hasAttribute("overflowing"), + "Toolbar shouldn't overflow to start with." + ); + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition( + () => + toolbarNode.hasAttribute("overflowing") && + !toolbarNode.querySelector("#" + widgetIds[1]) + ); + ok( + toolbarNode.hasAttribute("overflowing"), + "Should have an overflowing toolbar." + ); + + let btnId = kTestWidgetPrefix + missingId; + let btn = createDummyXULButton(btnId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(btnId, window); + + is( + btn.parentNode.id, + kToolbarName + "-overflow-list", + "New XUL widget should be placed inside new toolbar's overflow" + ); + is( + btn.previousElementSibling.id, + kTestWidgetPrefix + 1, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + is( + btn.nextElementSibling.id, + kTestWidgetPrefix + 4, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + await TestUtils.waitForCondition( + () => !toolbarNode.hasAttribute("overflowing") + ); + + btn.remove(); + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + removeCustomToolbars(); + await resetCustomization(); +}); + +/* +Tests nodes do *not* get placed in the toolbar's overflow. Replicates a +plcements situation similar to: + +exists-1,trying-to-insert-this,exists-2,overflowed-1 +*/ +add_task(async function() { + let widgetIds = []; + let missingId = 1; + for (let i = 0; i < 5; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + if (i != missingId) { + // Setting min-width to make the overflow state not depend on styling of the button and/or + // screen width + let spec = { + id, + type: "button", + removable: true, + label: "test", + tooltiptext: "" + i, + onCreated(node) { + node.style.minWidth = "200px"; + }, + }; + info("Creating: " + id); + CustomizableUI.createWidget(spec); + } + } + + let toolbarNode = createOverflowableToolbarWithPlacements( + kToolbarName, + widgetIds + ); + assertAreaPlacements(kToolbarName, widgetIds); + ok( + !toolbarNode.hasAttribute("overflowing"), + "Toolbar shouldn't overflow to start with." + ); + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition(() => + toolbarNode.hasAttribute("overflowing") + ); + ok( + toolbarNode.hasAttribute("overflowing"), + "Should have an overflowing toolbar." + ); + + let btnId = kTestWidgetPrefix + missingId; + let btn = createDummyXULButton(btnId, "test"); + CustomizableUI.ensureWidgetPlacedInWindow(btnId, window); + + is( + btn.parentNode.id, + kToolbarName + "-target", + "New XUL widget should be placed inside new toolbar" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + await TestUtils.waitForCondition( + () => !toolbarNode.hasAttribute("overflowing") + ); + + btn.remove(); + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + removeCustomToolbars(); + await resetCustomization(); +}); + +/* +Tests inserting a node onto the end of an overflowing toolbar *doesn't* put it in +the overflow list when the widget disallows overflowing. ie: + +exists-1,exists-2,overflows-1,trying-to-insert-this + +Where trying-to-insert-this has overflows=false +*/ +add_task(async function() { + let widgetIds = []; + let missingId = 3; + for (let i = 0; i < 5; i++) { + let id = kTestWidgetPrefix + i; + widgetIds.push(id); + if (i != missingId) { + // Setting min-width to make the overflow state not depend on styling of the button and/or + // screen width + let spec = { + id, + type: "button", + removable: true, + label: "test", + tooltiptext: "" + i, + onCreated(node) { + node.style.minWidth = "200px"; + }, + }; + info("Creating: " + id); + CustomizableUI.createWidget(spec); + } + } + + let toolbarNode = createOverflowableToolbarWithPlacements( + kToolbarName, + widgetIds + ); + assertAreaPlacements(kToolbarName, widgetIds); + ok( + !toolbarNode.hasAttribute("overflowing"), + "Toolbar shouldn't overflow to start with." + ); + + let originalWindowWidth = window.outerWidth; + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition(() => + toolbarNode.hasAttribute("overflowing") + ); + ok( + toolbarNode.hasAttribute("overflowing"), + "Should have an overflowing toolbar." + ); + + let btnId = kTestWidgetPrefix + missingId; + let btn = createDummyXULButton(btnId, "test"); + btn.setAttribute("overflows", false); + CustomizableUI.ensureWidgetPlacedInWindow(btnId, window); + + is( + btn.parentNode.id, + kToolbarName + "-target", + "New XUL widget should be placed inside new toolbar" + ); + is( + btn.nextElementSibling, + null, + "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements" + ); + + window.resizeTo(originalWindowWidth, window.outerHeight); + await TestUtils.waitForCondition( + () => !toolbarNode.hasAttribute("overflowing") + ); + + btn.remove(); + widgetIds.forEach(id => CustomizableUI.destroyWidget(id)); + removeCustomToolbars(); + await resetCustomization(); +}); + +add_task(async function asyncCleanUp() { + await resetCustomization(); +}); |