/** * Test reordering the tabs in the Tab Manager, moving the tab between the * Tab Manager and tab bar. */ "use strict"; const { TelemetryTestUtils } = ChromeUtils.importESModule( "resource://testing-common/TelemetryTestUtils.sys.mjs" ); const URL1 = "data:text/plain,tab1"; const URL2 = "data:text/plain,tab2"; const URL3 = "data:text/plain,tab3"; const URL4 = "data:text/plain,tab4"; const URL5 = "data:text/plain,tab5"; function assertOrder(order, expected, message) { is( JSON.stringify(order), JSON.stringify(expected), `The order of the tabs ${message}` ); } function toIndex(url) { const m = url.match(/^data:text\/plain,tab(\d)/); if (m) { return parseInt(m[1]); } return 0; } function getOrderOfList(list) { return [...list.querySelectorAll("toolbaritem")].map(row => { const url = row.firstElementChild.tab.linkedBrowser.currentURI.spec; return toIndex(url); }); } function getOrderOfTabs(tabs) { return tabs.map(tab => { const url = tab.linkedBrowser.currentURI.spec; return toIndex(url); }); } async function testWithNewWindow(func) { Services.prefs.setBoolPref("browser.tabs.tabmanager.enabled", true); const newWindow = await BrowserTestUtils.openNewWindowWithFlushedCacheForMozSupports(); await Promise.all([ addTabTo(newWindow.gBrowser, URL1), addTabTo(newWindow.gBrowser, URL2), addTabTo(newWindow.gBrowser, URL3), addTabTo(newWindow.gBrowser, URL4), addTabTo(newWindow.gBrowser, URL5), ]); newWindow.gTabsPanel.init(); const button = newWindow.document.getElementById("alltabs-button"); const allTabsView = newWindow.document.getElementById( "allTabsMenu-allTabsView" ); const allTabsPopupShownPromise = BrowserTestUtils.waitForEvent( allTabsView, "ViewShown" ); button.click(); await allTabsPopupShownPromise; await func(newWindow); await BrowserTestUtils.closeWindow(newWindow); Services.prefs.clearUserPref("browser.tabs.tabmanager.enabled"); } add_task(async function test_reorder() { await testWithNewWindow(async function (newWindow) { Services.telemetry.clearScalars(); const list = newWindow.document.getElementById( "allTabsMenu-allTabsView-tabs" ); assertOrder(getOrderOfList(list), [0, 1, 2, 3, 4, 5], "before reorder"); let rows; rows = list.querySelectorAll("toolbaritem"); EventUtils.synthesizeDrop( rows[3], rows[1], null, "move", newWindow, newWindow, { clientX: 0, clientY: 0 } ); assertOrder(getOrderOfList(list), [0, 3, 1, 2, 4, 5], "after moving up"); rows = list.querySelectorAll("toolbaritem"); EventUtils.synthesizeDrop( rows[1], rows[5], null, "move", newWindow, newWindow, { clientX: 0, clientY: 0 } ); assertOrder(getOrderOfList(list), [0, 1, 2, 4, 3, 5], "after moving down"); rows = list.querySelectorAll("toolbaritem"); EventUtils.synthesizeDrop( rows[4], rows[3], null, "move", newWindow, newWindow, { clientX: 0, clientY: 0 } ); assertOrder( getOrderOfList(list), [0, 1, 2, 3, 4, 5], "after moving up again" ); let scalars = TelemetryTestUtils.getProcessScalars("parent", false, true); TelemetryTestUtils.assertScalar( scalars, "browser.ui.interaction.all_tabs_panel_dragstart_tab_event_count", 3 ); }); }); function tabOf(row) { return row.firstElementChild.tab; } add_task(async function test_move_to_tab_bar() { await testWithNewWindow(async function (newWindow) { Services.telemetry.clearScalars(); const list = newWindow.document.getElementById( "allTabsMenu-allTabsView-tabs" ); assertOrder(getOrderOfList(list), [0, 1, 2, 3, 4, 5], "before reorder"); let rows; rows = list.querySelectorAll("toolbaritem"); EventUtils.synthesizeDrop( rows[3], tabOf(rows[1]), null, "move", newWindow, newWindow, { clientX: 0, clientY: 0 } ); assertOrder( getOrderOfList(list), [0, 3, 1, 2, 4, 5], "after moving up with tab bar" ); rows = list.querySelectorAll("toolbaritem"); EventUtils.synthesizeDrop( rows[1], tabOf(rows[4]), null, "move", newWindow, newWindow, { clientX: 0, clientY: 0 } ); assertOrder( getOrderOfList(list), [0, 1, 2, 3, 4, 5], "after moving down with tab bar" ); let scalars = TelemetryTestUtils.getProcessScalars("parent", false, true); TelemetryTestUtils.assertScalar( scalars, "browser.ui.interaction.all_tabs_panel_dragstart_tab_event_count", 2 ); }); }); add_task(async function test_move_to_different_tab_bar() { const newWindow2 = await BrowserTestUtils.openNewWindowWithFlushedCacheForMozSupports(); await testWithNewWindow(async function (newWindow) { Services.telemetry.clearScalars(); const list = newWindow.document.getElementById( "allTabsMenu-allTabsView-tabs" ); assertOrder( getOrderOfList(list), [0, 1, 2, 3, 4, 5], "before reorder in newWindow" ); assertOrder( getOrderOfTabs(newWindow2.gBrowser.tabs), [0], "before reorder in newWindow2" ); let rows; rows = list.querySelectorAll("toolbaritem"); EventUtils.synthesizeDrop( rows[3], newWindow2.gBrowser.tabs[0], null, "move", newWindow, newWindow2, { clientX: 0, clientY: 0 } ); assertOrder( getOrderOfList(list), [0, 1, 2, 4, 5], "after moving to other window in newWindow" ); assertOrder( getOrderOfTabs(newWindow2.gBrowser.tabs), [3, 0], "after moving to other window in newWindow2" ); let scalars = TelemetryTestUtils.getProcessScalars("parent", false, true); TelemetryTestUtils.assertScalar( scalars, "browser.ui.interaction.all_tabs_panel_dragstart_tab_event_count", 1 ); }); await BrowserTestUtils.closeWindow(newWindow2); });