govuk_frontend_toolkit 3.3.1 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/.gitignore +1 -1
- data/app/assets/CHANGELOG.md +5 -0
- data/app/assets/VERSION.txt +1 -1
- data/app/assets/docs/javascript.md +51 -5
- data/app/assets/javascripts/govuk/multivariate-test.js +26 -11
- data/app/assets/spec/unit/MultivariateTestSpec.js +38 -31
- data/app/assets/stylesheets/_colours.scss +1 -1
- metadata +4 -4
data/app/assets/.gitignore
CHANGED
data/app/assets/CHANGELOG.md
CHANGED
data/app/assets/VERSION.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.4.0
|
@@ -36,7 +36,6 @@ A simple content replacement test can be done by defining a set of cohorts with
|
|
36
36
|
var test = new GOVUK.MultivariateTest({
|
37
37
|
el: '.car-tax-button',
|
38
38
|
name: 'car_tax_button_text',
|
39
|
-
customVarIndex: 555,
|
40
39
|
cohorts: {
|
41
40
|
pay_your_car_tax: {html: "Pay Your Car Tax"},
|
42
41
|
give_us_money: {html: "Give Us Money Or We Will Crush Your Car"}
|
@@ -50,7 +49,6 @@ when a user is in each cohort:
|
|
50
49
|
```javascript
|
51
50
|
var test = new GOVUK.MultivariateTest({
|
52
51
|
name: 'car_tax_button_text',
|
53
|
-
customVarIndex: 555,
|
54
52
|
cohorts: {
|
55
53
|
pay_your_car_tax: {callback: function() { ... }},
|
56
54
|
give_us_money: {callback: function() { ... }}
|
@@ -64,7 +62,6 @@ that cohort:
|
|
64
62
|
```javascript
|
65
63
|
var test = new GOVUK.MultivariateTest({
|
66
64
|
name: 'car_tax_button_text',
|
67
|
-
customVarIndex: 555,
|
68
65
|
cohorts: {
|
69
66
|
pay_your_car_tax: {weight: 25, callback: function() { ... }}, // 25%
|
70
67
|
give_us_money: {weight: 75, callback: function() { ... }} // 75%
|
@@ -78,8 +75,7 @@ on the current object.
|
|
78
75
|
|
79
76
|
Takes these options:
|
80
77
|
- `el`: Element to run this test on (optional)
|
81
|
-
- `name`: The name of the text (alphanumeric and underscores)
|
82
|
-
- `customVarIndex`: The index of the custom variable in Google Analytics. GA only gives 50 integer slots to each account, and it is important that a unique integer is assigned to each test. Current contact for assigning a custom var slot for GOV.UK is: Ashraf Chohan <ashraf.chohan@digital.cabinet-office.gov.uk>
|
78
|
+
- `name`: The name of the text (alphanumeric and underscores), which will be part of the cookie.
|
83
79
|
- `defaultWeight`: Number of times each cohorts should appear in an array the random cohort is picked from, to be used in conjunction with weights on individual cohorts.
|
84
80
|
- `cohorts`: An object that maps cohort name to an object that defines the cohort. Name must be same format as test name. Object contains keys (all optional):
|
85
81
|
- `html`: HTML to fill element with when this cohort is picked.
|
@@ -88,6 +84,56 @@ Takes these options:
|
|
88
84
|
|
89
85
|
Full documentation on how to design multivariate tests, use the data in GA and construct hypothesis tests is on its way soon.
|
90
86
|
|
87
|
+
### Reporting to Google Content Experiments
|
88
|
+
The toolkit includes a library for multivariate testing that is capable of reporting data into [Google Content Experiments](https://developers.google.com/analytics/devguides/platform/experiments-overview).
|
89
|
+
|
90
|
+
#### To create a new experiment
|
91
|
+
|
92
|
+
1. Log in to Google Universal Analytics, select "UA - Preview environment".
|
93
|
+
2. In the left column, click on Behaviour, then Experiments and follow [these instructions](https://support.google.com/analytics/answer/1745152?hl=en-GB) to set up your experiment; you will need to have edit permissions on the Universal Analytics profile. If you cannot see a "Create experiment" button, this means you don't have these permissions; you can ask someone from the Performance Analyst team to set the experiment up for you.
|
94
|
+
3. In step number 2, in our case the address of the web pages will purely be used as descriptions in reports, so we recommend you pick the addresses accordingly, ie: "www.gov.uk" and "www.gov.uk/?=variation1".
|
95
|
+
4. In step number 3, "Setting up your experiment code", select "Manually insert the code" and make a note of the Experiment ID number located under the script window.
|
96
|
+
5. Add the below code to the page you want to test.
|
97
|
+
- the contentExperimentId is the Experiment ID you retrieved in step 3
|
98
|
+
- the variantId is 0 for the original variant, 1 for the first modified variant, 2 for the second modified variant, etc.
|
99
|
+
- see section above for other elements
|
100
|
+
This code requires analytics to be loaded in order to run; static is the app that would load the analytics by default, which automatically happens before experiments are run.
|
101
|
+
6. Check that it works: launch the app, open the page of your app, and check that there is a cookie with the name you had picked in your experiment. You can delete the cookie and refresh the page to check whether you can be assigned to another cohort.
|
102
|
+
|
103
|
+
```js
|
104
|
+
var test = new GOVUK.MultivariateTest({
|
105
|
+
name: 'car_tax_button_text',
|
106
|
+
contentExperimentId: "Your_Experiment_ID",
|
107
|
+
cohorts: {
|
108
|
+
pay_your_car_tax: {weight: 25, variantId: 0},
|
109
|
+
give_us_money: {weight: 25, variantId: 1}
|
110
|
+
}
|
111
|
+
});
|
112
|
+
|
113
|
+
```
|
114
|
+
|
115
|
+
### Using Google custom dimensions with your own statistical model
|
116
|
+
|
117
|
+
It is possible to use Google custom dimensions for determining the results of
|
118
|
+
the multivariate test (as an alternative to Google Content Experiments). This
|
119
|
+
may be appropriate if you wish to build the statistical model yourself or you
|
120
|
+
aren't able to use Content Experiments for some reason.
|
121
|
+
|
122
|
+
This requires setting the optional `customDimensionIndex` variable:
|
123
|
+
|
124
|
+
```js
|
125
|
+
var test = new GOVUK.MultivariateTest({
|
126
|
+
name: 'car_tax_button_text',
|
127
|
+
customDimensionIndex: 555,
|
128
|
+
cohorts: {
|
129
|
+
pay_your_car_tax: {weight: 25},
|
130
|
+
give_us_money: {weight: 50}
|
131
|
+
}
|
132
|
+
});
|
133
|
+
```
|
134
|
+
|
135
|
+
`customDimensionIndex` is the index of the custom variable in Google Analytics. GA only gives 50 integer slots to each account, and it is important that a unique integer is assigned to each test. Current contact for assigning a custom var slot for GOV.UK is: Ashraf Chohan <ashraf.chohan@digital.cabinet-office.gov.uk>
|
136
|
+
|
91
137
|
## Primary Links
|
92
138
|
|
93
139
|
`GOVUK.PrimaryList` hides elements in a list which don't have a supplied
|
@@ -12,10 +12,11 @@
|
|
12
12
|
function MultivariateTest(options) {
|
13
13
|
this.$el = $(options.el);
|
14
14
|
this._loadOption(options, 'name');
|
15
|
-
this._loadOption(options, '
|
15
|
+
this._loadOption(options, 'customDimensionIndex', null);
|
16
16
|
this._loadOption(options, 'cohorts');
|
17
17
|
this._loadOption(options, 'runImmediately', true);
|
18
18
|
this._loadOption(options, 'defaultWeight', 1);
|
19
|
+
this._loadOption(options, 'contentExperimentId', null);
|
19
20
|
|
20
21
|
if (this.runImmediately) {
|
21
22
|
this.run();
|
@@ -39,8 +40,10 @@
|
|
39
40
|
MultivariateTest.prototype.run = function() {
|
40
41
|
var cohort = this.getCohort();
|
41
42
|
if (cohort) {
|
43
|
+
this.setUpContentExperiment(cohort);
|
42
44
|
this.setCustomVar(cohort);
|
43
45
|
this.executeCohort(cohort);
|
46
|
+
this.createDummyEvent(cohort);
|
44
47
|
}
|
45
48
|
};
|
46
49
|
|
@@ -71,18 +74,30 @@
|
|
71
74
|
};
|
72
75
|
|
73
76
|
MultivariateTest.prototype.setCustomVar = function(cohort) {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
if (this.customDimensionIndex) {
|
78
|
+
GOVUK.analytics.setDimension(
|
79
|
+
this.customDimensionIndex,
|
80
|
+
this.cookieName(),
|
81
|
+
cohort,
|
82
|
+
2 // session level
|
83
|
+
);
|
84
|
+
}
|
85
|
+
};
|
86
|
+
|
87
|
+
MultivariateTest.prototype.setUpContentExperiment = function(cohort) {
|
88
|
+
var contentExperimentId = this.contentExperimentId;
|
89
|
+
var cohortVariantId = this.cohorts[cohort]['variantId'];
|
90
|
+
if(contentExperimentId && cohortVariantId && typeof window.ga === "function"){
|
91
|
+
window.ga('set', 'expId', contentExperimentId);
|
92
|
+
window.ga('set', 'expVar', cohortVariantId);
|
93
|
+
};
|
94
|
+
};
|
95
|
+
|
96
|
+
MultivariateTest.prototype.createDummyEvent = function(cohort) {
|
97
|
+
// Fire off a dummy event to set the custom var and the content experiment on the page.
|
83
98
|
// Ideally we'd be able to call setCustomVar before trackPageview,
|
84
99
|
// but would need reordering the existing GA code.
|
85
|
-
|
100
|
+
GOVUK.analytics.trackEvent(this.cookieName(), 'run', {nonInteraction:true});
|
86
101
|
};
|
87
102
|
|
88
103
|
MultivariateTest.prototype.weightedCohortNames = function() {
|
@@ -1,7 +1,9 @@
|
|
1
1
|
describe("MultivariateTest", function() {
|
2
2
|
beforeEach(function() {
|
3
3
|
GOVUK.cookie = jasmine.createSpy('GOVUK.cookie');
|
4
|
-
|
4
|
+
GOVUK.analytics = {setDimension:function(){}, trackEvent:function(){}};
|
5
|
+
spyOn(GOVUK.analytics, "setDimension");
|
6
|
+
spyOn(GOVUK.analytics, "trackEvent");
|
5
7
|
});
|
6
8
|
|
7
9
|
describe("#run", function() {
|
@@ -11,7 +13,6 @@ describe("MultivariateTest", function() {
|
|
11
13
|
var barSpy = jasmine.createSpy('barSpy');
|
12
14
|
var test = new GOVUK.MultivariateTest({
|
13
15
|
name: 'stuff',
|
14
|
-
customVarIndex: 1,
|
15
16
|
cohorts: {
|
16
17
|
foo: {callback: fooSpy},
|
17
18
|
bar: {callback: barSpy}
|
@@ -34,7 +35,6 @@ describe("MultivariateTest", function() {
|
|
34
35
|
var barSpy = jasmine.createSpy('barSpy');
|
35
36
|
var test = new GOVUK.MultivariateTest({
|
36
37
|
name: 'stuff',
|
37
|
-
customVarIndex: 1,
|
38
38
|
cohorts: {
|
39
39
|
foo: {callback: fooSpy},
|
40
40
|
bar: {callback: barSpy}
|
@@ -43,7 +43,7 @@ describe("MultivariateTest", function() {
|
|
43
43
|
expect(fooSpy).toHaveBeenCalled();
|
44
44
|
});
|
45
45
|
|
46
|
-
it("should set a custom var", function() {
|
46
|
+
it("should set a custom var if one is defined", function() {
|
47
47
|
GOVUK.cookie.and.returnValue('foo');
|
48
48
|
var test = new GOVUK.MultivariateTest({
|
49
49
|
name: 'stuff',
|
@@ -51,25 +51,19 @@ describe("MultivariateTest", function() {
|
|
51
51
|
foo: {},
|
52
52
|
bar: {}
|
53
53
|
},
|
54
|
-
|
54
|
+
customDimensionIndex: 2
|
55
55
|
});
|
56
|
-
expect(
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
'run',
|
68
|
-
'-',
|
69
|
-
0,
|
70
|
-
true
|
71
|
-
]
|
72
|
-
]);
|
56
|
+
expect(GOVUK.analytics.setDimension).toHaveBeenCalledWith(
|
57
|
+
2,
|
58
|
+
'multivariatetest_cohort_stuff',
|
59
|
+
'foo',
|
60
|
+
2
|
61
|
+
);
|
62
|
+
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
|
63
|
+
'multivariatetest_cohort_stuff',
|
64
|
+
'run',
|
65
|
+
{nonInteraction:true}
|
66
|
+
);
|
73
67
|
});
|
74
68
|
|
75
69
|
it("should set html for a cohort", function() {
|
@@ -77,7 +71,6 @@ describe("MultivariateTest", function() {
|
|
77
71
|
var $el = $('<div>');
|
78
72
|
var test = new GOVUK.MultivariateTest({
|
79
73
|
name: 'stuff',
|
80
|
-
customVarIndex: 1,
|
81
74
|
el: $el,
|
82
75
|
cohorts: {
|
83
76
|
foo: {html: "foo"},
|
@@ -94,7 +87,6 @@ describe("MultivariateTest", function() {
|
|
94
87
|
var $el = $('<div>');
|
95
88
|
var test = new GOVUK.MultivariateTest({
|
96
89
|
name: 'stuff',
|
97
|
-
customVarIndex: 1,
|
98
90
|
el: $el,
|
99
91
|
cohorts: {
|
100
92
|
foo: {callback: fooSpy},
|
@@ -108,7 +100,6 @@ describe("MultivariateTest", function() {
|
|
108
100
|
GOVUK.cookie.and.returnValue('foo');
|
109
101
|
var test = new GOVUK.MultivariateTest({
|
110
102
|
name: 'stuff',
|
111
|
-
customVarIndex: 1,
|
112
103
|
cohorts: {
|
113
104
|
foo: {callback: 'fooCallback'},
|
114
105
|
bar: {}
|
@@ -126,7 +117,6 @@ describe("MultivariateTest", function() {
|
|
126
117
|
GOVUK.cookie.and.returnValue('baz');
|
127
118
|
var test = new GOVUK.MultivariateTest({
|
128
119
|
name: 'stuff',
|
129
|
-
customVarIndex: 1,
|
130
120
|
cohorts: {
|
131
121
|
foo: {callback: fooSpy},
|
132
122
|
bar: {callback: barSpy}
|
@@ -145,7 +135,6 @@ describe("MultivariateTest", function() {
|
|
145
135
|
it("should return the weighted names of the cohorts when no weights are defined", function() {
|
146
136
|
var test = new GOVUK.MultivariateTest({
|
147
137
|
name: 'stuff',
|
148
|
-
customVarIndex: 1,
|
149
138
|
cohorts: {foo: {}, bar: {}, baz: {}}
|
150
139
|
});
|
151
140
|
expect(test.weightedCohortNames()).toEqual(['foo', 'bar', 'baz']);
|
@@ -154,7 +143,6 @@ describe("MultivariateTest", function() {
|
|
154
143
|
it("should return the weighted names of the cohorts when weights are defined", function() {
|
155
144
|
var test = new GOVUK.MultivariateTest({
|
156
145
|
name: 'stuff',
|
157
|
-
customVarIndex: 1,
|
158
146
|
cohorts: {foo: { weight: 2 }, bar: { weight: 1 }, baz: { weight: 3 }}
|
159
147
|
});
|
160
148
|
expect(test.weightedCohortNames()).toEqual(['foo', 'foo', 'bar', 'baz', 'baz', 'baz']);
|
@@ -163,7 +151,6 @@ describe("MultivariateTest", function() {
|
|
163
151
|
it("should return the weighted names of the cohorts using default weighting", function() {
|
164
152
|
var test = new GOVUK.MultivariateTest({
|
165
153
|
name: 'stuff',
|
166
|
-
customVarIndex: 1,
|
167
154
|
defaultWeight: 2,
|
168
155
|
cohorts: {foo: {}, bar: {}, baz: {}}
|
169
156
|
});
|
@@ -173,7 +160,6 @@ describe("MultivariateTest", function() {
|
|
173
160
|
it("should return the weighted names of the cohorts using default weighting or defined weighting", function() {
|
174
161
|
var test = new GOVUK.MultivariateTest({
|
175
162
|
name: 'stuff',
|
176
|
-
customVarIndex: 1,
|
177
163
|
defaultWeight: 2,
|
178
164
|
cohorts: {foo: {}, bar: { weight: 1 }, baz: {}}
|
179
165
|
});
|
@@ -185,10 +171,31 @@ describe("MultivariateTest", function() {
|
|
185
171
|
it("should choose a random cohort", function() {
|
186
172
|
var test = new GOVUK.MultivariateTest({
|
187
173
|
name: 'stuff',
|
188
|
-
customVarIndex: 1,
|
189
174
|
cohorts: {foo: {}, bar: {}}
|
190
175
|
});
|
191
176
|
expect(['foo', 'bar']).toContain(test.chooseRandomCohort());
|
192
177
|
})
|
193
178
|
});
|
179
|
+
|
180
|
+
describe("Google Content Experiment Integration", function() {
|
181
|
+
beforeEach(function() {
|
182
|
+
window.ga = function() {};
|
183
|
+
spyOn(window, 'ga');
|
184
|
+
});
|
185
|
+
|
186
|
+
it("should report the experiment data to Google", function() {
|
187
|
+
var test = new GOVUK.MultivariateTest({
|
188
|
+
name: 'stuff',
|
189
|
+
contentExperimentId: "asdfsadasdfa",
|
190
|
+
cohorts: {foo: {variantId: 0, weight: 0}, bar: {variantId: 1, weight: 1}}
|
191
|
+
});
|
192
|
+
expect(window.ga.calls.first().args).toEqual(['set', 'expId', 'asdfsadasdfa']);
|
193
|
+
expect(window.ga.calls.mostRecent().args).toEqual(['set', 'expVar', 1]);
|
194
|
+
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
|
195
|
+
'multivariatetest_cohort_stuff',
|
196
|
+
'run',
|
197
|
+
{nonInteraction:true}
|
198
|
+
);
|
199
|
+
});
|
200
|
+
});
|
194
201
|
});
|
@@ -105,5 +105,5 @@ $page-colour: $white; // The page
|
|
105
105
|
$alpha-colour: $pink; // Alpha badges and banners
|
106
106
|
$beta-colour: $orange; // Beta badges and banners
|
107
107
|
$banner-text-colour: #000; // Text colour for Alpha & Beta banners
|
108
|
-
$error-colour:
|
108
|
+
$error-colour: #af1324; // Error text and border colour
|
109
109
|
$error-background: #fef7f7; // Error background colour
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: govuk_frontend_toolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-04-
|
12
|
+
date: 2015-04-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -288,7 +288,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
288
288
|
version: '0'
|
289
289
|
segments:
|
290
290
|
- 0
|
291
|
-
hash:
|
291
|
+
hash: 3731870620465373503
|
292
292
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
293
293
|
none: false
|
294
294
|
requirements:
|
@@ -297,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
297
297
|
version: '0'
|
298
298
|
segments:
|
299
299
|
- 0
|
300
|
-
hash:
|
300
|
+
hash: 3731870620465373503
|
301
301
|
requirements: []
|
302
302
|
rubyforge_project:
|
303
303
|
rubygems_version: 1.8.23
|