Bug 1646423 - Experimental features should only be displayed on release channels that they are intended for. r=mstriemer,preferences-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D80714
This commit is contained in:
Jared Wein 2020-06-26 03:45:05 +00:00
parent e23dc1af7e
commit 9e14db259e
5 changed files with 111 additions and 4 deletions

View File

@ -63,9 +63,14 @@ var gExperimentalPane = {
"pane-experimental-featureGates"
);
this._boundRestartObserver = this._observeRestart.bind(this);
let features = await FeatureGate.all();
let searchParams = new URLSearchParams(document.documentURIObject.query);
let definitionsUrl = searchParams.get("definitionsUrl");
let features = await FeatureGate.all(definitionsUrl);
let frag = document.createDocumentFragment();
for (let feature of features) {
if (!feature.isPublic) {
continue;
}
if (Preferences.get(feature.preference)) {
console.error(
"Preference control already exists for experimental feature '" +

View File

@ -18,6 +18,7 @@ skip-if = !updater
[browser_bug731866.js]
[browser_bug1579418.js]
[browser_experimental_features.js]
[browser_experimental_features_hidden_when_not_public.js]
[browser_filetype_dialog.js]
[browser_search_no_results_change_category.js]
[browser_search_within_preferences_1.js]

View File

@ -30,8 +30,7 @@ add_task(async function testCanOpenWithPref() {
ok(experimentalCategory, "The category exists");
ok(!experimentalCategory.hidden, "The category is not hidden");
let categoryHeader;
categoryHeader = await TestUtils.waitForCondition(
let categoryHeader = await TestUtils.waitForCondition(
() => doc.getElementById("firefoxExperimentalCategory"),
"Waiting for experimental features category to get initialized"
);

View File

@ -0,0 +1,97 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
ChromeUtils.import("resource://featuregates/FeatureGate.jsm", this);
ChromeUtils.import(
"resource://featuregates/FeatureGateImplementation.jsm",
this
);
ChromeUtils.import("resource://testing-common/httpd.js", this);
class DefinitionServer {
constructor(definitionOverrides = []) {
this.server = new HttpServer();
this.server.registerPathHandler("/definitions.json", this);
this.definitions = {};
for (const override of definitionOverrides) {
this.addDefinition(override);
}
this.server.start();
registerCleanupFunction(
() => new Promise(resolve => this.server.stop(resolve))
);
}
// for nsIHttpRequestHandler
handle(request, response) {
response.write(JSON.stringify(this.definitions));
}
get definitionsUrl() {
const { primaryScheme, primaryHost, primaryPort } = this.server.identity;
return `${primaryScheme}://${primaryHost}:${primaryPort}/definitions.json`;
}
addDefinition(overrides = {}) {
const definition = {
id: "test-feature",
// These l10n IDs are just random so we have some text to display
title: "pane-experimental-subtitle",
description: "pane-experimental-description",
restartRequired: false,
type: "boolean",
preference: "test.feature",
defaultValue: false,
isPublic: false,
...overrides,
};
// convert targeted values, used by fromId
definition.isPublic = { default: definition.isPublic };
definition.defaultValue = { default: definition.defaultValue };
this.definitions[definition.id] = definition;
return definition;
}
}
add_task(async function testNonPublicFeaturesShouldntGetDisplayed() {
await SpecialPowers.pushPrefEnv({
set: [["browser.preferences.experimental", true]],
});
const server = new DefinitionServer();
let definitions = [
{ id: "test-featureA", isPublic: true, preference: "test.feature.a" },
{ id: "test-featureB", isPublic: false, preference: "test.feature.b" },
{ id: "test-featureC", isPublic: true, preference: "test.feature.c" },
];
for (let { id, isPublic, preference } of definitions) {
server.addDefinition({ id, isPublic, preference });
}
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
`about:preferences?definitionsUrl=${encodeURIComponent(
server.definitionsUrl
)}#paneExperimental`
);
let doc = gBrowser.contentDocument;
await TestUtils.waitForCondition(
() => doc.getElementById(definitions.find(d => d.isPublic).id),
"wait for the first public feature to get added to the DOM"
);
for (let definition of definitions) {
is(
!!doc.getElementById(definition.id),
definition.isPublic,
"feature should only be in DOM if it's public: " + definition.id
);
}
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

View File

@ -31,7 +31,12 @@ const kTargetFacts = new Map([
["release", AppConstants.MOZ_UPDATE_CHANNEL === "release"],
["beta", AppConstants.MOZ_UPDATE_CHANNEL === "beta"],
["dev-edition", AppConstants.MOZ_UPDATE_CHANNEL === "aurora"],
["nightly", AppConstants.MOZ_UPDATE_CHANNEL === "nightly"],
[
"nightly",
AppConstants.MOZ_UPDATE_CHANNEL === "nightly" ||
/* Treat local builds the same as Nightly builds */
AppConstants.MOZ_UPDATE_CHANNEL === "default",
],
["win", AppConstants.platform === "win"],
["mac", AppConstants.platform === "macosx"],
["linux", AppConstants.platform === "linux"],