/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /** * Browser test for the weather suggestion. */ "use strict"; ChromeUtils.defineESModuleGetters(this, { UrlbarProviderWeather: "resource:///modules/UrlbarProviderWeather.sys.mjs", }); add_setup(async function () { await QuickSuggestTestUtils.ensureQuickSuggestInit({ remoteSettingsResults: [ { type: "weather", weather: MerinoTestUtils.WEATHER_RS_DATA, }, ], }); await MerinoTestUtils.initWeather(); }); // This test ensures the browser navigates to the weather webpage after // the weather result is selected. add_task(async function test_weather_result_selection() { let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); let browserLoadedPromise = BrowserTestUtils.browserLoaded( tab.linkedBrowser, false ); await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: MerinoTestUtils.WEATHER_KEYWORD, }); info(`Select the weather result`); EventUtils.synthesizeKey("KEY_ArrowDown"); info(`Navigate to the weather url`); EventUtils.synthesizeKey("KEY_Enter"); await browserLoadedPromise; Assert.equal( gBrowser.currentURI.spec, "https://example.com/weather", "Assert the page navigated to the weather webpage after selecting the weather result." ); BrowserTestUtils.removeTab(tab); await PlacesUtils.history.clear(); }); // Does a search, clicks the "Show less frequently" result menu command, and // repeats both steps until the min keyword length cap is reached. add_task(async function showLessFrequentlyCapReached_manySearches() { // Set up a min keyword length and cap. await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: { keywords: ["weather"], min_keyword_length: 3, min_keyword_length_cap: 4, }, }, ]); // Trigger the suggestion. await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "wea", }); let resultIndex = 1; let details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); Assert.equal( details.result.providerName, UrlbarProviderWeather.name, "Weather suggestion should be present at expected index after 'wea' search" ); // Click the command. let command = "show_less_frequently"; await UrlbarTestUtils.openResultMenuAndClickItem(window, command, { resultIndex, }); Assert.ok( gURLBar.view.isOpen, "The view should remain open clicking the command" ); Assert.ok( details.element.row.hasAttribute("feedback-acknowledgment"), "Row should have feedback acknowledgment after clicking command" ); Assert.equal( UrlbarPrefs.get("weather.minKeywordLength"), 4, "weather.minKeywordLength should be incremented once" ); // Do the same search again. The suggestion should not appear. await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "wea", }); for (let i = 0; i < UrlbarTestUtils.getResultCount(window); i++) { details = await UrlbarTestUtils.getDetailsOfResultAt(window, i); Assert.notEqual( details.result.providerName, UrlbarProviderWeather.name, `Weather suggestion should be absent (checking index ${i})` ); } // Do a search using one more character. The suggestion should appear. await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "weat", }); details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); Assert.equal( details.result.providerName, UrlbarProviderWeather.name, "Weather suggestion should be present at expected index after 'weat' search" ); Assert.ok( !details.element.row.hasAttribute("feedback-acknowledgment"), "Row should not have feedback acknowledgment after 'weat' search" ); // Since the cap has been reached, the command should no longer appear in the // result menu. await UrlbarTestUtils.openResultMenu(window, { resultIndex }); let menuitem = gURLBar.view.resultMenu.querySelector( `menuitem[data-command=${command}]` ); Assert.ok(!menuitem, "Menuitem should be absent"); gURLBar.view.resultMenu.hidePopup(true); await UrlbarTestUtils.promisePopupClose(window); await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: MerinoTestUtils.WEATHER_RS_DATA, }, ]); UrlbarPrefs.clear("weather.minKeywordLength"); }); // Repeatedly clicks the "Show less frequently" result menu command after doing // a single search until the min keyword length cap is reached. add_task(async function showLessFrequentlyCapReached_oneSearch() { // Set up a min keyword length and cap. await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: { keywords: ["weather"], min_keyword_length: 3, min_keyword_length_cap: 6, }, }, ]); // Trigger the suggestion. await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "wea", }); let resultIndex = 1; let details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); Assert.equal( details.result.providerName, UrlbarProviderWeather.name, "Weather suggestion should be present at expected index after 'wea' search" ); let command = "show_less_frequently"; for (let i = 0; i < 3; i++) { await UrlbarTestUtils.openResultMenuAndClickItem(window, command, { resultIndex, openByMouse: true, }); Assert.ok( gURLBar.view.isOpen, "The view should remain open clicking the command" ); Assert.ok( details.element.row.hasAttribute("feedback-acknowledgment"), "Row should have feedback acknowledgment after clicking command" ); Assert.equal( UrlbarPrefs.get("weather.minKeywordLength"), 4 + i, "weather.minKeywordLength should be incremented once" ); } let menuitem = await UrlbarTestUtils.openResultMenuAndGetItem({ window, command, resultIndex, }); Assert.ok( !menuitem, "The menuitem should not exist after the cap is reached" ); gURLBar.view.resultMenu.hidePopup(true); await UrlbarTestUtils.promisePopupClose(window); await QuickSuggestTestUtils.setRemoteSettingsResults([ { type: "weather", weather: MerinoTestUtils.WEATHER_RS_DATA, }, ]); UrlbarPrefs.clear("weather.minKeywordLength"); }); // Tests the "Not interested" result menu dismissal command. add_task(async function notInterested() { await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: MerinoTestUtils.WEATHER_KEYWORD, }); await doDismissTest("not_interested"); }); // Tests the "Not relevant" result menu dismissal command. add_task(async function notRelevant() { await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: MerinoTestUtils.WEATHER_KEYWORD, }); await doDismissTest("not_relevant"); }); async function doDismissTest(command) { let resultCount = UrlbarTestUtils.getResultCount(window); let resultIndex = 1; let details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); Assert.equal( details.result.providerName, UrlbarProviderWeather.name, "Weather suggestion should be present" ); // Click the command. await UrlbarTestUtils.openResultMenuAndClickItem( window, ["[data-l10n-id=firefox-suggest-command-dont-show-this]", command], { resultIndex, openByMouse: true } ); Assert.ok( !UrlbarPrefs.get("suggest.weather"), "suggest.weather pref should be set to false after dismissal" ); // The row should be a tip now. Assert.ok(gURLBar.view.isOpen, "The view should remain open after dismissal"); Assert.equal( UrlbarTestUtils.getResultCount(window), resultCount, "The result count should not haved changed after dismissal" ); details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); Assert.equal( details.type, UrlbarUtils.RESULT_TYPE.TIP, "Row should be a tip after dismissal" ); Assert.equal( details.result.payload.type, "dismissalAcknowledgment", "Tip type should be dismissalAcknowledgment" ); Assert.ok( !details.element.row.hasAttribute("feedback-acknowledgment"), "Row should not have feedback acknowledgment after dismissal" ); // Get the dismissal acknowledgment's "Got it" button and click it. let gotItButton = UrlbarTestUtils.getButtonForResultIndex( window, "0", resultIndex ); Assert.ok(gotItButton, "Row should have a 'Got it' button"); EventUtils.synthesizeMouseAtCenter(gotItButton, {}, window); // The view should remain open and the tip row should be gone. Assert.ok( gURLBar.view.isOpen, "The view should remain open clicking the 'Got it' button" ); Assert.equal( UrlbarTestUtils.getResultCount(window), resultCount - 1, "The result count should be one less after clicking 'Got it' button" ); for (let i = 0; i < UrlbarTestUtils.getResultCount(window); i++) { details = await UrlbarTestUtils.getDetailsOfResultAt(window, i); Assert.ok( details.type != UrlbarUtils.RESULT_TYPE.TIP && details.result.providerName != UrlbarProviderWeather.name, "Tip result and weather result should not be present" ); } await UrlbarTestUtils.promisePopupClose(window); // Enable the weather suggestion again and wait for it to be fetched. let fetchPromise = QuickSuggest.weather.waitForFetches(); UrlbarPrefs.clear("suggest.weather"); info("Waiting for weather fetch after re-enabling the suggestion"); await fetchPromise; info("Got weather fetch"); } // Tests the "Report inaccurate location" result menu command immediately // followed by a dismissal command to make sure other commands still work // properly while the urlbar session remains ongoing. add_task(async function inaccurateLocationAndDismissal() { await doSessionOngoingCommandTest("inaccurate_location"); }); // Tests the "Show less frequently" result menu command immediately followed by // a dismissal command to make sure other commands still work properly while the // urlbar session remains ongoing. add_task(async function showLessFrequentlyAndDismissal() { await doSessionOngoingCommandTest("show_less_frequently"); UrlbarPrefs.clear("weather.minKeywordLength"); }); async function doSessionOngoingCommandTest(command) { // Trigger the suggestion. await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: MerinoTestUtils.WEATHER_KEYWORD, }); let resultIndex = 1; let details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); Assert.equal( details.result.providerName, UrlbarProviderWeather.name, "Weather suggestion should be present at expected index after search" ); // Click the command. await UrlbarTestUtils.openResultMenuAndClickItem(window, command, { resultIndex, }); Assert.ok( gURLBar.view.isOpen, "The view should remain open clicking the command" ); Assert.ok( details.element.row.hasAttribute("feedback-acknowledgment"), "Row should have feedback acknowledgment after clicking command" ); info("Doing dismissal"); await doDismissTest("not_interested"); }