Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const SETTING_ID = "highlightToSearchEnabled";
const ASK_SETTING_ID = "highlightToSearchAskChatbot";
const SEARCH_SETTING_ID = "highlightToSearchSearch";
const FEATURE_GATE_PREF = "browser.highlightToSearch.featureGate";
const ENABLED_PREF = "browser.highlightToSearch.enabled";
const SEARCH_ENABLED_PREF = "browser.highlightToSearch.search.enabled";
const SHORTCUTS_PREF = "browser.ml.chat.shortcuts";
const PROVIDER_PREF = "browser.ml.chat.provider";
/**
* Open the pane that holds the setting, which differs between the redesigned
* and legacy layouts.
*
* @returns {Promise<{tab: MozTabbrowserTab, control: Element}>}
*/
async function openPaneWithSetting() {
let pane = Services.prefs.getBoolPref("browser.settings-redesign.enabled")
? "tabsBrowsing"
: "general";
let tab = await openPrefsTab(pane);
let doc = tab.linkedBrowser.contentDocument;
await TestUtils.waitForCondition(
() => doc.getElementById(SETTING_ID),
"Wait for the setting to render"
);
return { tab, control: doc.getElementById(SETTING_ID) };
}
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [
["browser.ml.chat.enabled", true],
["browser.ml.chat.openSidebarOnProviderChange", false],
["sidebar.main.tools", "aichat,history"],
],
});
});
add_task(async function test_visibility_follows_feature_gate() {
Assert.ok(
!Services.prefs.getBoolPref(FEATURE_GATE_PREF),
"Feature gate is off by default"
);
let { tab, control } = await openPaneWithSetting();
await TestUtils.waitForCondition(
() => BrowserTestUtils.isHidden(control),
"Wait for the setting to be hidden"
);
is_element_hidden(control, "Hidden while the feature gate is off");
await SpecialPowers.pushPrefEnv({ set: [[FEATURE_GATE_PREF, true]] });
await TestUtils.waitForCondition(
() => BrowserTestUtils.isVisible(control),
"Wait for the setting to be shown"
);
is_element_visible(control, "Shown once the feature gate turns on");
await SpecialPowers.popPrefEnv();
await TestUtils.waitForCondition(
() => BrowserTestUtils.isHidden(control),
"Wait for the setting to be hidden again"
);
is_element_hidden(control, "Hidden again once the feature gate turns off");
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_checkbox_controls_pref() {
Services.fog.testResetFOG();
await SpecialPowers.pushPrefEnv({
set: [
[FEATURE_GATE_PREF, true],
[ENABLED_PREF, false],
],
});
let { tab, control } = await openPaneWithSetting();
await TestUtils.waitForCondition(
() => BrowserTestUtils.isVisible(control),
"Wait for the setting to be shown"
);
Assert.ok(!control.checked, "Unchecked while the menu is turned off");
control.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(
control.labelEl,
{},
control.documentGlobal
);
await TestUtils.waitForCondition(
() => Services.prefs.getBoolPref(ENABLED_PREF),
"Wait for the pref to turn on"
);
Assert.ok(control.checked, "Checking the setting turns the menu on");
control.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(
control.labelEl,
{},
control.documentGlobal
);
await TestUtils.waitForCondition(
() => !Services.prefs.getBoolPref(ENABLED_PREF),
"Wait for the pref to turn off"
);
Assert.ok(!control.checked, "Unchecking the setting turns the menu off");
Assert.deepEqual(
Glean.selectionMenu.optionToggled
.testGetValue()
.map(({ extra: { action, enabled, source } }) => [
action,
enabled,
source,
]),
[
["master", "true", "settings"],
["master", "false", "settings"],
],
"Both clicks on the menu setting are recorded"
);
await BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
add_task(async function test_ask_chatbot_toggle() {
await SpecialPowers.pushPrefEnv({
set: [
[FEATURE_GATE_PREF, true],
[PROVIDER_PREF, "https://chatgpt.com"],
[SHORTCUTS_PREF, true],
],
});
let { tab } = await openPaneWithSetting();
let doc = tab.linkedBrowser.contentDocument;
let ask = doc.getElementById(ASK_SETTING_ID);
await TestUtils.waitForCondition(
() => BrowserTestUtils.isVisible(ask),
"Wait for the ask setting to be shown"
);
await TestUtils.waitForCondition(
() => ask.label == "Ask ChatGPT",
"Wait for the provider name in the label"
);
Assert.equal(ask.label, "Ask ChatGPT", "Names the chosen provider");
await SpecialPowers.pushPrefEnv({ set: [[PROVIDER_PREF, ""]] });
await TestUtils.waitForCondition(
() => ask.label == "Ask AI",
"Wait for the generic label"
);
Assert.equal(
ask.label,
"Ask AI",
"Falls back to a generic name once no provider is chosen"
);
await SpecialPowers.popPrefEnv();
await BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
add_task(async function test_menu_never_on_without_an_action() {
Services.fog.testResetFOG();
await SpecialPowers.pushPrefEnv({
set: [
[FEATURE_GATE_PREF, true],
[ENABLED_PREF, true],
[SHORTCUTS_PREF, true],
[SEARCH_ENABLED_PREF, true],
],
});
let { tab } = await openPaneWithSetting();
let doc = tab.linkedBrowser.contentDocument;
await TestUtils.waitForCondition(
() =>
BrowserTestUtils.isVisible(doc.getElementById(ASK_SETTING_ID)) &&
BrowserTestUtils.isVisible(doc.getElementById(SEARCH_SETTING_ID)),
"Wait for both actions to be shown"
);
// Re-fetch each control right before use: toggling one re-renders the
// group, which detaches any element reference captured beforehand.
let ask = doc.getElementById(ASK_SETTING_ID);
ask.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(ask.labelEl, {}, ask.documentGlobal);
await TestUtils.waitForCondition(
() => !Services.prefs.getBoolPref(SHORTCUTS_PREF),
"Wait for the ai action to turn off"
);
Assert.ok(
doc.getElementById(SETTING_ID).checked,
"Menu stays on while search is still checked"
);
let search = doc.getElementById(SEARCH_SETTING_ID);
search.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(search.labelEl, {}, search.documentGlobal);
await TestUtils.waitForCondition(
() => !Services.prefs.getBoolPref(ENABLED_PREF),
"Wait for the menu pref to turn off"
);
Assert.ok(
!Services.prefs.getBoolPref(SEARCH_ENABLED_PREF),
"Unchecking the setting hides the search action"
);
Assert.ok(
!doc.getElementById(SETTING_ID).checked,
"Unchecking the last action turns the menu off"
);
let control = doc.getElementById(SETTING_ID);
control.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(
control.labelEl,
{},
control.documentGlobal
);
await TestUtils.waitForCondition(
() =>
Services.prefs.getBoolPref(SHORTCUTS_PREF) &&
Services.prefs.getBoolPref(SEARCH_ENABLED_PREF),
"Wait for both actions to turn back on"
);
Assert.ok(
Services.prefs.getBoolPref(ENABLED_PREF),
"Checking the setting turns the menu on"
);
Assert.ok(
doc.getElementById(ASK_SETTING_ID).checked &&
doc.getElementById(SEARCH_SETTING_ID).checked,
"Turning the menu on with no action checked checks every action"
);
Assert.deepEqual(
Glean.selectionMenu.optionToggled
.testGetValue()
.map(({ extra: { action, enabled, source } }) => [
action,
enabled,
source,
]),
[
["ai", "false", "settings"],
["search", "false", "settings"],
["master", "false", "uncheck_all"],
["master", "true", "settings"],
],
"Each click is recorded, and the menu turning itself off is recorded after the click that caused it"
);
await BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
add_task(async function test_search_toggle() {
Services.fog.testResetFOG();
await SpecialPowers.pushPrefEnv({
set: [
[FEATURE_GATE_PREF, true],
[SEARCH_ENABLED_PREF, true],
],
});
let { tab } = await openPaneWithSetting();
let doc = tab.linkedBrowser.contentDocument;
let search = doc.getElementById(SEARCH_SETTING_ID);
await TestUtils.waitForCondition(
() => BrowserTestUtils.isVisible(search),
"Wait for the search setting to be shown"
);
Assert.ok(search.checked, "Starts checked to match the pref");
search.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(search.labelEl, {}, search.documentGlobal);
await TestUtils.waitForCondition(
() => !Services.prefs.getBoolPref(SEARCH_ENABLED_PREF),
"Wait for the pref to turn off"
);
Assert.ok(!search.checked, "Unchecking the setting turns search off");
let toggles = Glean.selectionMenu.optionToggled.testGetValue();
Assert.equal(toggles.length, 1, "One option toggled");
Assert.equal(toggles[0].extra.action, "search", "Toggled the search action");
Assert.equal(toggles[0].extra.enabled, "false", "Turned off");
Assert.equal(toggles[0].extra.source, "settings", "From the Settings pane");
await BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
add_task(async function test_ask_chatbot_hidden_when_chatbot_blocked() {
await SpecialPowers.pushPrefEnv({
set: [
[FEATURE_GATE_PREF, true],
["browser.ml.chat.enabled", false],
],
});
let { tab, control } = await openPaneWithSetting();
let doc = tab.linkedBrowser.contentDocument;
await TestUtils.waitForCondition(
() => BrowserTestUtils.isVisible(control),
"Wait for the menu setting to be shown"
);
await TestUtils.waitForCondition(
() => doc.getElementById(ASK_SETTING_ID),
"Wait for the ask setting to render"
);
let ask = doc.getElementById(ASK_SETTING_ID);
await TestUtils.waitForCondition(
() => BrowserTestUtils.isHidden(ask),
"Wait for the ask setting to be hidden"
);
is_element_hidden(ask, "No AI action to offer when the chatbot is blocked");
await BrowserTestUtils.removeTab(tab);
await SpecialPowers.popPrefEnv();
});