Skip to content

Commit 573dd98

Browse files
authored
Move ShowExtensionSurveyPrompt experiment to ExP (#15693)
* Move ShowExtensionSurveyPrompt experiment to ExP * Allow opt-in/out of the new experiment * Use experiment name in test name
1 parent f214544 commit 573dd98

7 files changed

Lines changed: 24 additions & 51 deletions

File tree

experiments.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
11
[
2-
{
3-
"name": "ShowExtensionSurveyPrompt - enabled",
4-
"salt": "ShowExtensionSurveyPrompt",
5-
"max": 100,
6-
"min": 60
7-
},
8-
{
9-
"name": "ShowExtensionSurveyPrompt - control",
10-
"salt": "ShowExtensionSurveyPrompt",
11-
"min": 0,
12-
"max": 40
13-
},
142
{
153
"name": "CollectLSRequestTiming - experiment",
164
"salt": "CollectLSRequestTiming",

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,12 +1054,12 @@
10541054
"default": [],
10551055
"items": {
10561056
"enum": [
1057-
"ShowExtensionSurveyPrompt - enabled",
10581057
"DeprecatePythonPath - experiment",
10591058
"tryPylance",
10601059
"pythonTensorboardExperiment",
10611060
"pythonDiscoveryModule",
10621061
"pythonJediLSP",
1062+
"pythonSurveyNotification",
10631063
"All"
10641064
]
10651065
},
@@ -1071,12 +1071,12 @@
10711071
"default": [],
10721072
"items": {
10731073
"enum": [
1074-
"ShowExtensionSurveyPrompt - enabled",
10751074
"DeprecatePythonPath - experiment",
10761075
"tryPylance",
10771076
"pythonTensorboardExperiment",
10781077
"pythonDiscoveryModule",
10791078
"pythonJediLSP",
1079+
"pythonSurveyNotification",
10801080
"All"
10811081
]
10821082
},

src/client/activation/extensionSurvey.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { ShowExtensionSurveyPrompt } from '../common/experiments/groups';
1111
import '../common/extensions';
1212
import { traceDecorators } from '../common/logger';
1313
import { IPlatformService } from '../common/platform/types';
14-
import { IBrowserService, IExperimentsManager, IPersistentStateFactory, IRandom } from '../common/types';
14+
import { IBrowserService, IExperimentService, IPersistentStateFactory, IRandom } from '../common/types';
1515
import { Common, ExtensionSurveyBanner } from '../common/utils/localize';
1616
import { sendTelemetryEvent } from '../telemetry';
1717
import { EventName } from '../telemetry/constants';
@@ -33,16 +33,15 @@ export class ExtensionSurveyPrompt implements IExtensionSingleActivationService
3333
@inject(IBrowserService) private browserService: IBrowserService,
3434
@inject(IPersistentStateFactory) private persistentState: IPersistentStateFactory,
3535
@inject(IRandom) private random: IRandom,
36-
@inject(IExperimentsManager) private experiments: IExperimentsManager,
36+
@inject(IExperimentService) private experiments: IExperimentService,
3737
@inject(IApplicationEnvironment) private appEnvironment: IApplicationEnvironment,
3838
@inject(IPlatformService) private platformService: IPlatformService,
3939
@optional() private sampleSizePerOneHundredUsers: number = 10,
4040
@optional() private waitTimeToShowSurvey: number = WAIT_TIME_TO_SHOW_SURVEY,
4141
) {}
4242

4343
public async activate(): Promise<void> {
44-
if (!this.experiments.inExperiment(ShowExtensionSurveyPrompt.enabled)) {
45-
this.experiments.sendTelemetryIfInExperiment(ShowExtensionSurveyPrompt.control);
44+
if (!(await this.experiments.inExperiment(ShowExtensionSurveyPrompt.experiment))) {
4645
return;
4746
}
4847
const show = this.shouldShowBanner();

src/client/common/experiments/groups.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Experiment to check whether to show "Extension Survey prompt" or not.
22
export enum ShowExtensionSurveyPrompt {
3-
control = 'ShowExtensionSurveyPrompt - control',
4-
enabled = 'ShowExtensionSurveyPrompt - enabled',
3+
experiment = 'pythonSurveyNotification',
54
}
65

76
/*

src/client/common/experiments/manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const experimentStorageKey = 'EXPERIMENT_STORAGE_KEY';
3333
* as about 40% of the users never come back for the second session.
3434
*/
3535
const configFile = path.join(EXTENSION_ROOT_DIR, 'experiments.json');
36-
export const oldExperimentSalts = ['ShowExtensionSurveyPrompt', 'LS'];
36+
export const oldExperimentSalts = ['LS'];
3737

3838
/**
3939
* <DEPRECATED> Manages and stores experiments, implements the AB testing functionality

src/test/activation/extensionSurvey.unit.test.ts

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { PersistentStateFactory } from '../../client/common/persistentState';
1414
import { IPlatformService } from '../../client/common/platform/types';
1515
import {
1616
IBrowserService,
17-
IExperimentsManager,
17+
IExperimentService,
1818
IPersistentState,
1919
IPersistentStateFactory,
2020
IRandom,
@@ -29,14 +29,14 @@ suite('Extension survey prompt - shouldShowBanner()', () => {
2929
let browserService: TypeMoq.IMock<IBrowserService>;
3030
let random: TypeMoq.IMock<IRandom>;
3131
let persistentStateFactory: IPersistentStateFactory;
32-
let experiments: TypeMoq.IMock<IExperimentsManager>;
32+
let experiments: TypeMoq.IMock<IExperimentService>;
3333
let platformService: TypeMoq.IMock<IPlatformService>;
3434
let appEnvironment: TypeMoq.IMock<IApplicationEnvironment>;
3535
let disableSurveyForTime: TypeMoq.IMock<IPersistentState<any>>;
3636
let doNotShowAgain: TypeMoq.IMock<IPersistentState<any>>;
3737
let extensionSurveyPrompt: ExtensionSurveyPrompt;
3838
setup(() => {
39-
experiments = TypeMoq.Mock.ofType<IExperimentsManager>();
39+
experiments = TypeMoq.Mock.ofType<IExperimentService>();
4040
appShell = TypeMoq.Mock.ofType<IApplicationShell>();
4141
browserService = TypeMoq.Mock.ofType<IBrowserService>();
4242
random = TypeMoq.Mock.ofType<IRandom>();
@@ -176,7 +176,7 @@ suite('Extension survey prompt - shouldShowBanner()', () => {
176176
});
177177

178178
suite('Extension survey prompt - showSurvey()', () => {
179-
let experiments: TypeMoq.IMock<IExperimentsManager>;
179+
let experiments: TypeMoq.IMock<IExperimentService>;
180180
let appShell: TypeMoq.IMock<IApplicationShell>;
181181
let browserService: TypeMoq.IMock<IBrowserService>;
182182
let random: TypeMoq.IMock<IRandom>;
@@ -205,7 +205,7 @@ suite('Extension survey prompt - showSurvey()', () => {
205205
when(
206206
persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.doNotShowAgain, false),
207207
).thenReturn(doNotShowAgain.object);
208-
experiments = TypeMoq.Mock.ofType<IExperimentsManager>();
208+
experiments = TypeMoq.Mock.ofType<IExperimentService>();
209209
extensionSurveyPrompt = new ExtensionSurveyPrompt(
210210
appShell.object,
211211
browserService.object,
@@ -418,7 +418,7 @@ suite('Extension survey prompt - activate()', () => {
418418
let persistentStateFactory: IPersistentStateFactory;
419419
let shouldShowBanner: sinon.SinonStub<any>;
420420
let showSurvey: sinon.SinonStub<any>;
421-
let experiments: TypeMoq.IMock<IExperimentsManager>;
421+
let experiments: TypeMoq.IMock<IExperimentService>;
422422
let extensionSurveyPrompt: ExtensionSurveyPrompt;
423423
let platformService: TypeMoq.IMock<IPlatformService>;
424424
let appEnvironment: TypeMoq.IMock<IApplicationEnvironment>;
@@ -427,7 +427,7 @@ suite('Extension survey prompt - activate()', () => {
427427
browserService = TypeMoq.Mock.ofType<IBrowserService>();
428428
random = TypeMoq.Mock.ofType<IRandom>();
429429
persistentStateFactory = mock(PersistentStateFactory);
430-
experiments = TypeMoq.Mock.ofType<IExperimentsManager>();
430+
experiments = TypeMoq.Mock.ofType<IExperimentService>();
431431
platformService = TypeMoq.Mock.ofType<IPlatformService>();
432432
appEnvironment = TypeMoq.Mock.ofType<IApplicationEnvironment>();
433433
});
@@ -436,10 +436,9 @@ suite('Extension survey prompt - activate()', () => {
436436
sinon.restore();
437437
});
438438

439-
test("If user is not in 'ShowExtensionPrompt' experiment, send telemetry if in control group & return", async () => {
439+
test("If user is not in 'ShowExtensionSurveyPrompt' experiment, return immediately", async () => {
440440
shouldShowBanner = sinon.stub(ExtensionSurveyPrompt.prototype, 'shouldShowBanner');
441441
shouldShowBanner.callsFake(() => false);
442-
showSurvey = sinon.stub(ExtensionSurveyPrompt.prototype, 'showSurvey');
443442
extensionSurveyPrompt = new ExtensionSurveyPrompt(
444443
appShell.object,
445444
browserService.object,
@@ -451,19 +450,15 @@ suite('Extension survey prompt - activate()', () => {
451450
10,
452451
);
453452
experiments
454-
.setup((exp) => exp.inExperiment(ShowExtensionSurveyPrompt.enabled))
455-
.returns(() => false)
456-
.verifiable(TypeMoq.Times.once());
457-
experiments
458-
.setup((exp) => exp.sendTelemetryIfInExperiment(ShowExtensionSurveyPrompt.control))
459-
.returns(() => undefined)
453+
.setup((exp) => exp.inExperiment(ShowExtensionSurveyPrompt.experiment))
454+
.returns(() => Promise.resolve(false))
460455
.verifiable(TypeMoq.Times.once());
461456
await extensionSurveyPrompt.activate();
462457
assert.ok(shouldShowBanner.notCalled);
463458
experiments.verifyAll();
464459
});
465460

466-
test("No survey is shown if shouldShowBanner() returns false and user is in 'ShowExtensionPrompt' experiment", async () => {
461+
test("No survey is shown if shouldShowBanner() returns false and user is in 'ShowExtensionSurveyPrompt' experiment", async () => {
467462
const deferred = createDeferred<true>();
468463
shouldShowBanner = sinon.stub(ExtensionSurveyPrompt.prototype, 'shouldShowBanner');
469464
shouldShowBanner.callsFake(() => false);
@@ -485,13 +480,9 @@ suite('Extension survey prompt - activate()', () => {
485480
50,
486481
);
487482
experiments
488-
.setup((exp) => exp.inExperiment(ShowExtensionSurveyPrompt.enabled))
489-
.returns(() => true)
483+
.setup((exp) => exp.inExperiment(ShowExtensionSurveyPrompt.experiment))
484+
.returns(() => Promise.resolve(true))
490485
.verifiable(TypeMoq.Times.once());
491-
experiments
492-
.setup((exp) => exp.sendTelemetryIfInExperiment(TypeMoq.It.isAny()))
493-
.returns(() => undefined)
494-
.verifiable(TypeMoq.Times.never());
495486
await extensionSurveyPrompt.activate();
496487
assert.ok(shouldShowBanner.calledOnce);
497488

@@ -501,7 +492,7 @@ suite('Extension survey prompt - activate()', () => {
501492
experiments.verifyAll();
502493
});
503494

504-
test("Survey is shown after waitTimeToShowSurvey if shouldShowBanner() returns true and user is in 'ShowExtensionPrompt' experiment", async () => {
495+
test("Survey is shown after waitTimeToShowSurvey if shouldShowBanner() returns true and user is in 'ShowExtensionSurveyPrompt' experiment", async () => {
505496
const deferred = createDeferred<true>();
506497
shouldShowBanner = sinon.stub(ExtensionSurveyPrompt.prototype, 'shouldShowBanner');
507498
shouldShowBanner.callsFake(() => true);
@@ -523,13 +514,9 @@ suite('Extension survey prompt - activate()', () => {
523514
50,
524515
);
525516
experiments
526-
.setup((exp) => exp.inExperiment(ShowExtensionSurveyPrompt.enabled))
527-
.returns(() => true)
517+
.setup((exp) => exp.inExperiment(ShowExtensionSurveyPrompt.experiment))
518+
.returns(() => Promise.resolve(true))
528519
.verifiable(TypeMoq.Times.once());
529-
experiments
530-
.setup((exp) => exp.sendTelemetryIfInExperiment(TypeMoq.It.isAny()))
531-
.returns(() => undefined)
532-
.verifiable(TypeMoq.Times.never());
533520
await extensionSurveyPrompt.activate();
534521
assert.ok(shouldShowBanner.calledOnce);
535522

src/test/common/experiments/manager.unit.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ suite('A/B experiments', () => {
251251
verify(crypto.createHash(anything(), 'number', 'FNV')).once();
252252
});
253253
test('Use the expected list of old experiments', async () => {
254-
const expectedOldExperimentSalts = ['ShowExtensionSurveyPrompt', 'LS'];
254+
const expectedOldExperimentSalts = ['LS'];
255255
assert.deepEqual(expectedOldExperimentSalts, oldExperimentSalts);
256256
});
257257
});

0 commit comments

Comments
 (0)