Skip to content

Commit

Permalink
feat: add Multivariate Test
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit 210940d035f16a9d1dd136cb7744b9ef884897d8
Author: Hudo Assenco <hudo.assenco@gmail.com>
Date:   Tue Oct 13 15:56:01 2020 -0300

    docs: add @kelvinmaues as a contributor

commit 457c4fac8a99d469830abba0257c4427e6d854a3
Author: Hudo Assenco <hudo.assenco@gmail.com>
Date:   Tue Oct 13 15:53:19 2020 -0300

    build: remove unnecessary files

commit 0a0d5a1
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Mon Oct 12 12:18:15 2020 -0300

    Add lib to git ignore

commit 2f92156
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Mon Oct 12 12:08:35 2020 -0300

    Replace correct  markdown to image

commit 430fa3a
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Mon Oct 12 12:05:49 2020 -0300

    Add a new test to multivariate

commit 1587714
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Mon Oct 12 11:55:36 2020 -0300

    Add the documentation about the multivariante test and how to use it

commit 5bd2eb8
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Mon Oct 12 11:34:46 2020 -0300

    Add the feature to allow multivariate testing with variants

commit decae29
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Wed Sep 16 11:26:09 2020 -0300

    Removing prop types out of the component

commit 602d59d
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Wed Sep 16 10:46:12 2020 -0300

    New build improving the conditional

commit 64ade37
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Wed Sep 16 10:45:17 2020 -0300

    Conditional improved

commit 21aed44
Merge: 8b64802 114dbe2
Author: Kelvin Maues <kelvinmaus@gmail.com>
Date:   Wed Sep 16 10:37:42 2020 -0300

    Merge pull request #1 from kelvinmaues/feature/mvt-experiments

    Improved Experiment component with a new feature to mtv experiments, …

commit 114dbe2
Author: Kelvin Maues <kgmdeveloper@gmail.com>
Date:   Wed Sep 16 10:26:15 2020 -0300

    Improved Experiment component with a new feature to mtv experiments,
    new types added and script changed
  • Loading branch information
hudovisk committed Oct 13, 2020
1 parent fe650fc commit 3794bd6
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 33 deletions.
10 changes: 10 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
"contributions": [
"review"
]
},
{
"login": "kelvinmaues",
"name": "Kelvin Maues",
"avatar_url": "https://avatars0.githubusercontent.com/u/11196828?v=4",
"profile": "https://kelvinmaues.github.io/",
"contributions": [
"code",
"doc"
]
}
],
"contributorsPerLine": 7,
Expand Down
79 changes: 68 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# react-optimize

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)

