commit 8f71edffd04897bc2a673d04e7c48b7c74f32633
parent a3c91c5ecb3c912b503aa5b968883e276f62e124
Author: Beth Rennie <beth@brennie.ca>
Date: Fri, 31 Oct 2025 03:39:48 +0000
Bug 1972647 - Hide Firefox Labs opt-ins from about:studies r=nimbus-reviewers,relud
We do not want users to confuse these opt-ins with regular studies,
especially when studies are disabled, as that may lead them to believe
that we are running studies without their consent.
Differential Revision: https://phabricator.services.mozilla.com/D269918
Diffstat:
2 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/toolkit/components/normandy/content/AboutPages.sys.mjs b/toolkit/components/normandy/content/AboutPages.sys.mjs
@@ -101,7 +101,11 @@ ChromeUtils.defineLazyGetter(AboutPages, "aboutStudies", () => {
},
getMessagingSystemList() {
- return lazy.ExperimentAPI.manager.store.getAll();
+ // Do not include Firefox Labs. Those are shown on
+ // about:preferences#experimental.
+ return lazy.ExperimentAPI.manager.store
+ .getAll()
+ .filter(e => !e.isFirefoxLabsOptIn);
},
async optInToExperiment(data) {
@@ -220,7 +224,7 @@ ChromeUtils.defineLazyGetter(AboutPages, "aboutStudies", () => {
);
this._sendToAll(
"Shield:UpdateMessagingSystemExperimentList",
- lazy.ExperimentAPI.manager.store.getAll()
+ this.getMessagingSystemList()
);
},
diff --git a/toolkit/components/normandy/test/browser/browser_about_studies.js b/toolkit/components/normandy/test/browser/browser_about_studies.js
@@ -12,8 +12,8 @@ const { NimbusTestUtils } = ChromeUtils.importESModule(
const { ExperimentAPI } = ChromeUtils.importESModule(
"resource://nimbus/ExperimentAPI.sys.mjs"
);
-const { RemoteSettingsExperimentLoader } = ChromeUtils.importESModule(
- "resource://nimbus/lib/RemoteSettingsExperimentLoader.sys.mjs"
+const { FirefoxLabs } = ChromeUtils.importESModule(
+ "resource://nimbus/FirefoxLabs.sys.mjs"
);
const { NormandyTestUtils } = ChromeUtils.importESModule(
@@ -866,7 +866,7 @@ add_task(async function test_forceEnroll() {
}
);
- NimbusTestUtils.assert.storeIsEmpty(ExperimentAPI.manager.store);
+ await NimbusTestUtils.assert.storeIsEmpty(ExperimentAPI.manager.store);
sandbox.restore();
});
@@ -956,3 +956,51 @@ add_task(async function test_inactive_rollouts_under_completed_studies() {
// Cleanup for multiple test runs
await NimbusTestUtils.assert.storeIsEmpty(ExperimentAPI.manager.store);
});
+
+add_task(async function testFirefoxLabs() {
+ const study = NimbusTestUtils.factories.recipe("study");
+ await ExperimentAPI.manager.enroll(study, "rs-loader");
+
+ const optin = NimbusTestUtils.factories.recipe("optin", {
+ isRollout: true,
+ isFirefoxLabsOptIn: true,
+ firefoxLabsTitle: "title",
+ firefoxLabsDescription: "description",
+ firefoxLabsGroup: "group",
+ requiresRestart: false,
+ });
+
+ ExperimentAPI.manager.optInRecipes.push(optin);
+
+ const labs = await FirefoxLabs.create();
+ await labs.enroll("optin", "control");
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: "about:studies" },
+ async browser => {
+ const nimbusItems = await SpecialPowers.spawn(browser, [], async () => {
+ await ContentTaskUtils.waitForCondition(
+ () => content.document.querySelector(".nimbus .remove-button"),
+ "waiting for page to load"
+ );
+
+ return Array.from(
+ content.document.querySelectorAll(".nimbus"),
+ el => el.dataset.studySlug
+ );
+ });
+
+ Assert.deepEqual(
+ nimbusItems,
+ ["study"],
+ "Firefox Labs opt-in not present"
+ );
+ }
+ );
+
+ await labs.unenroll("optin", "control");
+ await ExperimentAPI.manager.unenroll("study");
+ ExperimentAPI.manager.optInRecipes.pop();
+
+ await NimbusTestUtils.assert.storeIsEmpty(ExperimentAPI.manager.store);
+});