Skip to content

Commit

Permalink
🧪 Introduce shared auto-advance and CTA exp (#36674)
Browse files Browse the repository at this point in the history
* remove old CTA exp

* new exp setup

* one more branch

* update ids

* parseJson

* isArray

* fix test

* more tests

* one more test
  • Loading branch information
calebcordry authored Oct 30, 2021
1 parent 4ae2b92 commit 1cc0733
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import {
randomlySelectUnsetExperiments,
} from '#experiments';
import {StoryAdAutoAdvance} from '#experiments/story-ad-auto-advance';
import {StoryAdPageOutlink} from '#experiments/story-ad-page-outlink';
import {StoryAdPlacements} from '#experiments/story-ad-placements';
import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment';

Expand Down Expand Up @@ -247,14 +246,6 @@ export class AmpAdNetworkAdsenseImpl extends AmpA4A {
addExperimentIdToElement(storyAdPlacementsExpId, this.element);
}

const storyAdPageOutlinkExpId = getExperimentBranch(
this.win,
StoryAdPageOutlink.ID
);
if (storyAdPageOutlinkExpId) {
addExperimentIdToElement(storyAdPageOutlinkExpId, this.element);
}

const autoAdvanceExpBranch = getExperimentBranch(
this.win,
StoryAdAutoAdvance.ID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ import {
randomlySelectUnsetExperiments,
} from '#experiments';
import {StoryAdAutoAdvance} from '#experiments/story-ad-auto-advance';
import {StoryAdPageOutlink} from '#experiments/story-ad-page-outlink';
import {StoryAdPlacements} from '#experiments/story-ad-placements';
import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment';

Expand Down Expand Up @@ -499,14 +498,6 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
addExperimentIdToElement(storyAdPlacementsExpId, this.element);
}

const storyAdPageOutlinkExpId = getExperimentBranch(
this.win,
StoryAdPageOutlink.ID
);
if (storyAdPageOutlinkExpId) {
addExperimentIdToElement(storyAdPageOutlinkExpId, this.element);
}

const autoAdvanceExpBranch = getExperimentBranch(
this.win,
StoryAdAutoAdvance.ID
Expand Down
64 changes: 46 additions & 18 deletions extensions/amp-story-auto-ads/0.1/amp-story-auto-ads.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@ import {CommonSignals} from '#core/constants/common-signals';
import {toggleAttribute} from '#core/dom';
import {svgFor} from '#core/dom/static-template';
import {setStyle} from '#core/dom/style';
import {isArray} from '#core/types';
import {dict} from '#core/types/object';
import {tryParseJson} from '#core/types/object/json';

import {forceExperimentBranch, getExperimentBranch} from '#experiments';
import {
AdvanceExpToTime,
StoryAdAutoAdvance,
divertStoryAdAutoAdvance,
} from '#experiments/story-ad-auto-advance';
import {divertStoryAdPageOutlink} from '#experiments/story-ad-page-outlink';
import {divertStoryAdPlacements} from '#experiments/story-ad-placements';
import {
StoryAdSegmentExp,
ViewerSetTimeToBranch,
} from '#experiments/story-ad-progress-segment';
import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment';

import {Services} from '#service';

Expand Down Expand Up @@ -52,6 +50,20 @@ const AD_TAG = 'amp-ad';
/** @const {string} */
const MUSTACHE_TAG = 'amp-mustache';

/**
* Map of experiment IDs that might be enabled by the player to
* their experiment names. Used to toggle client side experiment on.
* @const {Object<string, string>}
*/
const RELEVANT_PLAYER_EXPS = {
[StoryAdSegmentExp.CONTROL]: StoryAdSegmentExp.ID,
[StoryAdSegmentExp.NO_ADVANCE_BOTH]: StoryAdSegmentExp.ID,
[StoryAdSegmentExp.NO_ADVANCE_AD]: StoryAdSegmentExp.ID,
[StoryAdSegmentExp.TEN_SECONDS]: StoryAdSegmentExp.ID,
[StoryAdSegmentExp.TWELVE_SECONDS]: StoryAdSegmentExp.ID,
[StoryAdSegmentExp.FOURTEEN_SECONDS]: StoryAdSegmentExp.ID,
};

/** @enum {string} */
export const Attributes = {
AD_SHOWING: 'ad-showing',
Expand Down Expand Up @@ -144,7 +156,6 @@ export class AmpStoryAutoAds extends AMP.BaseElement {
this.config_
);
divertStoryAdPlacements(this.win);
divertStoryAdPageOutlink(this.win);
divertStoryAdAutoAdvance(this.win);
this.placementAlgorithm_ = getPlacementAlgo(
this.win,
Expand All @@ -155,6 +166,7 @@ export class AmpStoryAutoAds extends AMP.BaseElement {
if (!this.placementAlgorithm_.isStoryEligible()) {
return;
}
this.askPlayerForActiveExperiments_();
this.analytics_ = getServicePromiseForDoc(
this.element,
STORY_AD_ANALYTICS
Expand All @@ -166,6 +178,30 @@ export class AmpStoryAutoAds extends AMP.BaseElement {
});
}

/**
* Sends message to player asking for active experiments and enables
* the branch for any relevant experiments.
*/
askPlayerForActiveExperiments_() {
const viewer = Services.viewerForDoc(this.doc_);
if (!viewer.isEmbedded()) {
return;
}
viewer./*OK*/ sendMessageAwaitResponse('playerExperiments').then((json) => {
if (json) {
const obj = tryParseJson(json);
const ids = obj['experimentIds'];
isArray(ids) &&
ids.forEach((id) => {
const relevantExp = RELEVANT_PLAYER_EXPS[id];
if (relevantExp) {
forceExperimentBranch(this.win, relevantExp, id);
}
});
}
});
}

/**
* Force an immediate ad placement without waiting for ad being loaded,
* and then navigate to the ad page.
Expand Down Expand Up @@ -417,23 +453,15 @@ export class AmpStoryAutoAds extends AMP.BaseElement {
this.win,
StoryAdAutoAdvance.ID
);
const storyNextUpParam = Services.viewerForDoc(this.element).getParam(
'storyNextUp'
);
if (storyNextUpParam && ViewerSetTimeToBranch[storyNextUpParam]) {
// Actual progress bar creation handled in progress-bar.js.
forceExperimentBranch(
this.win,
StoryAdSegmentExp.ID,
ViewerSetTimeToBranch[storyNextUpParam]
);
if (getExperimentBranch(this.win, StoryAdSegmentExp.ID)) {
// In the viewer controlled experiment progress bar is created by
// progress-bar.js
return;
} else if (
autoAdvanceExpBranch &&
autoAdvanceExpBranch !== StoryAdAutoAdvance.CONTROL
) {
this.createProgressBar_(AdvanceExpToTime[autoAdvanceExpBranch]);
} else if (storyNextUpParam) {
this.createProgressBar_(storyNextUpParam);
}
}

Expand Down
20 changes: 6 additions & 14 deletions extensions/amp-story-auto-ads/0.1/story-ad-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import {dict, map} from '#core/types/object';
import {parseJson} from '#core/types/object/json';

import {getExperimentBranch} from '#experiments';
import {
AdvanceExpToTime,
StoryAdAutoAdvance,
} from '#experiments/story-ad-auto-advance';
import {
BranchToTimeValues,
StoryAdSegmentExp,
Expand Down Expand Up @@ -310,22 +306,18 @@ export class StoryAdPage {
'id': this.id_,
});

const autoAdvanceExpBranch = getExperimentBranch(
this.win_,
StoryAdAutoAdvance.ID
);
const segmentExpBranch = getExperimentBranch(
this.win_,
StoryAdSegmentExp.ID
);

if (segmentExpBranch && segmentExpBranch !== StoryAdSegmentExp.CONTROL) {
attributes['auto-advance-after'] = BranchToTimeValues[segmentExpBranch];
} else if (
autoAdvanceExpBranch &&
autoAdvanceExpBranch !== StoryAdAutoAdvance.CONTROL
if (
segmentExpBranch &&
segmentExpBranch !== StoryAdSegmentExp.CONTROL &&
segmentExpBranch !== StoryAdSegmentExp.NO_ADVANCE_BOTH &&
segmentExpBranch !== StoryAdSegmentExp.NO_ADVANCE_AD
) {
attributes['auto-advance-after'] = AdvanceExpToTime[autoAdvanceExpBranch];
attributes['auto-advance-after'] = BranchToTimeValues[segmentExpBranch];
}

const page = createElementWithAttributes(
Expand Down
11 changes: 7 additions & 4 deletions extensions/amp-story-auto-ads/0.1/story-ad-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {createElementWithAttributes, iterateCursor} from '#core/dom';
import {dict, map} from '#core/types/object';

import {getExperimentBranch} from '#experiments';
import {StoryAdPageOutlink} from '#experiments/story-ad-page-outlink';
import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment';

import {dev, user} from '#utils/log';

Expand Down Expand Up @@ -303,12 +303,15 @@ export function createCta(doc, buttonFitter, container, uiMetadata) {
return null;
}

const autoAdvanceExpBranch = getExperimentBranch(
const storyAdSegmentBranch = getExperimentBranch(
doc.defaultView,
StoryAdPageOutlink.ID
StoryAdSegmentExp.ID
);

if (autoAdvanceExpBranch === StoryAdPageOutlink.EXPERIMENT) {
if (
storyAdSegmentBranch &&
storyAdSegmentBranch !== StoryAdSegmentExp.CONTROL
) {
return createPageOutlink_(doc, uiMetadata, container);
} else {
return createCtaLayer_(a, doc, container);
Expand Down
16 changes: 0 additions & 16 deletions extensions/amp-story-auto-ads/0.1/test/test-amp-story-auto-ads.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,22 +258,6 @@ describes.realWin(
});
});

// TODO(#33969) remove when launched.
it('should create progress bar from #storyNextUp', async () => {
env.sandbox.stub(viewer, 'getParam').returns('6s');
env.sandbox.stub(autoAds, 'mutateElement').callsArg(0);
addStoryAutoAdsConfig(adElement);
await story.buildCallback();
// Fire these events so that story ads thinks the parent story is ready.
story.signals().signal(CommonSignals.BUILT);
story.signals().signal(CommonSignals.INI_LOAD);
await autoAds.buildCallback();
await autoAds.layoutCallback();

const progressBar = doc.querySelector('.i-amphtml-story-ad-progress-bar');
expect(progressBar).to.exist;
});

describe('system layer', () => {
beforeEach(async () => {
// TODO(#33969) remove when launched.
Expand Down
14 changes: 0 additions & 14 deletions extensions/amp-story-auto-ads/0.1/test/test-story-ad-page.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import {CommonSignals} from '#core/constants/common-signals';

import {forceExperimentBranch} from '#experiments';
import {StoryAdAutoAdvance} from '#experiments/story-ad-auto-advance';

import {macroTask} from '#testing/helpers';

import {Gestures} from '../../../../src/gesture';
Expand Down Expand Up @@ -84,17 +81,6 @@ describes.realWin('story-ad-page', {amp: true}, (env) => {
const glassPane = glassPaneGridLayer.firstChild;
expect(glassPane).to.have.class('i-amphtml-glass-pane');
});

it('sets auto-advance if in the experiment', () => {
// TODO(#33969) remove when launched.
forceExperimentBranch(
win,
StoryAdAutoAdvance.ID,
StoryAdAutoAdvance.SIX_SECONDS
);
const pageElement = storyAdPage.build();
expect(pageElement).to.have.attribute('auto-advance-after');
});
});

describe('#getAdDoc', () => {
Expand Down
6 changes: 3 additions & 3 deletions extensions/amp-story-auto-ads/0.1/test/test-story-ad-ui.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {forceExperimentBranch} from '#experiments';
import {StoryAdPageOutlink} from '#experiments/story-ad-page-outlink';
import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment';

import {ButtonTextFitter} from '../story-ad-button-text-fitter';
import {
Expand Down Expand Up @@ -227,8 +227,8 @@ describes.realWin('story-ad-ui', {amp: true}, (env) => {
buttonFitter = new ButtonTextFitter(env.ampdoc);
forceExperimentBranch(
win,
StoryAdPageOutlink.ID,
StoryAdPageOutlink.EXPERIMENT
StoryAdSegmentExp.ID,
StoryAdSegmentExp.NO_ADVANCE_AD
);
});

Expand Down
7 changes: 6 additions & 1 deletion extensions/amp-story/1.0/progress-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,12 @@ export class ProgressBar {
this.win_,
StoryAdSegmentExp.ID
);
if (!segmentExpBranch || segmentExpBranch === StoryAdSegmentExp.CONTROL) {
if (
!segmentExpBranch ||
segmentExpBranch === StoryAdSegmentExp.CONTROL ||
segmentExpBranch === StoryAdSegmentExp.NO_ADVANCE_BOTH ||
segmentExpBranch === StoryAdSegmentExp.NO_ADVANCE_AD
) {
return;
}
// Set CSS signal that we are in the experiment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describes.realWin('amp-story-progress-bar', {amp: true}, (env) => {
forceExperimentBranch(
win,
StoryAdSegmentExp.ID,
StoryAdSegmentExp.EIGHT_SECONDS
StoryAdSegmentExp.TEN_SECONDS
);
expect(doc.querySelector('.i-amphtml-story-ad-progress-value')).not.to
.exist;
Expand Down
24 changes: 0 additions & 24 deletions src/experiments/story-ad-page-outlink.js

This file was deleted.

26 changes: 10 additions & 16 deletions src/experiments/story-ad-progress-segment.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
/** @const */
export const StoryAdSegmentExp = {
ID: 'story-ad-progress-segment',
CONTROL: '31061402',
SIX_SECONDS: '31061403',
EIGHT_SECONDS: '31061404',
TEN_SECONDS: '31061405',
CONTROL: '31063379', // No ad advance, no page advance, no new cta.
NO_ADVANCE_BOTH: '31063380', // No ad advance, no page advance, new cta.
NO_ADVANCE_AD: '31063381', // No ad advance, page=10s, new cta.
TEN_SECONDS: '31063382', // Advance ad with new cta for the rest, page=10s.
TWELVE_SECONDS: '31063383',
FOURTEEN_SECONDS: '31063384',
};

/** @const */
export const StoryAdSegmentTimes = {
SENTINEL: '999999ms',
SIX_SECONDS: '6000ms',
EIGHT_SECONDS: '8000ms',
TEN_SECONDS: '10000ms',
};

/** @const */
export const ViewerSetTimeToBranch = {
[StoryAdSegmentTimes.SIX_SECONDS]: StoryAdSegmentExp.SIX_SECONDS,
[StoryAdSegmentTimes.EIGHT_SECONDS]: StoryAdSegmentExp.EIGHT_SECONDS,
[StoryAdSegmentTimes.TEN_SECONDS]: StoryAdSegmentExp.TEN_SECONDS,
[StoryAdSegmentTimes.SENTINEL]: StoryAdSegmentExp.CONTROL,
TWELVE_SECONDS: '12000ms',
FOURTEEN_SECONDS: '14000ms',
};

/** @const */
export const BranchToTimeValues = {
[StoryAdSegmentExp.SIX_SECONDS]: StoryAdSegmentTimes.SIX_SECONDS,
[StoryAdSegmentExp.EIGHT_SECONDS]: StoryAdSegmentTimes.EIGHT_SECONDS,
[StoryAdSegmentExp.TEN_SECONDS]: StoryAdSegmentTimes.TEN_SECONDS,
[StoryAdSegmentExp.TWELVE_SECONDS]: StoryAdSegmentTimes.TWELVE_SECONDS,
[StoryAdSegmentExp.FOURTEEN_SECONDS]: StoryAdSegmentTimes.FOURTEEN_SECONDS,
};

0 comments on commit 1cc0733

Please sign in to comment.