New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Splitting re-usable page-level experiment functionality out of google/ads/traffic-experiments.js #8374
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good, and I'm willing to approve as-is. But one suggestion (about migrating all experiments info to the new format) and one open question (about whether the page-level-experiments should move to src/, instead of ads/google/)
const experimentInfo = {}; | ||
experimentInfo[experimentName] = internalBranches; | ||
const experimentInfoMap = {}; | ||
experimentInfoMap[experimentName] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The format change is reasonable, but why not just migrate the existing experiment info descriptions to the new format, rather than copying them here at runtime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started doing that, but the logic on line 105 that decides whether or not A4A is enabled, needs to know whether the chosen experiment was the control or the experiment, so it's not completely trivial to change it to using anonymous branches. There's probably something we can do, but would rather tackle it in a separate PR request so this one doesn't get too far reaching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense and SGTM.
ads/google/page-level-experiments.js
Outdated
@@ -0,0 +1,133 @@ | |||
/** | |||
* Copyright 2016 The AMP HTML Authors. All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only question is whether this should continue to live in the ads/google hierarchy or just move to the src/ hierarchy? Perhaps @lannka has an opinion? (History: When I wrote the traffic-experiments.js code in the first place, we debated whether it was better to make it local to A4A or shared. At that time, it was decided to keep it local until there was a need to expand it. This is a clear need to expand, at least to Google scope. Do we foresee that it could be valuable to make this available to other clients as well, and so move to src/?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine it would be useful outside the google scope and nothing in page-level-experiments.js is specific to google (or even ads) now so happy to move if @lannka is happy with that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i was about to ask the same thing. feel free to move to src/experiments.js
also, in the context of src/experiments.js
, all the experiment is page-level, page
prefix is no longer needed in your method names.
@tlong2 this looks good. getExperimentBranch('experiment-a') {
...
} It will be configured at {
"experiment-a": {
"branch-1": 0.5,
"branch-2": 0.5,
}
} It will not have |
@lannka, the isTrafficEligible feature is important. The immediate use case for this is to test amp-auto-ads with traffic experiments. Since very few pubs will have the tag it will be necessary to limit the experiment to only pubs with the |
ads/google/page-level-experiments.js
Outdated
* @visibleForTesting | ||
*/ | ||
export function randomlySelectUnsetPageExperiments(win, experiments) { | ||
win.pageExperimentBranches = win.pageExperimentBranches || {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tdrl any reason why this was set on window object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's page-level, rather than element-level info, so I needed some page shared state to track. (Ensures that multiple slots on the same page don't reach different conclusions about their experiment status.) Is there a better place to store such shared state?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can just put a local var, as we did here
ads/google/page-level-experiments.js
Outdated
@@ -0,0 +1,133 @@ | |||
/** | |||
* Copyright 2016 The AMP HTML Authors. All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i was about to ask the same thing. feel free to move to src/experiments.js
also, in the context of src/experiments.js
, all the experiment is page-level, page
prefix is no longer needed in your method names.
ads/google/page-level-experiments.js
Outdated
continue; | ||
} | ||
|
||
if (!experiments[experimentName].isTrafficEligible(win)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better check the availability of isTrafficEligible
function before using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tlong2 this is very cool. thanks for making the change. Actually my next PR will be benefitted from your refactoring.
As commented in code, please move the logic into src/experiments.js
@lannka Have moved the logic to src/experiments.js and removed the page prefix. Also now checks that the isTrafficEligible function is definitely defined before calling it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay. (Was in paternity leave).
The refactoring looks great.
I'll let @tdrl do a final check to make sure it's not going to break the A4A experiments.
@tlong2 pls also resolve the conflicts |
@lannka Conflicts resolved |
seems @tdrl is OOO, @keithwrightbos can you take a look to make sure the new changes after @tdrl 's approval does not break any A4A experiment settings? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM though if there is no rush and we're concerned, we could wait for Terran to return from vacation (will be back Monday)
*/ | ||
export const PROFILING_BRANCHES = { | ||
a4aProfilingRate: { | ||
control: 'unused', | ||
experiment: 'unused', | ||
isTrafficEligible: () => { return true; }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be isTrafficEligible: () => true,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments about restructuring tests, but they're not critical. (Nice to have, if there's time, though.) Overall, LGTM.
const renderViaA4a = googleAdsIsA4AEnabled( | ||
sandbox.win, element, 'exp_name', externalBranches, internalBranches); | ||
expect(renderViaA4a).to.be.true; | ||
expect(element.getAttribute(EXPERIMENT_ATTRIBUTE)).to.equal('34,2088461'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to use traffic-experiments.js#IsExperimentOn
to check for eid 34
, rather than literal string match -- the other active experiments could change outside of your test control. And use expect(IsExperimentOn(12)).to.be.false
to ensure that unwanted experiments are not turned on. Finally, import traffic-experiments.js#EXTERNALLY_SELECTED_ID
and check for it via IsExperimentOn
rather than checking 2088461
directly. Might be simplest to roll all this into a helper function that does all these expectations and can be called from every test case. (Ditto for other eid tests below.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
experimentInfo[experimentName] = internalBranches; | ||
const experimentInfoMap = {}; | ||
experimentInfoMap[experimentName] = { | ||
isTrafficEligible: () => { return true; }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, like @keithwrightbos mentioned elsewhere, that this can just be isTrafficEligible: () => true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
const selectedBranch = getPageExperimentBranch(win, experimentName); | ||
addExperimentIdToElement(selectedBranch, element); | ||
const selectedBranch = getExperimentBranch(win, experimentName); | ||
if (selectedBranch) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could selectedBranch
ever fail to be truthy here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the exact current combinations of the internal branches, isTrafficEligible value, and behavior of all the various functions probably no. But since anyone of those things is liable to be changed by someone at some point, we should check that it is truthy here.
For testing amp-auto-ads for Google ad users we'd like to have page-level experiments that divert client-side.
This CL splits the generic page-level experiment selection logic out of google/ads/traffic-experiments.js, so that it can be re-used for other things.
Other details: