/* Any copyright is dedicated to the Public Domain. * * http://creativecommons.org/publicdomain/zero/1.0/ */ /* * Test searching for the selected text using the context menu */ const { AddonTestUtils } = ChromeUtils.importESModule( "resource://testing-common/AddonTestUtils.sys.mjs" ); AddonTestUtils.initMochitest(this); const ENGINE_NAME = "mozSearch"; const PRIVATE_ENGINE_NAME = "mozPrivateSearch"; const ENGINE_DATA = new Map([ [ ENGINE_NAME, "https://example.com/browser/browser/components/search/test/browser/mozsearch.sjs", ], [PRIVATE_ENGINE_NAME, "https://example.com:443/browser/"], ]); let engine; let privateEngine; let extensions = []; let oldDefaultEngine; let oldDefaultPrivateEngine; add_setup(async function () { await SpecialPowers.pushPrefEnv({ set: [ ["browser.search.separatePrivateDefault", true], ["browser.search.separatePrivateDefault.ui.enabled", true], ], }); await Services.search.init(); for (let [name, search_url] of ENGINE_DATA) { let extension = ExtensionTestUtils.loadExtension({ manifest: { chrome_settings_overrides: { search_provider: { name, search_url, params: [ { name: "test", value: "{searchTerms}", }, ], }, }, }, }); await extension.startup(); await AddonTestUtils.waitForSearchProviderStartup(extension); extensions.push(extension); } engine = await Services.search.getEngineByName(ENGINE_NAME); Assert.ok(engine, "Got a search engine"); oldDefaultEngine = await Services.search.getDefault(); await Services.search.setDefault( engine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); privateEngine = await Services.search.getEngineByName(PRIVATE_ENGINE_NAME); Assert.ok(privateEngine, "Got a search engine"); oldDefaultPrivateEngine = await Services.search.getDefaultPrivate(); await Services.search.setDefaultPrivate( privateEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); }); async function checkContextMenu( win, expectedName, expectedBaseUrl, expectedPrivateName ) { let contextMenu = win.document.getElementById("contentAreaContextMenu"); Assert.ok(contextMenu, "Got context menu XUL"); let tab = await BrowserTestUtils.openNewForegroundTab( win.gBrowser, "https://example.com/browser/browser/components/search/test/browser/test_search.html" ); await SpecialPowers.spawn(tab.linkedBrowser, [""], async function () { return new Promise(resolve => { content.document.addEventListener( "selectionchange", function () { resolve(); }, { once: true } ); content.document.getSelection().selectAllChildren(content.document.body); }); }); let eventDetails = { type: "contextmenu", button: 2 }; let popupPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); BrowserTestUtils.synthesizeMouseAtCenter( "body", eventDetails, win.gBrowser.selectedBrowser ); await popupPromise; info("checkContextMenu"); let searchItem = contextMenu.getElementsByAttribute( "id", "context-searchselect" )[0]; Assert.ok(searchItem, "Got search context menu item"); Assert.equal( searchItem.label, "Search " + expectedName + " for \u201ctest%20search\u201d", "Check context menu label" ); Assert.equal( searchItem.disabled, false, "Check that search context menu item is enabled" ); let loaded = BrowserTestUtils.waitForNewTab( win.gBrowser, expectedBaseUrl + "?test=test%2520search", true ); contextMenu.activateItem(searchItem); let searchTab = await loaded; let browser = win.gBrowser.selectedBrowser; await SpecialPowers.spawn(browser, [], async function () { Assert.ok( !/error/.test(content.document.body.innerHTML), "Ensure there were no errors loading the search page" ); }); searchItem = contextMenu.getElementsByAttribute( "id", "context-searchselect-private" )[0]; Assert.ok(searchItem, "Got search in private window context menu item"); if (PrivateBrowsingUtils.isWindowPrivate(win)) { Assert.ok(searchItem.hidden, "Search in private window should be hidden"); } else { let expectedLabel = expectedPrivateName ? "Search with " + expectedPrivateName + " in a Private Window" : "Search in a Private Window"; Assert.equal(searchItem.label, expectedLabel, "Check context menu label"); Assert.equal( searchItem.disabled, false, "Check that search context menu item is enabled" ); } contextMenu.hidePopup(); BrowserTestUtils.removeTab(searchTab); BrowserTestUtils.removeTab(tab); } add_task(async function test_normalWindow() { await checkContextMenu( window, ENGINE_NAME, "https://example.com/browser/browser/components/search/test/browser/mozsearch.sjs", PRIVATE_ENGINE_NAME ); }); add_task(async function test_privateWindow() { const win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); registerCleanupFunction(async () => { await BrowserTestUtils.closeWindow(win); }); await checkContextMenu( win, PRIVATE_ENGINE_NAME, "https://example.com/browser/" ); }); add_task(async function test_normalWindow_sameDefaults() { // Set the private default engine to be the same as the current default engine // in 'normal' mode. await Services.search.setDefaultPrivate( await Services.search.getDefault(), Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await checkContextMenu( window, ENGINE_NAME, "https://example.com/browser/browser/components/search/test/browser/mozsearch.sjs" ); }); add_task(async function test_privateWindow_no_separate_engine() { await SpecialPowers.pushPrefEnv({ set: [ // We want select events to be fired. ["browser.search.separatePrivateDefault", false], ], }); const win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); registerCleanupFunction(async () => { await BrowserTestUtils.closeWindow(win); }); await checkContextMenu( win, ENGINE_NAME, "https://example.com/browser/browser/components/search/test/browser/mozsearch.sjs" ); }); // We can't do the unload within registerCleanupFunction as that's too late for // the test to be happy. Do it into a cleanup "test" here instead. add_task(async function cleanup() { await Services.search.setDefault( oldDefaultEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await Services.search.setDefaultPrivate( oldDefaultPrivateEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await Services.search.removeEngine(engine); await Services.search.removeEngine(privateEngine); for (let extension of extensions) { await extension.unload(); } });