diff --git a/data/experiment-recipe-samples/desktop-97-rollout.json b/data/experiment-recipe-samples/desktop-97-rollout.json new file mode 100644 index 00000000..1a35d4fb --- /dev/null +++ b/data/experiment-recipe-samples/desktop-97-rollout.json @@ -0,0 +1,48 @@ +{ + "appId": "firefox-desktop", + "appName": "firefox_desktop", + "application": "firefox-desktop", + "arguments": {}, + "isRollout": true, + "branches": [ + { + "feature": { + "enabled": true, + "featureId": "urlbar", + "value": { + "firefoxSuggestLabelsEnabled": true, + "quickSuggestEnabled": false, + "quickSuggestNonSponsoredIndex": -1, + "quickSuggestShouldShowOnboardingDialog": true, + "quickSuggestShowOnboardingDialogAfterNRestarts": 2, + "quickSuggestSponsoredIndex": -1 + } + }, + "ratio": 1, + "slug": "control" + } + ], + "bucketConfig": { + "count": 1700, + "namespace": "urlbar-21-rollout", + "randomizationUnit": "normandy_id", + "start": 7300, + "total": 10000 + }, + "channel": "release", + "endDate": null, + "featureIds": ["urlbar"], + "id": "desktop-rollout-firefox-suggest-history-rollout-3", + "isEnrollmentPaused": true, + "outcomes": [], + "probeSets": [], + "proposedDuration": 28, + "proposedEnrollment": 7, + "referenceBranch": "control", + "schemaVersion": "1.7.0", + "slug": "desktop-rollout-example-firefox-suggest-history-rollout-3", + "startDate": "2021-08-24", + "targeting": "browserSettings.update.channel == \"release\" && version|versionCompare('89.!') >= 0 && 'app.shield.optoutstudies.enabled'|preferenceValue && 'browser.urlbar.showSearchSuggestionsFirst'|preferenceValue && locale in ['en-CA', 'en-GB', 'en-US'] && region in ['US']", + "userFacingDescription": "a UX treatment of history suggestions from Firefox", + "userFacingName": "Desktop Rollout Example Firefox Suggest History Rollout 3" +} diff --git a/data/experiment-recipe-samples/mobile-android-rollout.json b/data/experiment-recipe-samples/mobile-android-rollout.json new file mode 100644 index 00000000..8e52fb4b --- /dev/null +++ b/data/experiment-recipe-samples/mobile-android-rollout.json @@ -0,0 +1,54 @@ +{ + "appId": "org.mozilla.firefox", + "appName": "fenix", + "application": "org.mozilla.firefox", + "arguments": {}, + "isRollout": true, + "branches": [ + { + "feature": { + "enabled": true, + "featureId": "homescreen", + "value": { + "sections-enabled": { + "jumpBackIn": true, + "pocket": true, + "recentExplorations": true, + "recentlySaved": true, + "topSites": true + } + } + }, + "ratio": 1, + "slug": "control" + } + ], + "bucketConfig": { + "count": 9000, + "namespace": "fenix-homescreen-release-2-rollout", + "randomizationUnit": "nimbus_id", + "start": 0, + "total": 10000 + }, + "channel": "release", + "endDate": null, + "featureIds": ["homescreen"], + "id": "mobile-rollout-example-all-users-home-screen-android-production", + "isEnrollmentPaused": false, + "outcomes": [ + { + "priority": "secondary", + "slug": "default-browser" + } + ], + "probeSets": [], + "proposedDuration": 45, + "proposedEnrollment": 28, + "referenceBranch": "control", + "schemaVersion": "1.7.0", + "slug": "mobile-rollout-example-all-users-home-screen-android-production", + "startDate": null, + "targeting": "true", + "userFacingDescription": "We want to understand the impact of the new Home screen on our users, to be measured by increased usage.", + "userFacingName": "Mobile Rollout Example All Users Home Screen Android Production" +} diff --git a/data/experiment-recipe-samples/mobile-ios-rollout.json b/data/experiment-recipe-samples/mobile-ios-rollout.json new file mode 100644 index 00000000..b710cb2c --- /dev/null +++ b/data/experiment-recipe-samples/mobile-ios-rollout.json @@ -0,0 +1,52 @@ +{ + "appId": "org.mozilla.ios.Firefox", + "appName": "firefox_ios", + "application": "org.mozilla.ios.Firefox", + "arguments": {}, + "isRollout": true, + "branches": [ + { + "feature": { + "enabled": true, + "featureId": "homescreen", + "value": { + "sections-enabled": { + "jumpBackIn": true, + "libraryShortcuts": false, + "recentlySaved": true + } + } + }, + "ratio": 1, + "slug": "control" + } + ], + "bucketConfig": { + "count": 6000, + "namespace": "ios-homescreen-release-2-rollout", + "randomizationUnit": "nimbus_id", + "start": 0, + "total": 10000 + }, + "channel": "release", + "endDate": null, + "featureIds": ["homescreen"], + "id": "mobile-rollout-example-all-users-homescreen-ios-production", + "isEnrollmentPaused": false, + "outcomes": [ + { + "priority": "secondary", + "slug": "default_browser" + } + ], + "probeSets": [], + "proposedDuration": 28, + "proposedEnrollment": 7, + "referenceBranch": "control", + "schemaVersion": "1.7.0", + "slug": "mobile-rollout-example-all-users-homescreen-ios-production", + "startDate": null, + "targeting": "true", + "userFacingDescription": "We want to understand the impact of the new Home screen on our users, to be measured by increased usage.", + "userFacingName": "Mobile Rollout Example All Users HomeScreen iOS Production" +} diff --git a/test/test-experiment-recipe-firefox.ts b/test/test-experiment-recipe-firefox.ts index 96e9d966..dc40f0cb 100644 --- a/test/test-experiment-recipe-firefox.ts +++ b/test/test-experiment-recipe-firefox.ts @@ -14,6 +14,14 @@ describe("experiment schemas", () => { assert.equal(result.ok, false, "validation should fail"); assert.propertyVal(result.errors[0], "message", 'should match format "date"'); }); + it("should fail on a non-boolean for a boolean", async () => { + const result = typeGuards.experiments_checkNimbusExperiment({ + ...TEST_EXPERIMENT, + isRollout: "foo", + }); + assert.equal(result.ok, false, "validation should fail"); + assert.propertyVal(result.errors[0], "message", "should be boolean"); + }); it("should fail on a non-integer value for a number", async () => { const result = typeGuards.experiments_checkNimbusExperiment({ ...TEST_EXPERIMENT, diff --git a/types/experiments.ts b/types/experiments.ts index 43b0db06..ece56ff4 100644 --- a/types/experiments.ts +++ b/types/experiments.ts @@ -47,6 +47,14 @@ export interface NimbusExperiment { */ isEnrollmentPaused: boolean; + /** + * When this property is set to true, treat this experiment as a rollout. + * Rollouts are currently handled as single-branch experiments separated + * from the bucketing namespace for normal experiments. + * See also: https://mozilla-hub.atlassian.net/browse/SDK-405 + */ + isRollout?: boolean; + /** Bucketing configuration */ bucketConfig: BucketConfig;