diff --git a/README.md b/README.md index 92ace75..5689ced 100755 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ export default { // Google optimize experiment id experimentID: '....', + // Experiment id evaluated from context, e.g. from runtime config + // experimentID: ({ $config }) => $config.experimentIDs.backgroundColor // [optional] specify number of sections for MVT experiments // sections: 1, @@ -234,4 +236,3 @@ import './styles.scss' ## License [MIT License](./LICENSE) - Alibaba Travels Co - diff --git a/lib/plugin.js b/lib/plugin.js index 0ff8eac..68ceb12 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -17,6 +17,7 @@ export default function (ctx, inject) { function assignExperiment(ctx) { let experimentIndex = -1 let experiment = {} + let experimentID = null let variantIndexes = [] let classes = [] @@ -26,7 +27,7 @@ function assignExperiment(ctx) { if (cookieExp && cookieVars) { // Try to find experiment with that id - experimentIndex = experiments.findIndex(exp => exp.experimentID === cookieExp) + experimentIndex = experiments.findIndex(exp => evaluateExperimentID(exp, ctx) === cookieExp) experiment = experiments[experimentIndex] // Variant indexes @@ -62,8 +63,10 @@ function assignExperiment(ctx) { variantIndexes.push(index) } + experimentID = evaluateExperimentID(experiment, ctx) + // Write exp cookie if changed - const expCookie = experiment.experimentID + '.' + variantIndexes.join('-') + const expCookie = experimentID + '.' + variantIndexes.join('-') if (cookie !== expCookie) { setCookie(ctx, 'exp', expCookie, experiment.maxAge) } @@ -82,7 +85,8 @@ function assignExperiment(ctx) { $variantIndexes: variantIndexes, $activeVariants: variantIndexes.map(index => experiment.variants[index]), $classes: classes, - ...experiment + ...experiment, + experimentID } } @@ -143,3 +147,11 @@ function skipAssignment(ctx) { return navigator.userAgent.match(<%= options.botExpression %>) } + +function evaluateExperimentID(experiment, ctx) { + if (typeof experiment.experimentID === 'function') { + return experiment.experimentID(ctx) + } else { + return experiment.experimentID + } +} diff --git a/test/fixture/experiments/index.js b/test/fixture/experiments/index.js index 753c18d..efff21a 100644 --- a/test/fixture/experiments/index.js +++ b/test/fixture/experiments/index.js @@ -1,9 +1,21 @@ -export default [{ - name: 'test1', - experimentID: 'id1', - variants: [ - { weight: 100 }, - { weight: 0 } - ], - maxAge: 120 -}] +export default [ + { + name: 'test1', + isEligible: ({ route }) => route.path === '/', + experimentID: 'id1', + variants: [ + { weight: 100 }, + { weight: 0 } + ], + maxAge: 120 + }, + { + name: 'test-evaluated-experimentID', + isEligible: ({ route }) => route.path === '/test-evaluated-experimentID', + experimentID: ({ route }) => route.query.id, + variants: [ + { weight: 100 }, + { weight: 0 } + ] + } +] diff --git a/test/module.test.js b/test/module.test.js index ce2e4ef..8db7f08 100644 --- a/test/module.test.js +++ b/test/module.test.js @@ -5,15 +5,20 @@ describe('defaults', () => { let nuxt, page, browser beforeAll(async () => { - browser = await puppeteer.launch() - page = await browser.newPage(); - ({ nuxt } = await setup(loadConfig(__dirname))) }, 60000) + beforeEach(async () => { + browser = await puppeteer.launch() + page = await browser.newPage() + }) + + afterEach(async () => { + await browser.close() + }) + afterAll(async () => { await nuxt.close() - await browser.close() }) test('variant-0', async () => { @@ -81,4 +86,13 @@ describe('defaults', () => { expect($exp.name).toBe('test1') }) } + + test('evaluated experiment ID', async () => { + await page.goto(url('/test-evaluated-experimentID?id=context-specific-experimentID')) + const $exp = await page.evaluate(() => window.$exp) + + expect($exp.$experimentIndex).toBe(1) + expect($exp.name).toBe('test-evaluated-experimentID') + expect($exp.experimentID).toBe('context-specific-experimentID') + }) })