hof 23.0.2-vite-sourcemap-beta → 23.0.3
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.
- package/CHANGELOG.md +47 -1
- package/README.md +96 -5
- package/build/tasks/vite/index.js +6 -7
- package/build/tasks/vite/vite.config.js +1 -27
- package/components/amount-with-unit-select/fields.js +15 -0
- package/components/amount-with-unit-select/hooks.js +168 -0
- package/components/amount-with-unit-select/index.js +107 -0
- package/components/amount-with-unit-select/templates/amount-with-unit-select.html +20 -0
- package/components/amount-with-unit-select/utils.js +197 -0
- package/components/amount-with-unit-select/validation.js +175 -0
- package/components/index.js +1 -0
- package/controller/controller.js +5 -3
- package/controller/validation/index.js +1 -1
- package/controller/validation/validators.js +0 -1
- package/frontend/template-mixins/mixins/template-mixins.js +55 -5
- package/frontend/template-mixins/partials/forms/grouped-inputs-select.html +13 -0
- package/frontend/template-mixins/partials/forms/grouped-inputs-text.html +37 -0
- package/frontend/themes/gov-uk/styles/_grouped-input.scss +5 -0
- package/frontend/themes/gov-uk/styles/govuk.scss +1 -0
- package/frontend/toolkit/assets/javascript/form-focus.js +4 -0
- package/lib/sessions.js +18 -7
- package/package.json +9 -4
- package/sandbox/apps/sandbox/fields.js +18 -1
- package/sandbox/apps/sandbox/index.js +4 -0
- package/sandbox/apps/sandbox/sections/summary-data-sections.js +7 -1
- package/sandbox/apps/sandbox/translations/src/en/fields.json +10 -0
- package/sandbox/apps/sandbox/translations/src/en/pages.json +3 -0
- package/sandbox/apps/sandbox/translations/src/en/validation.json +12 -0
- package/sandbox/server.js +0 -8
- package/utilities/autofill/index.js +169 -145
- package/frontend/govuk-template/govuk_template_generated.html +0 -118
- package/sandbox/apps/sandbox/translations/en/default.json +0 -245
- package/sandbox/public/css/app.css +0 -11708
- package/sandbox/public/css/app.css.map +0 -1
- package/sandbox/public/images/govuk-logo.svg +0 -25
- package/sandbox/public/images/icons/icon-caret-left.png +0 -0
- package/sandbox/public/images/icons/icon-complete.png +0 -0
- package/sandbox/public/images/icons/icon-cross-remove-sign.png +0 -0
- package/sandbox/public/js/bundle.js +0 -60
- package/sandbox/public/js/bundle.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hof",
|
|
3
3
|
"description": "A bootstrap for HOF projects",
|
|
4
|
-
"version": "23.0.
|
|
4
|
+
"version": "23.0.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"author": "HomeOffice",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"dialog-polyfill": "^0.5.6",
|
|
53
53
|
"dotenv": "^4.0.0",
|
|
54
54
|
"duplexify": "^3.7.1",
|
|
55
|
+
"exorcist": "^2.0.0",
|
|
55
56
|
"express": "^4.21.2",
|
|
56
57
|
"express-healthcheck": "^0.1.0",
|
|
57
58
|
"express-partial-templates": "^0.2.1",
|
|
@@ -97,7 +98,7 @@
|
|
|
97
98
|
"devDependencies": {
|
|
98
99
|
"@cucumber/cucumber": "^7.3.2",
|
|
99
100
|
"@cucumber/pretty-formatter": "^1.0.1",
|
|
100
|
-
"@types/jest": "^
|
|
101
|
+
"@types/jest": "^30.0.0",
|
|
101
102
|
"@vitest/coverage-v8": "^4.0.8",
|
|
102
103
|
"@xmldom/xmldom": "~0.8.11",
|
|
103
104
|
"chai": "^3.5.0",
|
|
@@ -110,7 +111,8 @@
|
|
|
110
111
|
"funkie": "0.0.5",
|
|
111
112
|
"funkie-phantom": "0.0.1",
|
|
112
113
|
"istanbul": "^0.4.5",
|
|
113
|
-
"jest": "^
|
|
114
|
+
"jest": "^30.2.0",
|
|
115
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
114
116
|
"jquery": "^3.7.1",
|
|
115
117
|
"mocha": "^8.4.0",
|
|
116
118
|
"mocha-sandbox": "^1.0.0",
|
|
@@ -127,7 +129,10 @@
|
|
|
127
129
|
"travis-conditions": "0.0.0",
|
|
128
130
|
"vitest": "^4.0.8",
|
|
129
131
|
"watchify": "^4.0.0",
|
|
130
|
-
"webdriverio": "^
|
|
132
|
+
"webdriverio": "^5.0.0"
|
|
133
|
+
},
|
|
134
|
+
"jest": {
|
|
135
|
+
"testEnvironment": "jsdom"
|
|
131
136
|
},
|
|
132
137
|
"mocha": {
|
|
133
138
|
"reporter": "spec",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
const dateComponent = require('../../../').components.date;
|
|
5
5
|
const staticAppealStages = require('./lib/staticAppealStages');
|
|
6
|
+
const amountWithUnitSelectComponent = require('../../../').components.amountWithUnitSelect;
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
'landing-page-radio': {
|
|
@@ -124,5 +125,21 @@ module.exports = {
|
|
|
124
125
|
value: '',
|
|
125
126
|
label: 'fields.appealStages.options.null'
|
|
126
127
|
}].concat(staticAppealStages.getstaticAppealStages())
|
|
127
|
-
}
|
|
128
|
+
},
|
|
129
|
+
'amountWithUnitSelect' : amountWithUnitSelectComponent('amountWithUnitSelect', {
|
|
130
|
+
mixin: 'input-amount-with-unit-select',
|
|
131
|
+
amountLabel: "Amount-",
|
|
132
|
+
unitLabel: "Unit-",
|
|
133
|
+
options: [
|
|
134
|
+
{ "null": "Select" },
|
|
135
|
+
{ "label": "non trans option 1", "value": "1" },
|
|
136
|
+
{ "label": "non trans option 2", "value": "2" }
|
|
137
|
+
],
|
|
138
|
+
hint: "E.G: 5 Kilogram",
|
|
139
|
+
legend: 'Enter An Amount',
|
|
140
|
+
isPageHeading: 'true',
|
|
141
|
+
unitOptional: 'false',
|
|
142
|
+
amountOptional: 'true',
|
|
143
|
+
validate: ['alphanum']
|
|
144
|
+
})
|
|
128
145
|
}
|
|
@@ -39,5 +39,11 @@ module.exports = {
|
|
|
39
39
|
],
|
|
40
40
|
whatHappened: [
|
|
41
41
|
'whatHappened'
|
|
42
|
-
]
|
|
42
|
+
],
|
|
43
|
+
amountWithUnitSelect:
|
|
44
|
+
[{
|
|
45
|
+
field: 'amountWithUnitSelect',
|
|
46
|
+
parse: val => val ?
|
|
47
|
+
(val.substring(0, val.lastIndexOf('-')) || '0') + ' ' + val.substring(val.lastIndexOf('-') + 1) : ''
|
|
48
|
+
}]
|
|
43
49
|
};
|
|
@@ -97,5 +97,15 @@
|
|
|
97
97
|
"options": {
|
|
98
98
|
"null": "Select..."
|
|
99
99
|
}
|
|
100
|
+
},
|
|
101
|
+
"amountWithUnitSelect": {
|
|
102
|
+
"label": "Amount",
|
|
103
|
+
"amountLabel": "Amount:",
|
|
104
|
+
"unitLabel": "Unit:",
|
|
105
|
+
"options": [
|
|
106
|
+
{ "null": "Select..." },
|
|
107
|
+
{ "label": "Litres", "value": "L" },
|
|
108
|
+
{ "label": "Kilograms", "value": "KG" }
|
|
109
|
+
]
|
|
100
110
|
}
|
|
101
111
|
}
|
|
@@ -50,5 +50,17 @@
|
|
|
50
50
|
},
|
|
51
51
|
"appealStages": {
|
|
52
52
|
"required": "Select an appeal stage from the list"
|
|
53
|
+
},
|
|
54
|
+
"amountWithUnitSelect": {
|
|
55
|
+
"default": "Enter the amount in the correct format; for example, 10 Litres",
|
|
56
|
+
"alphanum": "The amount must not contain any special characters",
|
|
57
|
+
"required": "Enter an amount and a unit value"
|
|
58
|
+
},
|
|
59
|
+
"amountWithUnitSelect-unit": {
|
|
60
|
+
"default": "A valid value must be selected as the amount unit",
|
|
61
|
+
"required": "A unit must be selected for the amount"
|
|
62
|
+
},
|
|
63
|
+
"amountWithUnitSelect-amount": {
|
|
64
|
+
"required": "An amount must be selected with the unit"
|
|
53
65
|
}
|
|
54
66
|
}
|
package/sandbox/server.js
CHANGED
|
@@ -3,187 +3,211 @@
|
|
|
3
3
|
|
|
4
4
|
const url = require('url');
|
|
5
5
|
const Inputs = require('./inputs');
|
|
6
|
-
const Promise = require('bluebird');
|
|
7
6
|
|
|
8
7
|
const debug = require('debug')('hof:util:autofill');
|
|
9
8
|
|
|
10
9
|
const MAX_LOOPS = 3;
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
function getRemoteFilePath(uploadResult) {
|
|
12
|
+
if (uploadResult && typeof uploadResult === 'object' && uploadResult.value) {
|
|
13
|
+
return uploadResult.value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return uploadResult;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = browser => async (target, input, opts) => {
|
|
13
20
|
const options = opts || {};
|
|
14
21
|
options.maxLoops = options.maxLoops || MAX_LOOPS;
|
|
15
|
-
|
|
16
22
|
const getValue = Inputs(input);
|
|
17
|
-
|
|
18
23
|
let last;
|
|
19
24
|
let count = 0;
|
|
20
25
|
|
|
21
|
-
function completeTextField(element, name) {
|
|
26
|
+
async function completeTextField(element, name) {
|
|
22
27
|
const value = getValue(name, 'text');
|
|
23
28
|
debug(`Filling field: ${name} with value: ${value}`);
|
|
24
|
-
|
|
25
|
-
.
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
try {
|
|
30
|
+
await element.clearValue();
|
|
31
|
+
await element.setValue(value);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
// any error here is *probably* because the field is hidden
|
|
34
|
+
// ignore and hope for the best
|
|
35
|
+
}
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
function completeFileField(element, name) {
|
|
38
|
+
async function completeFileField(element, name) {
|
|
34
39
|
const value = getValue(name, 'file');
|
|
35
40
|
if (value) {
|
|
36
41
|
debug(`Uploading file: ${value}`);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
42
|
+
const remotePath = getRemoteFilePath(await browser.uploadFile(value));
|
|
43
|
+
debug(`Uploaded file: ${value} - remote path ${remotePath}`);
|
|
44
|
+
await element.setValue(remotePath);
|
|
45
|
+
} else {
|
|
46
|
+
debug(`No file specified for input ${name} - ignoring`);
|
|
43
47
|
}
|
|
44
|
-
debug(`No file specified for input ${name} - ignoring`);
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
function
|
|
50
|
+
async function completeRadioGroup(name) {
|
|
48
51
|
const value = getValue(name, 'radio');
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return browser.elementIdClick(radios.value[index].ELEMENT);
|
|
55
|
-
});
|
|
52
|
+
const radios = await browser.$$(`input[type="radio"][name="${name}"]`);
|
|
53
|
+
|
|
54
|
+
if (!radios.length) {
|
|
55
|
+
debug(`No radio inputs found for ${name}`);
|
|
56
|
+
return;
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
|
|
59
|
+
if (!value) {
|
|
60
|
+
debug(`Checking random radio: ${name}`);
|
|
61
|
+
const index = Math.floor(Math.random() * radios.length);
|
|
62
|
+
if (!await radios[index].isSelected()) {
|
|
63
|
+
await radios[index].click();
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
for (const radio of radios) {
|
|
67
|
+
const val = await radio.getAttribute('value');
|
|
68
|
+
if (val === value) {
|
|
69
|
+
debug(`Checking radio: ${name} with value: ${val}`);
|
|
70
|
+
if (!await radio.isSelected()) {
|
|
71
|
+
await radio.click();
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
62
74
|
}
|
|
63
|
-
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
debug(`Ignoring radio group: ${name} - no option matches ${value}`);
|
|
78
|
+
}
|
|
64
79
|
}
|
|
65
80
|
|
|
66
|
-
function completeCheckbox(element, name) {
|
|
81
|
+
async function completeCheckbox(element, name) {
|
|
67
82
|
const value = getValue(name, 'checkbox');
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
debug(`Ignoring checkbox: ${name} with value: ${val.value} - looking for ${value}`);
|
|
90
|
-
}));
|
|
83
|
+
const val = await element.getAttribute('value');
|
|
84
|
+
const checked = await element.isSelected();
|
|
85
|
+
if (value === null) {
|
|
86
|
+
if (!checked) {
|
|
87
|
+
debug(`Leaving checkbox: ${name} blank`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
debug(`Unchecking checkbox: ${name}`);
|
|
91
|
+
await element.click();
|
|
92
|
+
} else if (!value && !checked) {
|
|
93
|
+
debug(`Checking checkbox: ${name} with value: ${val}`);
|
|
94
|
+
await element.click();
|
|
95
|
+
} else if (value && value.indexOf(val) > -1 && !checked) {
|
|
96
|
+
debug(`Checking checkbox: ${name} with value: ${val}`);
|
|
97
|
+
await element.click();
|
|
98
|
+
} else if (value && value.indexOf(val) === -1 && checked) {
|
|
99
|
+
debug(`Unchecking checkbox: ${name} with value: ${val}`);
|
|
100
|
+
await element.click();
|
|
101
|
+
} else {
|
|
102
|
+
debug(`Ignoring checkbox: ${name} with value: ${val} - looking for ${value}`);
|
|
103
|
+
}
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
function completeSelectElement(element, name) {
|
|
106
|
+
async function completeSelectElement(element, name) {
|
|
94
107
|
const value = getValue(name, 'select');
|
|
95
108
|
if (!value) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
109
|
+
const selectOptions = await element.$$('option');
|
|
110
|
+
if (selectOptions.length > 1) {
|
|
111
|
+
const index = 1 + Math.floor(Math.random() * (selectOptions.length - 1));
|
|
112
|
+
debug(`Selecting option: ${index} from select box: ${name}`);
|
|
113
|
+
await element.selectByIndex(index);
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
debug(`Selecting options: ${value} from select box: ${name}`);
|
|
117
|
+
await element.selectByAttribute('value', value);
|
|
102
118
|
}
|
|
103
|
-
debug(`Selecting options: ${value} from select box: ${name}`);
|
|
104
|
-
return browser.selectByValue(`select[name="${name}"]`, value);
|
|
105
119
|
}
|
|
106
120
|
|
|
107
|
-
function completeStep(path) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return completeFileField(field.ELEMENT, name.value);
|
|
121
|
-
} else if (type.value === 'text') {
|
|
122
|
-
return completeTextField(field.ELEMENT, name.value);
|
|
123
|
-
}
|
|
124
|
-
debug(`Ignoring field of type ${type.value}`);
|
|
125
|
-
})), {concurrency: 1});
|
|
126
|
-
})
|
|
127
|
-
.elements('select')
|
|
128
|
-
.then(fields => {
|
|
129
|
-
debug(`Found ${fields.value.length} <select> elements`);
|
|
130
|
-
return Promise.map(fields.value, field => browser.elementIdAttribute(field.ELEMENT, 'name')
|
|
131
|
-
.then(name => completeSelectElement(field.ELEMENT, name.value)));
|
|
132
|
-
})
|
|
133
|
-
.elements('textarea')
|
|
134
|
-
.then(fields => {
|
|
135
|
-
debug(`Found ${fields.value.length} <textarea> elements`);
|
|
136
|
-
return Promise.map(fields.value, field => browser.elementIdAttribute(field.ELEMENT, 'name')
|
|
137
|
-
.then(name => completeTextField(field.ELEMENT, name.value)));
|
|
138
|
-
})
|
|
139
|
-
.then(() => {
|
|
140
|
-
if (options.screenshots) {
|
|
141
|
-
const screenshot = require('path').resolve(options.screenshots, 'hof-autofill.pre-submit.png');
|
|
142
|
-
return browser.saveScreenshot(screenshot);
|
|
121
|
+
async function completeStep(path) {
|
|
122
|
+
const completedRadioGroups = new Set();
|
|
123
|
+
|
|
124
|
+
// Fill inputs
|
|
125
|
+
const inputs = await browser.$$('input');
|
|
126
|
+
debug(`Found ${inputs.length} <input> elements`);
|
|
127
|
+
for (const element of inputs) {
|
|
128
|
+
const type = await element.getAttribute('type');
|
|
129
|
+
const name = await element.getAttribute('name');
|
|
130
|
+
if (type === 'radio') {
|
|
131
|
+
if (!completedRadioGroups.has(name)) {
|
|
132
|
+
completedRadioGroups.add(name);
|
|
133
|
+
await completeRadioGroup(name);
|
|
143
134
|
}
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
135
|
+
} else if (type === 'checkbox') {
|
|
136
|
+
await completeCheckbox(element, name);
|
|
137
|
+
} else if (type === 'file') {
|
|
138
|
+
await completeFileField(element, name);
|
|
139
|
+
} else if (type === 'text') {
|
|
140
|
+
await completeTextField(element, name);
|
|
141
|
+
} else {
|
|
142
|
+
debug(`Ignoring field of type ${type}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Fill selects
|
|
147
|
+
const selects = await browser.$$('select');
|
|
148
|
+
debug(`Found ${selects.length} <select> elements`);
|
|
149
|
+
for (const element of selects) {
|
|
150
|
+
const name = await element.getAttribute('name');
|
|
151
|
+
await completeSelectElement(element, name);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Fill textareas
|
|
155
|
+
const textareas = await browser.$$('textarea');
|
|
156
|
+
debug(`Found ${textareas.length} <textarea> elements`);
|
|
157
|
+
for (const element of textareas) {
|
|
158
|
+
const name = await element.getAttribute('name');
|
|
159
|
+
await completeTextField(element, name);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (options.screenshots) {
|
|
163
|
+
const screenshot = path.resolve(options.screenshots, 'hof-autofill.pre-submit.png');
|
|
164
|
+
await browser.saveScreenshot(screenshot);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
debug('Submitting form');
|
|
168
|
+
const submitBtn = await browser.$('input[type="submit"], button[type="submit"]');
|
|
169
|
+
if (!await submitBtn.isExisting()) {
|
|
170
|
+
throw new Error('No submit control found on page');
|
|
171
|
+
}
|
|
172
|
+
await submitBtn.click();
|
|
173
|
+
|
|
174
|
+
const p = await browser.getUrl();
|
|
175
|
+
const u = url.parse(p);
|
|
176
|
+
debug(`New page is: ${u.path}`);
|
|
177
|
+
if (u.path !== path) {
|
|
178
|
+
debug(`Checking current path ${u.path} against last path ${last}`);
|
|
179
|
+
if (last === u.path) {
|
|
180
|
+
count++;
|
|
181
|
+
debug(`Stuck on path ${u.path} for ${count} iterations`);
|
|
182
|
+
if (count === options.maxLoops) {
|
|
183
|
+
if (options.screenshots) {
|
|
184
|
+
const screenshot = path.resolve(options.screenshots, 'hof-autofill.debug.png');
|
|
185
|
+
await browser.saveScreenshot(screenshot);
|
|
186
|
+
throw new Error(`Progress stuck at ${u.path} - screenshot saved to ${screenshot}`);
|
|
173
187
|
}
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.then(() => {
|
|
184
|
-
throw e;
|
|
185
|
-
}));
|
|
188
|
+
throw new Error(`Progress stuck at ${u.path}`);
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
count = 0;
|
|
192
|
+
}
|
|
193
|
+
last = u.path;
|
|
194
|
+
return completeStep(path);
|
|
195
|
+
}
|
|
196
|
+
debug(`Arrived at ${path}. Done.`);
|
|
186
197
|
}
|
|
187
198
|
|
|
188
|
-
|
|
199
|
+
try {
|
|
200
|
+
await completeStep(target);
|
|
201
|
+
} catch (e) {
|
|
202
|
+
try {
|
|
203
|
+
const content = await browser.$('#content');
|
|
204
|
+
const text = await content.getText();
|
|
205
|
+
debug('PAGE CONTENT >>>>>>');
|
|
206
|
+
debug(text);
|
|
207
|
+
debug('END PAGE CONTENT >>>>>>');
|
|
208
|
+
} catch (err) {
|
|
209
|
+
// ignore error
|
|
210
|
+
}
|
|
211
|
+
throw e;
|
|
212
|
+
}
|
|
189
213
|
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<!DOCTYPE html>
|
|
3
|
-
<!--[if lt IE 9]><html class="lte-ie8" lang="{{htmlLang}}"><![endif]-->
|
|
4
|
-
<!--[if gt IE 8]><!--><html lang="{{htmlLang}}" class="govuk-template--rebranded"><!--<![endif]-->
|
|
5
|
-
<head>
|
|
6
|
-
<meta charset="utf-8" />
|
|
7
|
-
<title>{{$pageTitle}}{{/pageTitle}}</title>
|
|
8
|
-
{{$head}}{{/head}}
|
|
9
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
10
|
-
<meta name="theme-color" content="#1d70b8">
|
|
11
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
12
|
-
<link rel="icon" sizes="48x48" href="{{govukAssetPath}}rebrand/images/favicon.ico">
|
|
13
|
-
<link rel="icon" sizes="any" href="{{govukAssetPath}}rebrand/images/favicon.svg" type="image/svg+xml">
|
|
14
|
-
<link rel="mask-icon" href="{{govukAssetPath}}rebrand/images/govuk-icon-mask.svg" color="#1d70b8">
|
|
15
|
-
<link rel="apple-touch-icon" href="{{govukAssetPath}}rebrand/images/govuk-icon-180.png">
|
|
16
|
-
<link rel="manifest" href="{{govukAssetPath}}rebrand/manifest.json">
|
|
17
|
-
<meta property="og:image" content="{{govukAssetPath}}rebrand/images/govuk-opengraph-image.png">
|
|
18
|
-
</head>
|
|
19
|
-
|
|
20
|
-
<body class="{{$bodyClasses}}{{/bodyClasses}} govuk-template__body js-enabled" >
|
|
21
|
-
<script {{#nonce}}nonce="{{nonce}}"{{/nonce}}>document.body.className += ' js-enabled' + ('noModule' in HTMLScriptElement.prototype ? ' govuk-frontend-supported' : '');</script>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<div id="global-cookie-message" class="gem-c-cookie-banner govuk-clearfix" data-module="cookie-banner" role="region" aria-label="cookie banner" data-nosnippet="">
|
|
25
|
-
{{$cookieMessage}}{{/cookieMessage}}
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
{{$bodyStart}}{{/bodyStart}}
|
|
29
|
-
|
|
30
|
-
<header role="banner" id="govuk-header" class="{{$headerClass}}{{/headerClass}}">
|
|
31
|
-
<div class="govuk-header__container govuk-width-container">
|
|
32
|
-
|
|
33
|
-
<div class="govuk-header__logo">
|
|
34
|
-
<a href="{{$homepageUrl}}https://www.gov.uk{{/homepageUrl}}" title="{{$logoLinkTitle}}Go to the GOV.UK homepage{{/logoLinkTitle}}" id="logo" class="govuk-header__link govuk-header__link--homepage" target="_blank" data-module="track-click" data-track-category="homeLinkClicked" data-track-action="homeHeader">
|
|
35
|
-
<!--[if gt IE 8]><!-->
|
|
36
|
-
<div id="govuk-header__logo"></div>
|
|
37
|
-
<img src="/public/images/govuk-logo.svg" id="govuk-header__logo" alt="Logo" loading="lazy" />
|
|
38
|
-
<!--<![endif]-->
|
|
39
|
-
<!--[if IE 8]>
|
|
40
|
-
<img src="{{govukAssetPath}}rebrand/images/govuk-logotype-tudor-crown.png" class="govuk-header__logotype-crown-fallback-image" width="32" height="30" alt="">
|
|
41
|
-
<![endif]-->
|
|
42
|
-
</a>
|
|
43
|
-
</div>
|
|
44
|
-
{{$insideHeader}}{{/insideHeader}}
|
|
45
|
-
|
|
46
|
-
{{$propositionHeader}}{{/propositionHeader}}
|
|
47
|
-
</div>
|
|
48
|
-
</header>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{{$afterHeader}}{{/afterHeader}}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{{$main}}{{/main}}
|
|
55
|
-
|
|
56
|
-
<footer class="govuk-footer">
|
|
57
|
-
<div class="govuk-width-container">
|
|
58
|
-
<svg
|
|
59
|
-
focusable="false"
|
|
60
|
-
role="presentation"
|
|
61
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
62
|
-
viewBox="0 0 64 60"
|
|
63
|
-
height="30"
|
|
64
|
-
width="32"
|
|
65
|
-
fill="currentcolor" class="govuk-footer__crown">
|
|
66
|
-
<g>
|
|
67
|
-
<circle cx="20" cy="17.6" r="3.7" />
|
|
68
|
-
<circle cx="10.2" cy="23.5" r="3.7" />
|
|
69
|
-
<circle cx="3.7" cy="33.2" r="3.7" />
|
|
70
|
-
<circle cx="31.7" cy="30.6" r="3.7" />
|
|
71
|
-
<circle cx="43.3" cy="17.6" r="3.7" />
|
|
72
|
-
<circle cx="53.2" cy="23.5" r="3.7" />
|
|
73
|
-
<circle cx="59.7" cy="33.2" r="3.7" />
|
|
74
|
-
<circle cx="31.7" cy="30.6" r="3.7" />
|
|
75
|
-
<path d="M33.1,9.8c.2-.1.3-.3.5-.5l4.6,2.4v-6.8l-4.6,1.5c-.1-.2-.3-.3-.5-.5l1.9-5.9h-6.7l1.9,5.9c-.2.1-.3.3-.5.5l-4.6-1.5v6.8l4.6-2.4c.1.2.3.3.5.5l-2.6,8c-.9,2.8,1.2,5.7,4.1,5.7h0c3,0,5.1-2.9,4.1-5.7l-2.6-8ZM37,37.9s-3.4,3.8-4.1,6.1c2.2,0,4.2-.5,6.4-2.8l-.7,8.5c-2-2.8-4.4-4.1-5.7-3.8.1,3.1.5,6.7,5.8,7.2,3.7.3,6.7-1.5,7-3.8.4-2.6-2-4.3-3.7-1.6-1.4-4.5,2.4-6.1,4.9-3.2-1.9-4.5-1.8-7.7,2.4-10.9,3,4,2.6,7.3-1.2,11.1,2.4-1.3,6.2,0,4,4.6-1.2-2.8-3.7-2.2-4.2.2-.3,1.7.7,3.7,3,4.2,1.9.3,4.7-.9,7-5.9-1.3,0-2.4.7-3.9,1.7l2.4-8c.6,2.3,1.4,3.7,2.2,4.5.6-1.6.5-2.8,0-5.3l5,1.8c-2.6,3.6-5.2,8.7-7.3,17.5-7.4-1.1-15.7-1.7-24.5-1.7h0c-8.8,0-17.1.6-24.5,1.7-2.1-8.9-4.7-13.9-7.3-17.5l5-1.8c-.5,2.5-.6,3.7,0,5.3.8-.8,1.6-2.3,2.2-4.5l2.4,8c-1.5-1-2.6-1.7-3.9-1.7,2.3,5,5.2,6.2,7,5.9,2.3-.4,3.3-2.4,3-4.2-.5-2.4-3-3.1-4.2-.2-2.2-4.6,1.6-6,4-4.6-3.7-3.7-4.2-7.1-1.2-11.1,4.2,3.2,4.3,6.4,2.4,10.9,2.5-2.8,6.3-1.3,4.9,3.2-1.8-2.7-4.1-1-3.7,1.6.3,2.3,3.3,4.1,7,3.8,5.4-.5,5.7-4.2,5.8-7.2-1.3-.2-3.7,1-5.7,3.8l-.7-8.5c2.2,2.3,4.2,2.7,6.4,2.8-.7-2.3-4.1-6.1-4.1-6.1h10.6,0Z" />
|
|
76
|
-
</g>
|
|
77
|
-
</svg>
|
|
78
|
-
<div class="govuk-footer__meta">
|
|
79
|
-
<div class="govuk-footer__meta-item govuk-footer__meta-item--grow">
|
|
80
|
-
<h2 class="govuk-visually-hidden">Support links</h2>
|
|
81
|
-
{{$footerSupportLinks}}{{/footerSupportLinks}}
|
|
82
|
-
<svg
|
|
83
|
-
aria-hidden="true"
|
|
84
|
-
focusable="false"
|
|
85
|
-
class="govuk-footer__licence-logo"
|
|
86
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
87
|
-
viewBox="0 0 483.2 195.7"
|
|
88
|
-
height="17"
|
|
89
|
-
width="41">
|
|
90
|
-
<path
|
|
91
|
-
fill="currentColor"
|
|
92
|
-
d="M421.5 142.8V.1l-50.7 32.3v161.1h112.4v-50.7zm-122.3-9.6A47.12 47.12 0 0 1 221 97.8c0-26 21.1-47.1 47.1-47.1 16.7 0 31.4 8.7 39.7 21.8l42.7-27.2A97.63 97.63 0 0 0 268.1 0c-36.5 0-68.3 20.1-85.1 49.7A98 98 0 0 0 97.8 0C43.9 0 0 43.9 0 97.8s43.9 97.8 97.8 97.8c36.5 0 68.3-20.1 85.1-49.7a97.76 97.76 0 0 0 149.6 25.4l19.4 22.2h3v-87.8h-80l24.3 27.5zM97.8 145c-26 0-47.1-21.1-47.1-47.1s21.1-47.1 47.1-47.1 47.2 21 47.2 47S123.8 145 97.8 145" />
|
|
93
|
-
</svg>
|
|
94
|
-
<span class="govuk-footer__licence-description">
|
|
95
|
-
{{$licenceMessage}}All content is available under the <a href="https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" id="open-government-licence" class="govuk-footer__link" target="_blank" rel="license">Open Government Licence v3.0</a>, except where otherwise stated{{/licenceMessage}}
|
|
96
|
-
</span>
|
|
97
|
-
</div>
|
|
98
|
-
<div class="govuk-footer__meta-item">
|
|
99
|
-
<a
|
|
100
|
-
class="govuk-footer__link govuk-footer__copyright-logo"
|
|
101
|
-
href="https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/">
|
|
102
|
-
{{$crownCopyrightMessage}}© Crown copyright{{/crownCopyrightMessage}}
|
|
103
|
-
</a>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
|
-
</div>
|
|
107
|
-
</footer>
|
|
108
|
-
|
|
109
|
-
<div id="global-app-error" class="app-error hidden"></div>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
{{$bodyEnd}}{{/bodyEnd}}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<script {{#nonce}}nonce="{{nonce}}"{{/nonce}}>if (typeof window.GOVUK === 'undefined') document.body.className = document.body.className.replace('js-enabled', '');</script>
|
|
116
|
-
|
|
117
|
-
</body>
|
|
118
|
-
</html>
|