diff options
Diffstat (limited to 'browser/components/customizableui/test/browser_editcontrols_update.js')
-rw-r--r-- | browser/components/customizableui/test/browser_editcontrols_update.js | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/browser/components/customizableui/test/browser_editcontrols_update.js b/browser/components/customizableui/test/browser_editcontrols_update.js new file mode 100644 index 0000000000..9f064e521a --- /dev/null +++ b/browser/components/customizableui/test/browser_editcontrols_update.js @@ -0,0 +1,307 @@ +// This test checks that the edit command enabled state (cut/paste) is updated +// properly when the edit controls are on the toolbar, popup and not present. +// It also verifies that the performance optimiation implemented by +// updateEditUIVisibility in browser.js is applied. + +let isMac = navigator.platform.indexOf("Mac") == 0; + +function checkState(allowCut, desc, testWindow = window) { + is( + testWindow.document.getElementById("cmd_cut").getAttribute("disabled") == + "true", + !allowCut, + desc + " - cut" + ); + is( + testWindow.document.getElementById("cmd_paste").getAttribute("disabled") == + "true", + false, + desc + " - paste" + ); +} + +// Add a special controller to the urlbar and browser to listen in on when +// commands are being updated. Return a promise that resolves when 'count' +// updates have occurred. +function expectCommandUpdate(count, testWindow = window) { + return new Promise((resolve, reject) => { + let overrideController = { + supportsCommand(cmd) { + return cmd == "cmd_delete"; + }, + isCommandEnabled(cmd) { + if (!count) { + ok(false, "unexpected update"); + reject(); + } + + if (!--count) { + testWindow.gURLBar.inputField.controllers.removeControllerAt( + 0, + overrideController + ); + testWindow.gBrowser.selectedBrowser.controllers.removeControllerAt( + 0, + overrideController + ); + resolve(true); + } + }, + }; + + if (!count) { + SimpleTest.executeSoon(() => { + testWindow.gURLBar.inputField.controllers.removeControllerAt( + 0, + overrideController + ); + testWindow.gBrowser.selectedBrowser.controllers.removeControllerAt( + 0, + overrideController + ); + resolve(false); + }); + } + + testWindow.gURLBar.inputField.controllers.insertControllerAt( + 0, + overrideController + ); + testWindow.gBrowser.selectedBrowser.controllers.insertControllerAt( + 0, + overrideController + ); + }); +} + +// Call this between `.select()` to make sure the selection actually changes +// and thus TextInputListener::UpdateTextInputCommands() is called. +function deselectURLBarAndSpin() { + gURLBar.inputField.setSelectionRange(0, 0); + return new Promise(setTimeout); +} + +add_task(async function test_init() { + // Put something on the clipboard to verify that the paste button is properly enabled during the test. + let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService( + Ci.nsIClipboardHelper + ); + await new Promise(resolve => { + SimpleTest.waitForClipboard( + "Sample", + function () { + clipboardHelper.copyString("Sample"); + }, + resolve + ); + }); + + // Open and close the panel first so that it is fully initialized. + await gCUITestUtils.openMainMenu(); + await gCUITestUtils.hideMainMenu(); +}); + +// Test updating when the panel is open with the edit-controls on the panel. +// Updates should occur. +add_task(async function test_panelui_opened() { + document.commandDispatcher.unlock(); + gURLBar.focus(); + gURLBar.value = "test"; + + await gCUITestUtils.openMainMenu(); + + checkState(false, "Update when edit-controls is on panel and visible"); + + let overridePromise = expectCommandUpdate(1); + gURLBar.select(); + await overridePromise; + + checkState( + true, + "Update when edit-controls is on panel and selection changed" + ); + + overridePromise = expectCommandUpdate(0); + await gCUITestUtils.hideMainMenu(); + await overridePromise; + + // Check that updates do not occur after the panel has been closed. + checkState(true, "Update when edit-controls is on panel and hidden"); + + // Mac will update the enabled state even when the panel is closed so that + // main menubar shortcuts will work properly. + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(isMac ? 1 : 0); + gURLBar.select(); + await overridePromise; + checkState( + true, + "Update when edit-controls is on panel, hidden and selection changed" + ); +}); + +// Test updating when the edit-controls are moved to the toolbar. +add_task(async function test_panelui_customize_to_toolbar() { + await startCustomizing(); + let navbar = document.getElementById("nav-bar"); + simulateItemDrag( + document.getElementById("edit-controls"), + CustomizableUI.getCustomizationTarget(navbar), + "end" + ); + await endCustomizing(); + + // updateEditUIVisibility should be called when customization ends but isn't. See bug 1359790. + updateEditUIVisibility(); + + // The URL bar may have been focused to begin with, which means + // that subsequent calls to focus it won't result in command + // updates, so we'll make sure to blur it. + gURLBar.blur(); + + let overridePromise = expectCommandUpdate(1); + gURLBar.select(); + gURLBar.focus(); + gURLBar.value = "other"; + await overridePromise; + checkState(false, "Update when edit-controls on toolbar and focused"); + + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(1); + gURLBar.select(); + await overridePromise; + checkState( + true, + "Update when edit-controls on toolbar and selection changed" + ); + + const kOverflowPanel = document.getElementById("widget-overflow"); + + let originalWidth = window.outerWidth; + registerCleanupFunction(async function () { + kOverflowPanel.removeAttribute("animate"); + window.resizeTo(originalWidth, window.outerHeight); + await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing")); + CustomizableUI.reset(); + }); + + window.resizeTo(kForceOverflowWidthPx, window.outerHeight); + await TestUtils.waitForCondition( + () => + navbar.hasAttribute("overflowing") && + !navbar.querySelector("edit-controls") + ); + + // Mac will update the enabled state even when the buttons are overflowing, + // so main menubar shortcuts will work properly. + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(isMac ? 1 : 0); + gURLBar.select(); + await overridePromise; + checkState( + true, + "Update when edit-controls is on overflow panel, hidden and selection changed" + ); + + // Check that we get an update if we select content while the panel is open. + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(1); + await navbar.overflowable.show(); + gURLBar.select(); + await overridePromise; + + // And that we don't (except on mac) when the panel is hidden. + kOverflowPanel.hidePopup(); + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(isMac ? 1 : 0); + gURLBar.select(); + await overridePromise; + + window.resizeTo(originalWidth, window.outerHeight); + await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing")); + + CustomizableUI.addWidgetToArea( + "edit-controls", + CustomizableUI.AREA_FIXED_OVERFLOW_PANEL + ); + // updateEditUIVisibility should be called when customization happens but isn't. See bug 1359790. + updateEditUIVisibility(); + + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(isMac ? 1 : 0); + gURLBar.select(); + await overridePromise; + + // Check that we get an update if we select content while the panel is open. + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(1); + await navbar.overflowable.show(); + gURLBar.select(); + await overridePromise; + + // And that we don't (except on mac) when the panel is hidden. + kOverflowPanel.hidePopup(); + await deselectURLBarAndSpin(); + overridePromise = expectCommandUpdate(isMac ? 1 : 0); + gURLBar.select(); + await overridePromise; +}); + +// Test updating when the edit-controls are moved to the palette. +add_task(async function test_panelui_customize_to_palette() { + await startCustomizing(); + let palette = document.getElementById("customization-palette"); + simulateItemDrag(document.getElementById("edit-controls"), palette); + await endCustomizing(); + + // updateEditUIVisibility should be called when customization ends but isn't. See bug 1359790. + updateEditUIVisibility(); + + let overridePromise = expectCommandUpdate(isMac ? 1 : 0); + gURLBar.focus(); + gURLBar.value = "other"; + gURLBar.select(); + await overridePromise; + + // If the UI isn't found, the command is set to be enabled. + checkState( + true, + "Update when edit-controls is on palette, hidden and selection changed" + ); +}); + +add_task(async function finish() { + await resetCustomization(); +}); + +// Test updating in the initial state when the edit-controls are on the panel but +// have not yet been created. This needs to be done in a new window to ensure that +// other tests haven't opened the panel. +add_task(async function test_initial_state() { + let testWindow = await BrowserTestUtils.openNewBrowserWindow(); + await SimpleTest.promiseFocus(testWindow); + + // For focusing the URL bar to have an effect, we need to ensure the URL bar isn't + // initially focused: + testWindow.gBrowser.selectedTab.focus(); + await TestUtils.waitForCondition(() => !testWindow.gURLBar.focused); + + let overridePromise = expectCommandUpdate(isMac, testWindow); + + testWindow.gURLBar.focus(); + testWindow.gURLBar.value = "test"; + + await overridePromise; + + // Commands won't update when no edit UI is present. They default to being + // enabled so that keyboard shortcuts will work. The real enabled state will + // be checked when shortcut is pressed. + checkState( + !isMac, + "No update when edit-controls is on panel and not visible", + testWindow + ); + + await BrowserTestUtils.closeWindow(testWindow); + await SimpleTest.promiseFocus(window); +}); |