зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1746598 - Route MS messages to PB newtab r=dmose,extension-reviewers,rpl
Differential Revision: https://phabricator.services.mozilla.com/D134157
This commit is contained in:
Родитель
2d4b0eb9d6
Коммит
c1807eee8c
|
@ -46,10 +46,8 @@ class AboutPrivateBrowsingChild extends RemotePageChild {
|
|||
}
|
||||
}
|
||||
|
||||
PrivateBrowsingFeatureConfig(defaultValues) {
|
||||
const config = NimbusFeatures.privatebrowsing.getAllVariables({
|
||||
defaultValues,
|
||||
});
|
||||
PrivateBrowsingFeatureConfig() {
|
||||
const config = NimbusFeatures.privatebrowsing.getAllVariables() || {};
|
||||
|
||||
NimbusFeatures.privatebrowsing.recordExposureEvent();
|
||||
|
||||
|
|
|
@ -1461,7 +1461,7 @@ pref("browser.newtabpage.activity-stream.asrouter.providers.message-groups", "{\
|
|||
// this page over http opens us up to a man-in-the-middle attack that we'd rather not face. If you are a downstream
|
||||
// repackager of this code using an alternate snippet url, please keep your users safe
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.snippets", "{\"id\":\"snippets\",\"enabled\":false,\"type\":\"remote\",\"url\":\"https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/\",\"updateCycleInMs\":14400000}");
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.messaging-experiments", "{\"id\":\"messaging-experiments\",\"enabled\":true,\"type\":\"remote-experiments\",\"messageGroups\":[\"cfr\",\"aboutwelcome\",\"infobar\",\"spotlight\",\"moments-page\"],\"updateCycleInMs\":3600000}");
|
||||
pref("browser.newtabpage.activity-stream.asrouter.providers.messaging-experiments", "{\"id\":\"messaging-experiments\",\"enabled\":true,\"type\":\"remote-experiments\",\"messageGroups\":[\"cfr\",\"aboutwelcome\",\"infobar\",\"spotlight\",\"moments-page\",\"pbNewtab\"],\"updateCycleInMs\":3600000}");
|
||||
|
||||
// ASRouter user prefs
|
||||
pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", true);
|
||||
|
|
|
@ -718,7 +718,12 @@ let JSWINDOWACTORS = {
|
|||
DOMDocElementInserted: {},
|
||||
},
|
||||
},
|
||||
matches: ["about:home*", "about:newtab*", "about:welcome*"],
|
||||
matches: [
|
||||
"about:home*",
|
||||
"about:newtab*",
|
||||
"about:welcome*",
|
||||
"about:privatebrowsing",
|
||||
],
|
||||
remoteTypes: ["privilegedabout"],
|
||||
},
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ add_task(async function test_no_show_hide_for_private_window() {
|
|||
});
|
||||
|
||||
// Open and close a menu on the private window.
|
||||
let menu = await openContextMenu("body", privateWindow);
|
||||
let menu = await openContextMenu("body div", privateWindow);
|
||||
// We should not see the "not_allowed" extension here.
|
||||
ok(
|
||||
!privateWindow.document.getElementById(extMenuId),
|
||||
|
|
|
@ -10,6 +10,8 @@ const MESSAGE_TYPE_LIST = [
|
|||
"IMPRESSION",
|
||||
"TRIGGER",
|
||||
"NEWTAB_MESSAGE_REQUEST",
|
||||
// PB is Private Browsing
|
||||
"PBNEWTAB_MESSAGE_REQUEST",
|
||||
"DOORHANGER_TELEMETRY",
|
||||
"TOOLBAR_BADGE_TELEMETRY",
|
||||
"TOOLBAR_PANEL_TELEMETRY",
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
"title": "PBNewtabPromoMessage",
|
||||
"description": "Message shown on the private browsing newtab page.",
|
||||
"version": "1.0.0",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"infoEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Should we show the info section."
|
||||
},
|
||||
"infoIcon": {
|
||||
"type": "string",
|
||||
"description": "Icon shown in the left side of the info section. Default is the private browsing icon."
|
||||
},
|
||||
"infoTitle": {
|
||||
"type": "string",
|
||||
"description": "Is the title in the info section enabled."
|
||||
},
|
||||
"infoTitleEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Is the title in the info section enabled."
|
||||
},
|
||||
"infoBody": {
|
||||
"type": "string",
|
||||
"description": "Text content in the info section."
|
||||
},
|
||||
"infoLinkText": {
|
||||
"type": "string",
|
||||
"description": "Text for the link in the info section."
|
||||
},
|
||||
"infoLinkUrl": {
|
||||
"type": "string",
|
||||
"description": "URL for the info section link."
|
||||
},
|
||||
"promoEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Should we show the promo section."
|
||||
},
|
||||
"promoSectionStyle": {
|
||||
"type": "string",
|
||||
"description": "Sets the position of the promo section. Possible values are: top, below-search, bottom. Default bottom.",
|
||||
"enum": ["top", "below-search", "bottom"]
|
||||
},
|
||||
"promoTitle": {
|
||||
"type": "string",
|
||||
"description": "The text content of the promo section."
|
||||
},
|
||||
"promoTitleEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Should we show text content in the promo section."
|
||||
},
|
||||
"promoLinkText": {
|
||||
"type": "string",
|
||||
"description": "The text of the link in the promo box."
|
||||
},
|
||||
"promoHeader": {
|
||||
"type": "string",
|
||||
"description": "The title of the promo section."
|
||||
},
|
||||
"promoLinkUrl": {
|
||||
"type": "string",
|
||||
"description": "URL for link in the promo box."
|
||||
},
|
||||
"promoLinkType": {
|
||||
"type": "string",
|
||||
"description": "Type of promo link type. Possible values: link, button. Default is link.",
|
||||
"enum": ["link", "button"]
|
||||
},
|
||||
"promoImageLarge": {
|
||||
"type": "string",
|
||||
"description": "URL for image used on the left side of the promo box, larger, showcases some feature. Default off."
|
||||
},
|
||||
"promoImageSmall": {
|
||||
"type": "string",
|
||||
"description": "URL for image used on the right side of the promo box, smaller, usually a logo. Default off."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2363,7 +2363,8 @@ __webpack_require__.r(__webpack_exports__);
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
const MESSAGE_TYPE_LIST = ["BLOCK_MESSAGE_BY_ID", "USER_ACTION", "IMPRESSION", "TRIGGER", "NEWTAB_MESSAGE_REQUEST", "DOORHANGER_TELEMETRY", "TOOLBAR_BADGE_TELEMETRY", "TOOLBAR_PANEL_TELEMETRY", "MOMENTS_PAGE_TELEMETRY", "INFOBAR_TELEMETRY", "SPOTLIGHT_TELEMETRY", "AS_ROUTER_TELEMETRY_USER_EVENT", // Admin types
|
||||
const MESSAGE_TYPE_LIST = ["BLOCK_MESSAGE_BY_ID", "USER_ACTION", "IMPRESSION", "TRIGGER", "NEWTAB_MESSAGE_REQUEST", // PB is Private Browsing
|
||||
"PBNEWTAB_MESSAGE_REQUEST", "DOORHANGER_TELEMETRY", "TOOLBAR_BADGE_TELEMETRY", "TOOLBAR_PANEL_TELEMETRY", "MOMENTS_PAGE_TELEMETRY", "INFOBAR_TELEMETRY", "SPOTLIGHT_TELEMETRY", "AS_ROUTER_TELEMETRY_USER_EVENT", // Admin types
|
||||
"ADMIN_CONNECT_STATE", "UNBLOCK_MESSAGE_BY_ID", "UNBLOCK_ALL", "BLOCK_BUNDLE", "UNBLOCK_BUNDLE", "DISABLE_PROVIDER", "ENABLE_PROVIDER", "EVALUATE_JEXL_EXPRESSION", "EXPIRE_QUERY_CACHE", "FORCE_ATTRIBUTION", "FORCE_WHATSNEW_PANEL", "CLOSE_WHATSNEW_PANEL", "OVERRIDE_MESSAGE", "MODIFY_MESSAGE_JSON", "RESET_PROVIDER_PREF", "SET_PROVIDER_USER_PREF", "RESET_GROUPS_STATE"];
|
||||
const MESSAGE_TYPE_HASH = MESSAGE_TYPE_LIST.reduce((hash, value) => {
|
||||
hash[value] = value;
|
||||
|
|
|
@ -1582,6 +1582,30 @@ class _ASRouter {
|
|||
return this.loadMessagesFromAllProviders();
|
||||
}
|
||||
|
||||
async sendPBNewTabMessage({ tabId }) {
|
||||
let message = null;
|
||||
|
||||
await this.loadMessagesFromAllProviders();
|
||||
|
||||
const telemetryObject = { tabId };
|
||||
TelemetryStopwatch.start("MS_MESSAGE_REQUEST_TIME_MS", telemetryObject);
|
||||
message = await this.handleMessageRequest({ template: "pb_newtab" });
|
||||
TelemetryStopwatch.finish("MS_MESSAGE_REQUEST_TIME_MS", telemetryObject);
|
||||
|
||||
// Format urls if any are defined
|
||||
["infoLinkUrl", "promoLinkUrl"].forEach(key => {
|
||||
if (message?.content?.[key]) {
|
||||
message.content[key] = Services.urlFormatter.formatURL(
|
||||
message.content[key]
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
NimbusFeatures.pbNewtab.recordExposureEvent({ once: true });
|
||||
|
||||
return { message };
|
||||
}
|
||||
|
||||
async sendNewTabMessage({ endpoint, tabId, browser }) {
|
||||
let message;
|
||||
|
||||
|
@ -1662,6 +1686,7 @@ class _ASRouter {
|
|||
spotlight: "spotlight",
|
||||
infobar: "infobar",
|
||||
update_action: "moments-page",
|
||||
pb_newtab: "pbNewtab",
|
||||
};
|
||||
let feature = featureMap[nonReachMessages[0].template];
|
||||
if (feature) {
|
||||
|
|
|
@ -75,6 +75,13 @@ class ASRouterParentProcessMessageHandler {
|
|||
browser,
|
||||
});
|
||||
}
|
||||
case msg.PBNEWTAB_MESSAGE_REQUEST: {
|
||||
return this._router.sendPBNewTabMessage({
|
||||
...data,
|
||||
tabId,
|
||||
browser,
|
||||
});
|
||||
}
|
||||
case msg.NEWTAB_MESSAGE_REQUEST: {
|
||||
return this._router.sendNewTabMessage({
|
||||
...data,
|
||||
|
|
|
@ -37,6 +37,20 @@ const ONBOARDING_MESSAGES = () => [
|
|||
},
|
||||
trigger: { id: "protectionsPanelOpen" },
|
||||
},
|
||||
{
|
||||
id: "PB_NEWTAB_INFO_SECTION",
|
||||
template: "pb_newtab",
|
||||
content: {
|
||||
promoEnabled: false,
|
||||
infoEnabled: true,
|
||||
infoIcon: "",
|
||||
infoTitle: "",
|
||||
infoBody: "fluent:about-private-browsing-info-description-private-window",
|
||||
infoLinkText: "fluent:about-private-browsing-learn-more-link",
|
||||
infoTitleEnabled: false,
|
||||
},
|
||||
targeting: "true",
|
||||
},
|
||||
];
|
||||
|
||||
const OnboardingMessageProvider = {
|
||||
|
|
|
@ -311,6 +311,28 @@ const MESSAGES = () => [
|
|||
frequency: { lifetime: 3 },
|
||||
trigger: { id: "defaultBrowserCheck" },
|
||||
},
|
||||
{
|
||||
id: "PB_NEWTAB_VPN_PROMO",
|
||||
template: "pb_newtab",
|
||||
content: {
|
||||
promoEnabled: true,
|
||||
infoEnabled: true,
|
||||
infoIcon: "",
|
||||
infoTitle: "",
|
||||
infoBody: "fluent:about-private-browsing-info-description-private-window",
|
||||
infoLinkText: "fluent:about-private-browsing-learn-more-link",
|
||||
infoTitleEnabled: false,
|
||||
promoLinkType: "button",
|
||||
promoLinkText: "fluent:about-private-browsing-prominent-cta",
|
||||
promoSectionStyle: "below-search",
|
||||
promoHeader: "fluent:about-private-browsing-get-privacy",
|
||||
promoTitle: "fluent:about-private-browsing-hide-activity-1",
|
||||
promoTitleEnabled: true,
|
||||
promoImageLarge: "chrome://browser/content/assets/moz-vpn.svg",
|
||||
},
|
||||
targeting: "region != 'CN' && !hasActiveEnterprisePolicies",
|
||||
frequency: { lifetime: 3 },
|
||||
},
|
||||
];
|
||||
|
||||
const PanelTestProvider = {
|
||||
|
|
|
@ -14,7 +14,7 @@ describe("CFRMessageProvider", () => {
|
|||
beforeEach(async () => {
|
||||
messages = await CFRMessageProvider.getMessages();
|
||||
});
|
||||
it("should have a total of 10 messages", () => {
|
||||
it("should have a total of 11 messages", () => {
|
||||
assert.lengthOf(messages, 11);
|
||||
});
|
||||
it("should have one message each for the three regular addons", () => {
|
||||
|
|
|
@ -2,16 +2,17 @@ import { PanelTestProvider } from "lib/PanelTestProvider.jsm";
|
|||
import update_schema from "content-src/asrouter/templates/OnboardingMessage/UpdateAction.schema.json";
|
||||
import whats_new_schema from "content-src/asrouter/templates/OnboardingMessage/WhatsNewMessage.schema.json";
|
||||
import spotlight_schema from "content-src/asrouter/templates/OnboardingMessage/Spotlight.schema.json";
|
||||
import PBNewtabSchema from "content-src/asrouter/templates/PBNewtab/NewtabPromoMessage.schema.json";
|
||||
|
||||
describe("PanelTestProvider", () => {
|
||||
let messages;
|
||||
beforeEach(async () => {
|
||||
messages = await PanelTestProvider.getMessages();
|
||||
});
|
||||
it("should have a message", () => {
|
||||
it("should have 12 messages", () => {
|
||||
// Careful: when changing this number make sure that new messages also go
|
||||
// through schema verifications.
|
||||
assert.lengthOf(messages, 11);
|
||||
assert.lengthOf(messages, 12);
|
||||
});
|
||||
it("should be a valid message", () => {
|
||||
const updateMessages = messages.filter(
|
||||
|
@ -31,7 +32,7 @@ describe("PanelTestProvider", () => {
|
|||
assert.property(message, "order");
|
||||
}
|
||||
});
|
||||
it("should be a valid message", () => {
|
||||
it("should be a valid spotlight message", () => {
|
||||
const spotlightMessages = messages.filter(
|
||||
({ template }) => template === "spotlight"
|
||||
);
|
||||
|
@ -39,4 +40,11 @@ describe("PanelTestProvider", () => {
|
|||
assert.jsonSchema(message, spotlight_schema);
|
||||
}
|
||||
});
|
||||
it("should be a valid pb newtab message", () => {
|
||||
const pbNewtabMessages = messages.filter(
|
||||
({ template }) => template === "pb_newtab"
|
||||
);
|
||||
assert.lengthOf(pbNewtabMessages, 1);
|
||||
pbNewtabMessages.forEach(m => assert.jsonSchema(m, PBNewtabSchema));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="promo">
|
||||
<div class="promo" hidden>
|
||||
<div class="promo-image-large">
|
||||
<img src="" alt="" />
|
||||
</div>
|
||||
|
|
|
@ -38,7 +38,7 @@ async function renderInfo({
|
|||
infoLinkText,
|
||||
infoLinkUrl,
|
||||
infoIcon,
|
||||
}) {
|
||||
} = {}) {
|
||||
const container = document.querySelector(".info");
|
||||
if (infoEnabled === false) {
|
||||
container.remove();
|
||||
|
@ -75,7 +75,7 @@ async function renderInfo({
|
|||
}
|
||||
|
||||
async function renderPromo({
|
||||
promoEnabled,
|
||||
promoEnabled = false,
|
||||
promoTitle,
|
||||
promoTitleEnabled,
|
||||
promoLinkText,
|
||||
|
@ -85,7 +85,7 @@ async function renderPromo({
|
|||
promoHeader,
|
||||
promoImageLarge,
|
||||
promoImageSmall,
|
||||
}) {
|
||||
} = {}) {
|
||||
const container = document.querySelector(".promo");
|
||||
if (promoEnabled === false) {
|
||||
container.remove();
|
||||
|
@ -164,33 +164,26 @@ async function renderPromo({
|
|||
[linkEl, promoLinkText],
|
||||
[promoHeaderEl, promoHeader],
|
||||
]);
|
||||
|
||||
// Only make promo section visible after adding content
|
||||
// and translations to prevent layout shifting in page
|
||||
container.classList.add("promo-visible");
|
||||
}
|
||||
|
||||
const DEFAULT_PRIVATE_BROWSING_CONTENT = {
|
||||
promoEnabled: true,
|
||||
infoEnabled: true,
|
||||
infoIcon: "",
|
||||
infoTitle: "",
|
||||
infoBody: "fluent:about-private-browsing-info-description-private-window",
|
||||
infoLinkText: "fluent:about-private-browsing-learn-more-link",
|
||||
infoTitleEnabled: false,
|
||||
promoLinkType: "button",
|
||||
promoLinkText: "fluent:about-private-browsing-prominent-cta",
|
||||
promoSectionStyle: "below-search",
|
||||
promoHeader: "fluent:about-private-browsing-get-privacy",
|
||||
promoTitle: "fluent:about-private-browsing-hide-activity-1",
|
||||
promoTitleEnabled: true,
|
||||
promoImageLarge: "chrome://browser/content/assets/moz-vpn.svg",
|
||||
};
|
||||
|
||||
async function setupFeatureConfig() {
|
||||
// Setup experiment data
|
||||
let config = {};
|
||||
let config = null;
|
||||
try {
|
||||
config = window.PrivateBrowsingFeatureConfig(
|
||||
DEFAULT_PRIVATE_BROWSING_CONTENT
|
||||
);
|
||||
config = window.PrivateBrowsingFeatureConfig();
|
||||
} catch (e) {}
|
||||
if (!Object.keys(config).length) {
|
||||
try {
|
||||
let response = await window.ASRouterMessage({
|
||||
type: "PBNEWTAB_MESSAGE_REQUEST",
|
||||
data: {},
|
||||
});
|
||||
config = response?.message?.content;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
await renderInfo(config);
|
||||
await renderPromo(config);
|
||||
|
|
|
@ -8,6 +8,12 @@ const { ExperimentFakes } = ChromeUtils.import(
|
|||
const { ExperimentAPI } = ChromeUtils.import(
|
||||
"resource://nimbus/ExperimentAPI.jsm"
|
||||
);
|
||||
const { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
const { PanelTestProvider } = ChromeUtils.import(
|
||||
"resource://activity-stream/lib/PanelTestProvider.jsm"
|
||||
);
|
||||
|
||||
/**
|
||||
* These tests ensure that the experiment and remote default capabilities
|
||||
|
@ -46,10 +52,14 @@ function waitForTelemetryEvent(category) {
|
|||
}
|
||||
|
||||
add_task(async function test_experiment_plain_text() {
|
||||
const defaultMessageContent = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.template === "pb_newtab"
|
||||
).content;
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "privatebrowsing",
|
||||
enabled: true,
|
||||
value: {
|
||||
...defaultMessageContent,
|
||||
infoTitle: "Hello world",
|
||||
infoTitleEnabled: true,
|
||||
infoBody: "This is some text",
|
||||
|
@ -94,10 +104,14 @@ add_task(async function test_experiment_plain_text() {
|
|||
});
|
||||
|
||||
add_task(async function test_experiment_fluent() {
|
||||
const defaultMessageContent = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.template === "pb_newtab"
|
||||
).content;
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "privatebrowsing",
|
||||
enabled: true,
|
||||
value: {
|
||||
...defaultMessageContent,
|
||||
infoBody: "fluent:about-private-browsing-info-title",
|
||||
promoLinkText: "fluent:about-private-browsing-prominent-cta",
|
||||
},
|
||||
|
@ -180,6 +194,8 @@ add_task(async function test_experiment_format_urls() {
|
|||
featureId: "privatebrowsing",
|
||||
enabled: true,
|
||||
value: {
|
||||
infoEnabled: true,
|
||||
promoEnabled: true,
|
||||
infoLinkUrl: "http://foo.mozilla.com/%LOCALE%",
|
||||
promoLinkUrl: "http://bar.mozilla.com/%LOCALE%",
|
||||
},
|
||||
|
@ -238,6 +254,7 @@ add_task(async function test_experiment_click_promo_telemetry() {
|
|||
featureId: "privatebrowsing",
|
||||
enabled: true,
|
||||
value: {
|
||||
promoEnabled: true,
|
||||
promoLinkUrl: "http://example.com",
|
||||
},
|
||||
});
|
||||
|
@ -263,9 +280,13 @@ add_task(async function test_experiment_click_promo_telemetry() {
|
|||
});
|
||||
|
||||
add_task(async function test_experiment_bottom_promo() {
|
||||
const defaultMessageContent = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.template === "pb_newtab"
|
||||
).content;
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "privatebrowsing",
|
||||
value: {
|
||||
...defaultMessageContent,
|
||||
enabled: true,
|
||||
promoLinkType: "button",
|
||||
promoSectionStyle: "bottom",
|
||||
|
@ -316,9 +337,13 @@ add_task(async function test_experiment_bottom_promo() {
|
|||
});
|
||||
|
||||
add_task(async function test_experiment_below_search_promo() {
|
||||
const defaultMessageContent = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.template === "pb_newtab"
|
||||
).content;
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "privatebrowsing",
|
||||
value: {
|
||||
...defaultMessageContent,
|
||||
enabled: true,
|
||||
promoLinkType: "button",
|
||||
promoSectionStyle: "below-search",
|
||||
|
@ -371,9 +396,13 @@ add_task(async function test_experiment_below_search_promo() {
|
|||
});
|
||||
|
||||
add_task(async function test_experiment_top_promo() {
|
||||
const defaultMessageContent = (await PanelTestProvider.getMessages()).find(
|
||||
m => m.template === "pb_newtab"
|
||||
).content;
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "privatebrowsing",
|
||||
value: {
|
||||
...defaultMessageContent,
|
||||
enabled: true,
|
||||
promoLinkType: "button",
|
||||
promoSectionStyle: "top",
|
||||
|
@ -421,3 +450,91 @@ add_task(async function test_experiment_top_promo() {
|
|||
|
||||
await doExperimentCleanup();
|
||||
});
|
||||
|
||||
add_task(async function test_experiment_messaging_system() {
|
||||
const LOCALE = Services.locale.appLocaleAsBCP47;
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "pbNewtab",
|
||||
enabled: true,
|
||||
value: {
|
||||
id: "PB_NEWTAB_MESSAGING_SYSTEM",
|
||||
template: "pb_newtab",
|
||||
content: {
|
||||
promoEnabled: true,
|
||||
infoEnabled: true,
|
||||
infoBody: "fluent:about-private-browsing-info-title",
|
||||
promoLinkText: "fluent:about-private-browsing-prominent-cta",
|
||||
infoLinkUrl: "http://foo.example.com/%LOCALE%",
|
||||
promoLinkUrl: "http://bar.example.com/%LOCALE%",
|
||||
},
|
||||
// Priority ensures this message is picked over the one in
|
||||
// OnboardingMessageProvider
|
||||
priority: 5,
|
||||
targeting: "true",
|
||||
},
|
||||
});
|
||||
Services.prefs.setStringPref(
|
||||
"browser.newtabpage.activity-stream.asrouter.providers.messaging-experiments",
|
||||
'{"id":"messaging-experiments","enabled":true,"type":"remote-experiments","messageGroups":["pbNewtab"],"updateCycleInMs":0}'
|
||||
);
|
||||
const { ASRouter } = ChromeUtils.import(
|
||||
"resource://activity-stream/lib/ASRouter.jsm"
|
||||
);
|
||||
// Reload the provider
|
||||
await ASRouter._updateMessageProviders();
|
||||
// Wait to load the messages from the messaging-experiments provider
|
||||
await ASRouter.loadMessagesFromAllProviders();
|
||||
|
||||
Assert.ok(
|
||||
ASRouter.state.messages.find(m => m.id === "PB_NEWTAB_MESSAGING_SYSTEM"),
|
||||
"Experiment message found in ASRouter state"
|
||||
);
|
||||
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
let { win, tab } = await openTabAndWaitForRender();
|
||||
|
||||
await SpecialPowers.spawn(tab, [LOCALE], async function(locale) {
|
||||
const infoBody = content.document.getElementById("info-body");
|
||||
const promoLink = content.document.getElementById(
|
||||
"private-browsing-vpn-link"
|
||||
);
|
||||
|
||||
// Check experiment values are rendered
|
||||
is(
|
||||
infoBody.textContent,
|
||||
"You’re in a Private Window",
|
||||
"should render infoBody with fluent"
|
||||
);
|
||||
is(
|
||||
promoLink.textContent,
|
||||
"Stay private with Mozilla VPN",
|
||||
"should render promoLinkText with fluent"
|
||||
);
|
||||
is(
|
||||
content.document.querySelector(".info a").getAttribute("href"),
|
||||
"http://foo.example.com/" + locale,
|
||||
"should format the infoLinkUrl url"
|
||||
);
|
||||
is(
|
||||
content.document.querySelector(".promo a").getAttribute("href"),
|
||||
"http://bar.example.com/" + locale,
|
||||
"should format the promoLinkUrl url"
|
||||
);
|
||||
});
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[
|
||||
{
|
||||
method: "expose",
|
||||
extra: {
|
||||
featureId: "pbNewtab",
|
||||
},
|
||||
},
|
||||
],
|
||||
{ category: "normandy" }
|
||||
);
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
await doExperimentCleanup();
|
||||
});
|
||||
|
|
|
@ -325,10 +325,13 @@ p {
|
|||
|
||||
.promo {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.promo-visible {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.promo-content {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -452,3 +452,12 @@ spotlight:
|
|||
schema: >-
|
||||
"browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/Spotlight.schema.json"
|
||||
variables: {}
|
||||
pbNewtab:
|
||||
description: Message shown on the PB newtab for Messaging System
|
||||
hasExposure: true
|
||||
exposureDescription: >-
|
||||
Exposure is sent if the message is about to be shown after trigger and targeting conditions on the message matched.
|
||||
isEarlyStartup: false
|
||||
schema: >-
|
||||
browser/components/newtab/content-src/asrouter/templates/PBNewtab/NewtabPromoMessage.schema.json
|
||||
variables: {}
|
||||
|
|
Загрузка…
Ссылка в новой задаче