From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../test/tabs/browser_new_tab_insert_position.js | 288 +++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 browser/base/content/test/tabs/browser_new_tab_insert_position.js (limited to 'browser/base/content/test/tabs/browser_new_tab_insert_position.js') diff --git a/browser/base/content/test/tabs/browser_new_tab_insert_position.js b/browser/base/content/test/tabs/browser_new_tab_insert_position.js new file mode 100644 index 0000000000..d54aed738b --- /dev/null +++ b/browser/base/content/test/tabs/browser_new_tab_insert_position.js @@ -0,0 +1,288 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +ChromeUtils.defineESModuleGetters(this, { + SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs", + TabStateFlusher: "resource:///modules/sessionstore/TabStateFlusher.sys.mjs", +}); + +const triggeringPrincipal_base64 = E10SUtils.SERIALIZED_SYSTEMPRINCIPAL; + +function promiseBrowserStateRestored(state) { + if (typeof state != "string") { + state = JSON.stringify(state); + } + // We wait for the notification that restore is done, and for the notification + // that the active tab is loaded and restored. + let promise = Promise.all([ + TestUtils.topicObserved("sessionstore-browser-state-restored"), + BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored"), + ]); + SessionStore.setBrowserState(state); + return promise; +} + +function promiseRemoveThenUndoCloseTab(tab) { + // We wait for the notification that restore is done, and for the notification + // that the active tab is loaded and restored. + let promise = Promise.all([ + TestUtils.topicObserved("sessionstore-closed-objects-changed"), + BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored"), + ]); + BrowserTestUtils.removeTab(tab); + SessionStore.undoCloseTab(window, 0); + return promise; +} + +// Compare the current browser tab order against the session state ordering, they should always match. +function verifyTabState(state) { + let newStateTabs = JSON.parse(state).windows[0].tabs; + for (let i = 0; i < gBrowser.tabs.length; i++) { + is( + gBrowser.tabs[i].linkedBrowser.currentURI.spec, + newStateTabs[i].entries[0].url, + `tab pos ${i} matched ${gBrowser.tabs[i].linkedBrowser.currentURI.spec}` + ); + } +} + +const bulkLoad = [ + "http://mochi.test:8888/#5", + "http://mochi.test:8888/#6", + "http://mochi.test:8888/#7", + "http://mochi.test:8888/#8", +]; + +const sessData = { + windows: [ + { + tabs: [ + { + entries: [ + { url: "http://mochi.test:8888/#0", triggeringPrincipal_base64 }, + ], + }, + { + entries: [ + { url: "http://mochi.test:8888/#1", triggeringPrincipal_base64 }, + ], + }, + { + entries: [ + { url: "http://mochi.test:8888/#3", triggeringPrincipal_base64 }, + ], + }, + { + entries: [ + { url: "http://mochi.test:8888/#4", triggeringPrincipal_base64 }, + ], + }, + ], + }, + ], +}; +// eslint-disable-next-line @microsoft/sdl/no-insecure-url +const urlbarURL = "http://example.com/#urlbar"; + +async function doTest(aInsertRelatedAfterCurrent, aInsertAfterCurrent) { + const kDescription = + "(aInsertRelatedAfterCurrent=" + + aInsertRelatedAfterCurrent + + ", aInsertAfterCurrent=" + + aInsertAfterCurrent + + "): "; + + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.tabs.opentabfor.middleclick", true], + ["browser.tabs.loadBookmarksInBackground", false], + ["browser.tabs.insertRelatedAfterCurrent", aInsertRelatedAfterCurrent], + ["browser.tabs.insertAfterCurrent", aInsertAfterCurrent], + ], + }); + + let oldState = SessionStore.getBrowserState(); + + await promiseBrowserStateRestored(sessData); + + // Create a *opener* tab page which has a link to "example.com". + let pageURL = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.com" + ); + pageURL = `${pageURL}file_new_tab_page.html`; + let openerTab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + pageURL + ); + const openerTabIndex = 1; + gBrowser.moveTabTo(openerTab, openerTabIndex); + + // Open a related tab via Middle click on the cell and test its position. + let openTabIndex = + aInsertRelatedAfterCurrent || aInsertAfterCurrent + ? openerTabIndex + 1 + : gBrowser.tabs.length; + let openTabDescription = + aInsertRelatedAfterCurrent || aInsertAfterCurrent + ? "immediately to the right" + : "at rightmost"; + + let newTabPromise = BrowserTestUtils.waitForNewTab( + gBrowser, + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.com/#linkclick", + true + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#link_to_example_com", + { button: 1 }, + gBrowser.selectedBrowser + ); + let openTab = await newTabPromise; + is( + openTab.linkedBrowser.currentURI.spec, + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.com/#linkclick", + "Middle click should open site to correct url." + ); + is( + openTab._tPos, + openTabIndex, + kDescription + + "Middle click should open site in a new tab " + + openTabDescription + ); + if (aInsertRelatedAfterCurrent || aInsertAfterCurrent) { + is(openTab.owner, openerTab, "tab owner is set correctly"); + } + is(openTab.openerTab, openerTab, "opener tab is set"); + + // Open an unrelated tab from the URL bar and test its position. + openTabIndex = aInsertAfterCurrent + ? openerTabIndex + 1 + : gBrowser.tabs.length; + openTabDescription = aInsertAfterCurrent + ? "immediately to the right" + : "at rightmost"; + + gURLBar.focus(); + gURLBar.select(); + newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, urlbarURL, true); + EventUtils.sendString(urlbarURL); + EventUtils.synthesizeKey("KEY_Alt", { + altKey: true, + code: "AltLeft", + type: "keydown", + }); + EventUtils.synthesizeKey("KEY_Enter", { altKey: true, code: "Enter" }); + EventUtils.synthesizeKey("KEY_Alt", { + altKey: false, + code: "AltLeft", + type: "keyup", + }); + let unrelatedTab = await newTabPromise; + + is( + gBrowser.selectedBrowser.currentURI.spec, + unrelatedTab.linkedBrowser.currentURI.spec, + `${kDescription} ${urlbarURL} should be loaded in the current tab.` + ); + is( + unrelatedTab._tPos, + openTabIndex, + `${kDescription} Alt+Enter in the URL bar should open page in a new tab ${openTabDescription}` + ); + is(unrelatedTab.owner, openerTab, "owner tab is set correctly"); + ok(!unrelatedTab.openerTab, "no opener tab is set"); + + // Closing this should go back to the last selected tab, which just happens to be "openerTab" + // but is not in fact the opener. + BrowserTestUtils.removeTab(unrelatedTab); + is( + gBrowser.selectedTab, + openerTab, + kDescription + `openerTab should be selected after closing unrelated tab` + ); + + // Go back to the opener tab. Closing the child tab should return to the opener. + BrowserTestUtils.removeTab(openTab); + is( + gBrowser.selectedTab, + openerTab, + kDescription + "openerTab should be selected after closing related tab" + ); + + // Flush before messing with browser state. + for (let tab of gBrowser.tabs) { + await TabStateFlusher.flush(tab.linkedBrowser); + } + + // Get the session state, verify SessionStore gives us expected data. + let newState = SessionStore.getBrowserState(); + verifyTabState(newState); + + // Remove the tab at the end, then undo. It should reappear where it was. + await promiseRemoveThenUndoCloseTab(gBrowser.tabs[gBrowser.tabs.length - 1]); + verifyTabState(newState); + + // Remove a tab in the middle, then undo. It should reappear where it was. + await promiseRemoveThenUndoCloseTab(gBrowser.tabs[2]); + verifyTabState(newState); + + // Bug 1442679 - Test bulk opening with loadTabs loads the tabs in order + + let loadPromises = Promise.all( + bulkLoad.map(url => + BrowserTestUtils.waitForNewTab(gBrowser, url, false, true) + ) + ); + // loadTabs will insertAfterCurrent + let nextTab = aInsertAfterCurrent + ? gBrowser.selectedTab._tPos + 1 + : gBrowser.tabs.length; + + gBrowser.loadTabs(bulkLoad, { + inBackground: true, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); + await loadPromises; + for (let i = nextTab, j = 0; j < bulkLoad.length; i++, j++) { + is( + gBrowser.tabs[i].linkedBrowser.currentURI.spec, + bulkLoad[j], + `bulkLoad tab pos ${i} matched` + ); + } + + // Now we want to test that positioning remains correct after a session restore. + + // Restore pre-test state so we can restore and test tab ordering. + await promiseBrowserStateRestored(oldState); + + // Restore test state and verify it is as it was. + await promiseBrowserStateRestored(newState); + verifyTabState(newState); + + // Restore pre-test state for next test. + await promiseBrowserStateRestored(oldState); +} + +add_task(async function test_settings_insertRelatedAfter() { + // Firefox default settings. + await doTest(true, false); +}); + +add_task(async function test_settings_insertAfter() { + await doTest(true, true); +}); + +add_task(async function test_settings_always_insertAfter() { + await doTest(false, true); +}); + +add_task(async function test_settings_always_insertAtEnd() { + await doTest(false, false); +}); -- cgit v1.2.3