experiments.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import hash from 'string-hash';
  2. const experiments = {
  3. S9wqVl2SQ4ab2yZtqDI3Dw: {
  4. id: 'S9wqVl2SQ4ab2yZtqDI3Dw',
  5. run: function(variant, state, emitter) {
  6. switch (variant) {
  7. case 1:
  8. state.promo = 'blue';
  9. break;
  10. case 2:
  11. state.promo = 'pink';
  12. break;
  13. default:
  14. state.promo = 'grey';
  15. }
  16. emitter.emit('render');
  17. },
  18. eligible: function() {
  19. return (
  20. !/firefox|fxios/i.test(navigator.userAgent) &&
  21. document.querySelector('html').lang === 'en-US'
  22. );
  23. },
  24. variant: function(state) {
  25. const n = this.luckyNumber(state);
  26. if (n < 0.33) {
  27. return 0;
  28. }
  29. return n < 0.66 ? 1 : 2;
  30. },
  31. luckyNumber: function(state) {
  32. return luckyNumber(
  33. `${this.id}:${state.storage.get('testpilot_ga__cid')}`
  34. );
  35. }
  36. }
  37. };
  38. //Returns a number between 0 and 1
  39. // eslint-disable-next-line no-unused-vars
  40. function luckyNumber(str) {
  41. return hash(str) / 0xffffffff;
  42. }
  43. function checkExperiments(state, emitter) {
  44. const all = Object.keys(experiments);
  45. const id = all.find(id => experiments[id].eligible(state));
  46. if (id) {
  47. const variant = experiments[id].variant(state);
  48. state.storage.enroll(id, variant);
  49. experiments[id].run(variant, state, emitter);
  50. }
  51. }
  52. export default function initialize(state, emitter) {
  53. emitter.on('DOMContentLoaded', () => {
  54. const xp = experiments[state.query.x];
  55. if (xp) {
  56. xp.run(+state.query.v, state, emitter);
  57. }
  58. });
  59. if (!state.storage.get('testpilot_ga__cid')) {
  60. // first ever visit. check again after cid is assigned.
  61. emitter.on('DOMContentLoaded', () => {
  62. checkExperiments(state, emitter);
  63. });
  64. } else {
  65. const enrolled = state.storage.enrolled.filter(([id, variant]) => {
  66. const xp = experiments[id];
  67. if (xp) {
  68. xp.run(variant, state, emitter);
  69. }
  70. return !!xp;
  71. });
  72. // single experiment per session for now
  73. if (enrolled.length === 0) {
  74. checkExperiments(state, emitter);
  75. }
  76. }
  77. }