[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

[![Build Status](https://github.com/hudovisk/react-optimize/workflows/Build/badge.svg)](https://github.com/hudovisk/react-optimize/actions) [![Greenkeeper badge](https://badges.greenkeeper.io/hudovisk/react-optimize.svg)](https://greenkeeper.io/)
Expand All @@ -21,8 +19,6 @@ Docs:
yarn add react-optimize
```

## How to use

You first need to add the gtag snippet with the optimize container id in it. If you are using [create-react-app](https://github.com/facebook/create-react-app)
you can add the following to `public/index.html`

Expand All @@ -44,7 +40,10 @@ REACT_APP_GA_ID=UA-xyz
REACT_APP_OPTIMIZE_ID=GTM-abc
```

After that you can use the lib like the following:
## How to use

#### A/B Test
If the experience is a **A/B testing** you can use the lib like the following:

```
import React from 'react';
Expand All @@ -69,6 +68,64 @@ class App extends React.Component {
}
```

#### Multivariate Test
If the experience is a **multivariate testing** to test variants with two or more different sections. You can use the lib like the following applying the props **asMtvExperiment (confirm that is multivariate)** and the **indexSectionPosition** on google optimize like the image below:

![google optimize multivariate test](./google-optimize-test.png)

```
import React from 'react';
import { Experiment, Variant } from "react-optimize";
class App extends React.Component {
render() {
return(
<Experiment
id="<experiment-id>"
asMtvExperiment
indexSectionPosition="0"
>
<Variant id="0">
Original
</Variant>
<Variant id="1">
Variant 1
</Variant>
</Experiment>
<Experiment
id="<experiment-id>"
asMtvExperiment
indexSectionPosition="1"
>
<Variant id="0">
Original
</Variant>
<Variant id="1">
Variant 1
</Variant>
<Variant id="2">
Variant 2
</Variant>
</Experiment>
<Experiment
id="<experiment-id>"
asMtvExperiment
indexSectionPosition="2"
>
<Variant id="0">
Original
</Variant>
<Variant id="1">
Variant 1
</Variant>
</Experiment>
)
}
}
```

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
Expand All @@ -78,15 +135,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://github.com/hudovisk"><img src="https://avatars2.githubusercontent.com/u/5161722?v=4" width="100px;" alt=""/><br /><sub><b>Hudo Assenco</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/commits?author=hudovisk" title="Code">💻</a> <a href="https://github.com/hudovisk/react-optimize/commits?author=hudovisk" title="Documentation">📖</a></td>
<td align="center"><a href="http://dobesv.com"><img src="https://avatars2.githubusercontent.com/u/327833?v=4" width="100px;" alt=""/><br /><sub><b>Dobes Vandermeer</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/commits?author=dobesv" title="Code">💻</a> <a href="https://github.com/hudovisk/react-optimize/commits?author=dobesv" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/tlaak"><img src="https://avatars0.githubusercontent.com/u/1674055?v=4" width="100px;" alt=""/><br /><sub><b>Timo Laak</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/pulls?q=is%3Apr+reviewed-by%3Atlaak" title="Reviewed Pull Requests">👀</a></td>
<td align="center"><a href="https://github.com/hudovisk"><img src="https://avatars2.githubusercontent.com/u/5161722?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hudo Assenco</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/commits?author=hudovisk" title="Code">💻</a> <a href="https://github.com/hudovisk/react-optimize/commits?author=hudovisk" title="Documentation">📖</a></td>
<td align="center"><a href="http://dobesv.com"><img src="https://avatars2.githubusercontent.com/u/327833?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dobes Vandermeer</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/commits?author=dobesv" title="Code">💻</a> <a href="https://github.com/hudovisk/react-optimize/commits?author=dobesv" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/tlaak"><img src="https://avatars0.githubusercontent.com/u/1674055?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Timo Laak</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/pulls?q=is%3Apr+reviewed-by%3Atlaak" title="Reviewed Pull Requests">👀</a></td>
<td align="center"><a href="https://kelvinmaues.github.io/"><img src="https://avatars0.githubusercontent.com/u/11196828?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kelvin Maues</b></sub></a><br /><a href="https://github.com/hudovisk/react-optimize/commits?author=kelvinmaues" title="Code">💻</a> <a href="https://github.com/hudovisk/react-optimize/commits?author=kelvinmaues" title="Documentation">📖</a></td>
</tr>
</table>

<!-- markdownlint-enable -->
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
Binary file added google-optimize-test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test:node": "mocha --require @babel/register test/test.node.js",
"test:browser": "cross-env NODE_ENV=test karma start",
"test": "yarn run test:node && yarn run test:browser && yarn run lint",
"build": "webpack",
"build": "rm -Rf lib && webpack",
"watch": "webpack --watch",
"prepublishOnly": "yarn run build"
},
Expand Down
44 changes: 30 additions & 14 deletions src/Experiment.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@ import PropTypes from "prop-types";
import OptimizeContext from "./OptimizeContext";

class Experiment extends React.Component {
static defaultProps = {
loader: null,
timeout: 3000,
};

static propTypes = {
id: PropTypes.string.isRequired,
loader: PropTypes.node,
timeout: PropTypes.number,
children: PropTypes.node,
};

state = {
variant: null,
};
Expand All @@ -32,12 +20,25 @@ class Experiment extends React.Component {
}
};

applyMtvExperiment = (value) => {
const sections = value.split("-");
const variant = sections[this.props.indexSectionPosition];
this.updateVariant(variant);
};

updateVariantFromGlobalState = () => {
const value =
const googleOptimizeExperimentValue =
typeof window !== "undefined" && window.google_optimize
? window.google_optimize.get(this.props.id)
: null;
this.updateVariant(value);
const isAMtvExperiment =
this.props.asMtvExperiment && googleOptimizeExperimentValue;

if (isAMtvExperiment) {
this.applyMtvExperiment(googleOptimizeExperimentValue);
} else {
this.updateVariant(googleOptimizeExperimentValue);
}
};

setupOptimizeCallback = () => {
Expand Down Expand Up @@ -99,4 +100,19 @@ class Experiment extends React.Component {
}
}

Experiment.propTypes = {
id: PropTypes.string.isRequired,
loader: PropTypes.node,
timeout: PropTypes.number,
children: PropTypes.node,
asMtvExperiment: PropTypes.bool,
indexSectionPosition: PropTypes.string,
};

Experiment.defaultProps = {
loader: null,
timeout: 3000,
asMtvExperiment: false,
};

export default Experiment;
10 changes: 5 additions & 5 deletions src/Variant.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import PropTypes from "prop-types";
import OptimizeContext from "./OptimizeContext";

class Variant extends React.Component {
static propTypes = {
id: PropTypes.string.isRequired,
children: PropTypes.node,
};

render() {
return (
<OptimizeContext.Consumer>
Expand All @@ -17,4 +12,9 @@ class Variant extends React.Component {
}
}

Variant.propTypes = {
id: PropTypes.string.isRequired,
children: PropTypes.node,
};

export default Variant;
6 changes: 4 additions & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
declare module 'react-optimize' {
import { ComponentType, ReactNode } from 'react';
declare module "react-optimize" {
import { ComponentType, ReactNode } from "react";
interface ExperimentProps {
children: ReactNode;
id: string;
loader?: ReactNode;
timeout?: number;
asMtvExperiment?: boolean;
indexSectionPosition?: string | number;
}

const Experiment: ComponentType<ExperimentProps>;
Expand Down
13 changes: 13 additions & 0 deletions test/specs/experiment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ describe("experiment", () => {

delete window.google_optimize;
});

it("should get multivariante test variants", () => {
window.google_optimize = { get: sinon.stub().returns("1-2-1") };

const wrapper = shallow(
<Experiment asMtvExperiment indexSectionPosition="0" id="abc" />
);

expect(window.google_optimize.get.calledWith("abc")).to.be.true;
expect(wrapper.state("variant")).to.be.equal("1");

delete window.google_optimize;
});
});

describe("on optimize not loaded yet", () => {
Expand Down

0 comments on commit 3794bd6

Please sign in to comment.