govuk_frontend_toolkit 3.3.1 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|