UNPKG

react-ab-test

Version:

A/B testing React components and debug tools. Isomorphic with a simple, universal interface. Well documented and lightweight. Tested in popular browsers and Node.js. Includes helpers for Mixpanel and Segment.com.

138 lines (136 loc) 4.64 kB
import React from "react"; import ReactDOM from "react-dom"; import Experiment from "../../src/CoreExperiment.jsx"; import Variant from "../../src/Variant.jsx"; import emitter from "../../src/emitter.jsx"; import assert from "assert"; import co from "co"; import UUID from "node-uuid"; import ES6Promise from 'es6-promise'; ES6Promise.polyfill(); describe("Core Experiment", function() { let container; before(function(){ container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); after(function(){ document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); it("should render the correct variant.", co.wrap(function *(){ let experimentName = UUID.v4(); let App = React.createClass({ render: function(){ return <Experiment name={experimentName} value="A"> <Variant name="A"><div id="variant-a" /></Variant> <Variant name="B"><div id="variant-b" /></Variant> </Experiment>; } }); yield new Promise(function(resolve, reject){ ReactDOM.render(<App />, container, resolve); }); let elementA = document.getElementById('variant-a'); let elementB = document.getElementById('variant-b'); assert.notEqual(elementA, null); assert.equal(elementB, null); ReactDOM.unmountComponentAtNode(container); })); it("should error if invalid children exist.", co.wrap(function *(){ let experimentName = UUID.v4(); let App = React.createClass({ render: function(){ return <Experiment name={experimentName} value="A"> <Variant name="A"><div id="variant-a" /></Variant> <div /> </Experiment>; } }); try { yield new Promise(function(resolve, reject){ ReactDOM.render(<App />, container, resolve); }); } catch(error) { if(error.type !== "PUSHTELL_INVALID_CHILD") { throw error; } ReactDOM.unmountComponentAtNode(container); return; } throw new Error("Experiment has invalid children."); })); it("should update on componentWillReceiveProps.", co.wrap(function *(){ let experimentName = UUID.v4(); let setState; let getValueA = function(){ return "A"; } let getValueB = function() { return "B"; } let App = React.createClass({ getInitialState: function(){ return { value: getValueA } }, componentWillMount: function(){ setState = this.setState.bind(this); }, render: function(){ return <Experiment name={experimentName} value={this.state.value}> <Variant name="A"><div id="variant-a" /></Variant> <Variant name="B"><div id="variant-b" /></Variant> </Experiment>; } }); yield new Promise(function(resolve, reject){ ReactDOM.render(<App />, container, resolve); }); let elementA = document.getElementById('variant-a'); let elementB = document.getElementById('variant-b'); assert.notEqual(elementA, null); assert.equal(elementB, null); setState({ value: getValueB }); elementA = document.getElementById('variant-a'); elementB = document.getElementById('variant-b'); assert.equal(elementA, null); assert.notEqual(elementB, null); ReactDOM.unmountComponentAtNode(container); })); it("should update the children when props change.", co.wrap(function *(){ let experimentName = UUID.v4(); let SubComponent = React.createClass({ render(){ return ( <div id="variant-a"> <span id="variant-a-text">{this.props.text}</span> </div> ) } }); let App = React.createClass({ render: function(){ return <Experiment name={experimentName} value="A"> <Variant name="A"><SubComponent text={this.props.text}/></Variant> <Variant name="B"><div id="variant-b" /></Variant> </Experiment>; } }); yield new Promise(function(resolve, reject){ let component = ReactDOM.render(<App text='original text'/>,container, resolve); }); let elementAText = document.getElementById('variant-a-text'); assert.equal(elementAText.textContent, "original text"); yield new Promise(function(resolve, reject){ component = ReactDOM.render(<App text='New text'/>,container, resolve); }); elementAText = document.getElementById('variant-a-text'); assert.equal(elementAText.textContent, "New text"); ReactDOM.unmountComponentAtNode(container); })); });