testaro 64.4.1 → 64.6.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.
- package/package.json +1 -1
- package/procs/identify.js +1 -1
- package/procs/nu.js +15 -2
- package/procs/standardize.js +28 -12
- package/procs/testaro.js +53 -0
- package/run.js +43 -19
- package/tests/alfa.js +3 -2
- package/tests/htmlcs.js +29 -23
- package/tests/nuVal.js +1 -1
- package/tests/nuVnu.js +1 -1
package/package.json
CHANGED
package/procs/identify.js
CHANGED
package/procs/nu.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
// ########## IMPORTS
|
|
16
16
|
|
|
17
|
+
// Module to add Testaro IDs to elements.
|
|
18
|
+
const {addTestaroIDs, getLocationData} = require('./testaro');
|
|
17
19
|
// Module to get the document source.
|
|
18
20
|
const {getSource} = require('./getSource');
|
|
19
21
|
|
|
@@ -43,14 +45,16 @@ exports.getContent = async (page, withSource) => {
|
|
|
43
45
|
}
|
|
44
46
|
// Otherwise, i.e. if the specified content type was the Playwright page content:
|
|
45
47
|
else {
|
|
46
|
-
//
|
|
48
|
+
// Annotate all elements on the page with unique identifiers.
|
|
49
|
+
await addTestaroIDs(page);
|
|
50
|
+
// Add the annotated page content to the data.
|
|
47
51
|
data.testTarget = await page.content();
|
|
48
52
|
}
|
|
49
53
|
// Return the data.
|
|
50
54
|
return data;
|
|
51
55
|
};
|
|
52
56
|
// Postprocesses a result from nuVal or nuVnu tests.
|
|
53
|
-
exports.curate = (data, nuData, rules) => {
|
|
57
|
+
exports.curate = async (page, data, nuData, rules) => {
|
|
54
58
|
// Delete most of the test target from the data.
|
|
55
59
|
data.testTarget = `${data.testTarget.slice(0, 200)}…`;
|
|
56
60
|
let result;
|
|
@@ -76,11 +80,20 @@ exports.curate = (data, nuData, rules) => {
|
|
|
76
80
|
return false;
|
|
77
81
|
}
|
|
78
82
|
}));
|
|
83
|
+
}
|
|
84
|
+
// If there is a result:
|
|
85
|
+
if (result) {
|
|
79
86
|
// Remove messages reporting duplicate blank IDs.
|
|
80
87
|
const badMessages = new Set(['Duplicate ID .', 'The first occurrence of ID was here.']);
|
|
81
88
|
result.messages = result.messages.filter(
|
|
82
89
|
message => ! badMessages.has(message.message)
|
|
83
90
|
);
|
|
91
|
+
// For each message:
|
|
92
|
+
for (const message of result.messages) {
|
|
93
|
+
const {extract} = message;
|
|
94
|
+
// Add location data for the element to the message.
|
|
95
|
+
message.elementLocation = await getLocationData(page, extract);
|
|
96
|
+
}
|
|
84
97
|
}
|
|
85
98
|
// Return the result.
|
|
86
99
|
return result;
|
package/procs/standardize.js
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
// Limits the length of and unilinearizes a string.
|
|
19
19
|
const cap = rawString => {
|
|
20
20
|
const string = (rawString || '').replace(/[\s\u2028\u2029]+/g, ' ');
|
|
21
|
-
if (string && string.length >
|
|
22
|
-
return `${string.slice(0,
|
|
21
|
+
if (string && string.length > 1000) {
|
|
22
|
+
return `${string.slice(0, 500)} … ${string.slice(-500)}`;
|
|
23
23
|
}
|
|
24
24
|
else if (string) {
|
|
25
25
|
return string;
|
|
@@ -35,12 +35,12 @@ const getIdentifiers = code => {
|
|
|
35
35
|
// Normalize the code.
|
|
36
36
|
code = code.replace(/\s+/g, ' ').replace(/\\"/g, '"');
|
|
37
37
|
// Get the first start tag of an element, if any.
|
|
38
|
-
const startTagData = code.match(/^.*?<
|
|
38
|
+
const startTagData = code.match(/^.*?<([a-zA-][^>]*)/);
|
|
39
39
|
// If there is any:
|
|
40
40
|
if (startTagData) {
|
|
41
41
|
// Get the tag name.
|
|
42
|
-
const
|
|
43
|
-
const tagName =
|
|
42
|
+
const tagNameArray = startTagData[1].match(/^[A-Za-z0-9]+/);
|
|
43
|
+
const tagName = tagNameArray ? tagNameArray[0].toUpperCase() : '';
|
|
44
44
|
// Get the value of the id attribute, if any.
|
|
45
45
|
const idData = startTagData[1].match(/ id="([^"]+)"/);
|
|
46
46
|
const id = idData ? idData[1] : '';
|
|
@@ -189,7 +189,7 @@ const doHTMLCS = (result, standardResult, severity) => {
|
|
|
189
189
|
const ruleData = result[severity][ruleID];
|
|
190
190
|
Object.keys(ruleData).forEach(what => {
|
|
191
191
|
ruleData[what].forEach(item => {
|
|
192
|
-
const {tagName, id,
|
|
192
|
+
const {tagName, id, excerpt, notInDOM, boxID, pathID} = item;
|
|
193
193
|
const instance = {
|
|
194
194
|
ruleID,
|
|
195
195
|
what,
|
|
@@ -197,11 +197,13 @@ const doHTMLCS = (result, standardResult, severity) => {
|
|
|
197
197
|
tagName: tagName.toUpperCase(),
|
|
198
198
|
id: isBadID(id.slice(1)) ? '' : id.slice(1),
|
|
199
199
|
location: {
|
|
200
|
-
doc: 'dom',
|
|
200
|
+
doc: notInDOM ? 'notInDOM' : 'dom',
|
|
201
201
|
type: '',
|
|
202
202
|
spec: ''
|
|
203
203
|
},
|
|
204
|
-
excerpt: cap(
|
|
204
|
+
excerpt: cap(excerpt),
|
|
205
|
+
boxID,
|
|
206
|
+
pathID
|
|
205
207
|
};
|
|
206
208
|
standardResult.instances.push(instance);
|
|
207
209
|
});
|
|
@@ -209,12 +211,23 @@ const doHTMLCS = (result, standardResult, severity) => {
|
|
|
209
211
|
});
|
|
210
212
|
}
|
|
211
213
|
};
|
|
212
|
-
// Converts issue instances from a nuVal or nuVnu result
|
|
214
|
+
// Converts issue instances from a nuVal or nuVnu result.
|
|
213
215
|
const doNu = (withSource, result, standardResult) => {
|
|
214
216
|
const items = result && result.messages;
|
|
217
|
+
// If there are any messages:
|
|
215
218
|
if (items && items.length) {
|
|
219
|
+
// For each one:
|
|
216
220
|
items.forEach(item => {
|
|
217
|
-
const {
|
|
221
|
+
const {
|
|
222
|
+
extract,
|
|
223
|
+
firstColumn,
|
|
224
|
+
lastColumn,
|
|
225
|
+
lastLine,
|
|
226
|
+
message,
|
|
227
|
+
subType,
|
|
228
|
+
type,
|
|
229
|
+
elementLocation
|
|
230
|
+
} = item;
|
|
218
231
|
const identifiers = getIdentifiers(extract);
|
|
219
232
|
if (! identifiers[0] && message) {
|
|
220
233
|
const tagNameLCArray = message.match(
|
|
@@ -229,6 +242,7 @@ const doNu = (withSource, result, standardResult) => {
|
|
|
229
242
|
if (locationSegments.every(segment => typeof segment === 'number')) {
|
|
230
243
|
spec = locationSegments.join(':');
|
|
231
244
|
}
|
|
245
|
+
const {notInDOM} = elementLocation;
|
|
232
246
|
const instance = {
|
|
233
247
|
ruleID: message,
|
|
234
248
|
what: message,
|
|
@@ -236,11 +250,13 @@ const doNu = (withSource, result, standardResult) => {
|
|
|
236
250
|
tagName: identifiers[0],
|
|
237
251
|
id: identifiers[1],
|
|
238
252
|
location: {
|
|
239
|
-
doc: withSource ? 'source' : 'dom',
|
|
253
|
+
doc: withSource ? 'source' : (notInDOM ? 'notInDOM' : 'dom'),
|
|
240
254
|
type: 'code',
|
|
241
255
|
spec
|
|
242
256
|
},
|
|
243
|
-
excerpt: cap(extract)
|
|
257
|
+
excerpt: cap(extract),
|
|
258
|
+
boxID: elementLocation?.boxID || '',
|
|
259
|
+
pathID: elementLocation?.pathID || ''
|
|
244
260
|
};
|
|
245
261
|
if (type === 'info' && subType === 'warning') {
|
|
246
262
|
instance.ordinalSeverity = 0;
|
package/procs/testaro.js
CHANGED
|
@@ -225,3 +225,56 @@ exports.getVisibleCountChange = async (
|
|
|
225
225
|
elapsedTime
|
|
226
226
|
};
|
|
227
227
|
};
|
|
228
|
+
// Annotates every element on a page with a unique identifier.
|
|
229
|
+
exports.addTestaroIDs = async page => {
|
|
230
|
+
await page.evaluate(() => {
|
|
231
|
+
let serialID = 0;
|
|
232
|
+
for (const element of Array.from(document.querySelectorAll('*'))) {
|
|
233
|
+
element.setAttribute('data-testaro-id', `${serialID++}#`);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
// Returns location data from the extract of a standard instance.
|
|
238
|
+
exports.getLocationData = async (page, extract) => {
|
|
239
|
+
const testaroIDArray = extract.match(/data-testaro-id="(\d+)#"/);
|
|
240
|
+
// If the extract contains a Testaro identifier:
|
|
241
|
+
if (testaroIDArray) {
|
|
242
|
+
const testaroID = testaroIDArray[1];
|
|
243
|
+
// Return location data for the element.
|
|
244
|
+
return await page.evaluate(testaroID => {
|
|
245
|
+
const element = document.querySelector(`[data-testaro-id="${testaroID}#"]`);
|
|
246
|
+
// If any element has that identifier:
|
|
247
|
+
if (element) {
|
|
248
|
+
// Get box and path IDs for the element.
|
|
249
|
+
const box = {};
|
|
250
|
+
let boxID = '';
|
|
251
|
+
const boundingBox = element.getBoundingClientRect() || {};
|
|
252
|
+
if (boundingBox.x) {
|
|
253
|
+
['x', 'y', 'width', 'height'].forEach(coordinate => {
|
|
254
|
+
box[coordinate] = Math.round(boundingBox[coordinate]);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
if (typeof box.x === 'number') {
|
|
258
|
+
boxID = Object.values(box).join(':');
|
|
259
|
+
}
|
|
260
|
+
const pathID = window.getXPath(element) || '';
|
|
261
|
+
// Return them.
|
|
262
|
+
return {
|
|
263
|
+
boxID,
|
|
264
|
+
pathID
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
// Otherwise, i.e. if no element has it, return empty location data.
|
|
268
|
+
return {};
|
|
269
|
+
}, testaroID);
|
|
270
|
+
}
|
|
271
|
+
// Otherwise, i.e. if the extract contains no Testaro identifier:
|
|
272
|
+
else {
|
|
273
|
+
// Return a non-DOM location.
|
|
274
|
+
return {
|
|
275
|
+
notInDOM: true,
|
|
276
|
+
boxID: '',
|
|
277
|
+
pathID: ''
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
};
|
package/run.js
CHANGED
|
@@ -377,23 +377,8 @@ const launch = exports.launch = async (
|
|
|
377
377
|
let indentedMsg = '';
|
|
378
378
|
// If debugging is on:
|
|
379
379
|
if (debug) {
|
|
380
|
-
// Log
|
|
381
|
-
|
|
382
|
-
if (msgText.length > 75) {
|
|
383
|
-
parts.push(msgText.slice(75, 150));
|
|
384
|
-
if (msgText.length > 150) {
|
|
385
|
-
const tail = msgText.slice(150).slice(-150);
|
|
386
|
-
if (msgText.length > 300) {
|
|
387
|
-
parts.push('...');
|
|
388
|
-
}
|
|
389
|
-
parts.push(tail.slice(0, 75));
|
|
390
|
-
if (tail.length > 75) {
|
|
391
|
-
parts.push(tail.slice(75));
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
indentedMsg = parts.map(part => ` | ${part}`).join('\n');
|
|
396
|
-
console.log(`\n${indentedMsg}`);
|
|
380
|
+
// Log the start of the message on the console.
|
|
381
|
+
console.log(`\n${msgText.slice(0, 300)}`);
|
|
397
382
|
}
|
|
398
383
|
// Add statistics on the message to the report.
|
|
399
384
|
const msgTextLC = msgText.toLowerCase();
|
|
@@ -429,8 +414,10 @@ const launch = exports.launch = async (
|
|
|
429
414
|
});
|
|
430
415
|
});
|
|
431
416
|
const isTestaroTest = act.type === 'test' && act.which === 'testaro';
|
|
432
|
-
|
|
433
|
-
|
|
417
|
+
const isHTMLCSTest = act.type === 'test' && act.which === 'htmlcs';
|
|
418
|
+
const isNuTest = act.type === 'test' && (['nuVal', 'nuVnu'].some(id => act.which === id));
|
|
419
|
+
// If the launch is for a testaro,3 htmlcs, or Nu test act:
|
|
420
|
+
if (isTestaroTest || isHTMLCSTest || isNuTest) {
|
|
434
421
|
// Add a script to the page to add a window method to get the XPath of an element.
|
|
435
422
|
await page.addInitScript(() => {
|
|
436
423
|
window.getXPath = element => {
|
|
@@ -477,6 +464,9 @@ const launch = exports.launch = async (
|
|
|
477
464
|
return `/${segments.join('/')}`;
|
|
478
465
|
};
|
|
479
466
|
});
|
|
467
|
+
}
|
|
468
|
+
// If the launch is for a testaro test act:
|
|
469
|
+
if (isTestaroTest) {
|
|
480
470
|
// Add a script to the page to compute the accessible name of an element.
|
|
481
471
|
await page.addInitScript({path: require.resolve('./dist/nameComputation.js')});
|
|
482
472
|
// Add a script to the page to:
|
|
@@ -1685,6 +1675,40 @@ const doActs = async (report, opts = {}) => {
|
|
|
1685
1675
|
// Close the last browser launched for standardization.
|
|
1686
1676
|
await browserClose();
|
|
1687
1677
|
console.log('Standardization completed');
|
|
1678
|
+
// XXX
|
|
1679
|
+
const {acts} = report;
|
|
1680
|
+
const idData = {};
|
|
1681
|
+
for (const act of acts) {
|
|
1682
|
+
if (act.type === 'test') {
|
|
1683
|
+
const {which} = act;
|
|
1684
|
+
idData[which] ??= {
|
|
1685
|
+
instanceCount: 0,
|
|
1686
|
+
boxIDCount: 0,
|
|
1687
|
+
pathIDCount: 0,
|
|
1688
|
+
boxIDPercent: null,
|
|
1689
|
+
pathIDPercent: null
|
|
1690
|
+
};
|
|
1691
|
+
const actIDData = idData[which];
|
|
1692
|
+
const {standardResult} = act;
|
|
1693
|
+
const {instances} = standardResult;
|
|
1694
|
+
for (const instance of instances) {
|
|
1695
|
+
const {boxID, pathID} = instance;
|
|
1696
|
+
actIDData.instanceCount++;
|
|
1697
|
+
if (boxID) {
|
|
1698
|
+
actIDData.boxIDCount++;
|
|
1699
|
+
}
|
|
1700
|
+
if (pathID) {
|
|
1701
|
+
actIDData.pathIDCount++;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
const {instanceCount, boxIDCount, pathIDCount} = actIDData;
|
|
1705
|
+
if (instanceCount) {
|
|
1706
|
+
actIDData.boxIDPercent = Math.round(100 * boxIDCount / instanceCount);
|
|
1707
|
+
actIDData.pathIDPercent = Math.round(100 * pathIDCount / instanceCount);
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
report.jobData.idData = idData;
|
|
1688
1712
|
}
|
|
1689
1713
|
// Delete the temporary report file.
|
|
1690
1714
|
await fs.rm(reportPath, {force: true});
|
package/tests/alfa.js
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
|
|
18
18
|
let alfaRules = require('@siteimprove/alfa-rules').default;
|
|
19
19
|
const {Audit} = require('@siteimprove/alfa-act');
|
|
20
|
-
const path = require('path');
|
|
21
20
|
const {Playwright} = require('@siteimprove/alfa-playwright');
|
|
22
21
|
|
|
23
22
|
// FUNCTIONS
|
|
@@ -88,7 +87,9 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
88
87
|
type: targetJ.type,
|
|
89
88
|
tagName: targetJ.name || '',
|
|
90
89
|
path: target.path(),
|
|
91
|
-
codeLines: codeLines.map(
|
|
90
|
+
codeLines: codeLines.map(
|
|
91
|
+
line => line.length > 300 ? `${line.slice(0, 300)}...` : line
|
|
92
|
+
)
|
|
92
93
|
}
|
|
93
94
|
};
|
|
94
95
|
// If the rule summary is missing:
|
package/tests/htmlcs.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
// IMPORTS
|
|
16
16
|
|
|
17
|
+
// Module to add Testaro IDs to elements.
|
|
18
|
+
const {addTestaroIDs, getLocationData} = require('../procs/testaro');
|
|
17
19
|
// Module to handle files.
|
|
18
20
|
const fs = require('fs/promises');
|
|
19
21
|
|
|
@@ -28,10 +30,12 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
28
30
|
// Get the HTMLCS script.
|
|
29
31
|
const scriptText = await fs.readFile(`${__dirname}/../htmlcs/HTMLCS.js`, 'utf8');
|
|
30
32
|
const scriptNonce = report.jobData && report.jobData.lastScriptNonce;
|
|
31
|
-
//
|
|
33
|
+
// Annotate all elements on the page with unique identifiers.
|
|
34
|
+
await addTestaroIDs(page);
|
|
32
35
|
let messageStrings = [];
|
|
36
|
+
// Define the rules to be employed as those of WCAG 2 level AAA.
|
|
33
37
|
for (const actStandard of ['WCAG2AAA']) {
|
|
34
|
-
const
|
|
38
|
+
const nextViolations = await page.evaluate(args => {
|
|
35
39
|
// Add the HTMLCS script to the page.
|
|
36
40
|
const scriptText = args[2];
|
|
37
41
|
const scriptNonce = args[3];
|
|
@@ -49,18 +53,18 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
49
53
|
}
|
|
50
54
|
window.HTMLCS_WCAG2AAA.sniffs = rules;
|
|
51
55
|
}
|
|
56
|
+
let violations = null;
|
|
52
57
|
// Run the tests.
|
|
53
|
-
let issues = null;
|
|
54
58
|
try {
|
|
55
|
-
|
|
59
|
+
violations = window.HTMLCS_RUNNER.run(actStandard);
|
|
56
60
|
}
|
|
57
61
|
catch(error) {
|
|
58
62
|
console.log(`ERROR executing HTMLCS_RUNNER on ${document.URL} (${error.message})`);
|
|
59
63
|
}
|
|
60
|
-
return
|
|
64
|
+
return violations;
|
|
61
65
|
}, [actStandard, rules, scriptText, scriptNonce]);
|
|
62
|
-
if (
|
|
63
|
-
messageStrings.push(...
|
|
66
|
+
if (nextViolations && nextViolations.every(violation => typeof violation === 'string')) {
|
|
67
|
+
messageStrings.push(... nextViolations);
|
|
64
68
|
}
|
|
65
69
|
else {
|
|
66
70
|
data.prevented = true;
|
|
@@ -69,39 +73,41 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
if (! data.prevented) {
|
|
72
|
-
// Sort the
|
|
76
|
+
// Sort the violations by class and standard.
|
|
73
77
|
messageStrings.sort();
|
|
74
|
-
// Remove any duplicate
|
|
78
|
+
// Remove any duplicate violations.
|
|
75
79
|
messageStrings = [... new Set(messageStrings)];
|
|
76
80
|
// Initialize the result.
|
|
77
81
|
result.Error = {};
|
|
78
82
|
result.Warning = {};
|
|
79
|
-
// For each
|
|
80
|
-
messageStrings.forEach(string => {
|
|
83
|
+
// For each violation:
|
|
84
|
+
messageStrings.forEach(async string => {
|
|
85
|
+
// Split its message into severity class, rule ID, tagname, ID, rule description, and excerpt.
|
|
81
86
|
const parts = string.split(/\|/, 6);
|
|
82
87
|
const partCount = parts.length;
|
|
83
88
|
if (partCount < 6) {
|
|
84
|
-
console.log(`ERROR:
|
|
89
|
+
console.log(`ERROR: Violation string ${string} has too few parts`);
|
|
85
90
|
}
|
|
86
91
|
// If it is an error or a warning (not a notice):
|
|
87
92
|
else if (['Error', 'Warning'].includes(parts[0])) {
|
|
88
93
|
/*
|
|
89
|
-
Add the
|
|
90
|
-
This saves space, because, although some descriptions are
|
|
94
|
+
Add the violation to an violationClass.violationCode.description array in the result.
|
|
95
|
+
This saves space, because, although some descriptions are violation-specific, such as
|
|
91
96
|
descriptions that state the contrast ratio of an element, most descriptions are
|
|
92
97
|
generic, so typically many violations share a description.
|
|
93
98
|
*/
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
result[parts[0]][issueCode][parts[4]].push({
|
|
99
|
+
const ruleID = parts[1].replace(/^WCAG2|\.Principle\d\.Guideline[\d_]+/g, '');
|
|
100
|
+
result[parts[0]][ruleID] ??= {};
|
|
101
|
+
result[parts[0]][ruleID][parts[4]] ??= [];
|
|
102
|
+
const elementLocation = await getLocationData(page, parts[5]);
|
|
103
|
+
const {boxID, notInDOM, pathID} = elementLocation;
|
|
104
|
+
result[parts[0]][ruleID][parts[4]].push({
|
|
102
105
|
tagName: parts[2],
|
|
103
106
|
id: parts[3],
|
|
104
|
-
|
|
107
|
+
notInDOM,
|
|
108
|
+
excerpt: parts[5],
|
|
109
|
+
boxID,
|
|
110
|
+
pathID
|
|
105
111
|
});
|
|
106
112
|
}
|
|
107
113
|
});
|
package/tests/nuVal.js
CHANGED
|
@@ -65,7 +65,7 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
65
65
|
data.error = message;
|
|
66
66
|
};
|
|
67
67
|
// Postprocess the response data.
|
|
68
|
-
result = curate(data, nuData, rules);
|
|
68
|
+
result = await curate(page, data, nuData, rules);
|
|
69
69
|
}
|
|
70
70
|
// Otherwise, i.e. if the page content was not obtained:
|
|
71
71
|
else {
|
package/tests/nuVnu.js
CHANGED
|
@@ -69,7 +69,7 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
69
69
|
// Delete the temporary file.
|
|
70
70
|
await fs.unlink(pagePath);
|
|
71
71
|
// Postprocess the result.
|
|
72
|
-
result = curate(data, nuData, rules);
|
|
72
|
+
result = await curate(page, data, nuData, rules);
|
|
73
73
|
}
|
|
74
74
|
// Otherwise, i.e. if the content was not obtained:
|
|
75
75
|
else {
|