pagean 6.0.7 → 7.0.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/README.md +104 -110
- package/bin/pagean.js +14 -7
- package/bin/pageanrc-lint.js +14 -13
- package/docs/upgrade-guide.md +26 -26
- package/index.js +18 -7
- package/lib/config.js +35 -13
- package/lib/default-config.json +2 -8
- package/lib/{externalFileUtils.js → external-file-utils.js} +7 -4
- package/lib/{linkUtils.js → link-utils.js} +36 -35
- package/lib/logger.js +7 -3
- package/lib/reporter.js +4 -2
- package/lib/{schemaErrors.js → schema-errors.js} +26 -10
- package/lib/{testUtils.js → test-utils.js} +20 -8
- package/lib/tests.js +194 -94
- package/package.json +25 -21
- package/schemas/pageanrc.schema.json +3 -11
package/lib/config.js
CHANGED
|
@@ -12,7 +12,7 @@ const Ajv = require('ajv').default;
|
|
|
12
12
|
const ajvErrors = require('ajv-errors');
|
|
13
13
|
const protocolify = require('protocolify');
|
|
14
14
|
|
|
15
|
-
const { normalizeLink } = require('./
|
|
15
|
+
const { normalizeLink } = require('./link-utils');
|
|
16
16
|
|
|
17
17
|
const defaultConfig = require('./default-config.json');
|
|
18
18
|
const defaultHtmlHintConfigFilename = './.htmlhintrc';
|
|
@@ -22,8 +22,7 @@ const getUrl = (testUrl) => {
|
|
|
22
22
|
if (typeof testUrl === 'object') {
|
|
23
23
|
rawUrl = testUrl.url;
|
|
24
24
|
urlSettings = testUrl.settings;
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
25
|
+
} else {
|
|
27
26
|
rawUrl = testUrl;
|
|
28
27
|
}
|
|
29
28
|
return { rawUrl, urlSettings };
|
|
@@ -47,27 +46,42 @@ const processAllTestSettings = (settings) => {
|
|
|
47
46
|
return processedSettings;
|
|
48
47
|
};
|
|
49
48
|
|
|
50
|
-
const consolidateTestSettings = (
|
|
49
|
+
const consolidateTestSettings = (
|
|
50
|
+
defaultSettings,
|
|
51
|
+
globalSettings,
|
|
52
|
+
urlSettings
|
|
53
|
+
) => {
|
|
51
54
|
const sanitizedGlobalSettings = globalSettings ? globalSettings : {};
|
|
52
55
|
const sanitizedUrlSettings = urlSettings ? urlSettings : {};
|
|
53
56
|
const processedSettings = {};
|
|
54
57
|
for (const key of Object.keys(defaultSettings)) {
|
|
55
|
-
processedSettings[key] = {
|
|
58
|
+
processedSettings[key] = {
|
|
59
|
+
...defaultSettings[key],
|
|
60
|
+
...sanitizedGlobalSettings[key],
|
|
61
|
+
...sanitizedUrlSettings[key]
|
|
62
|
+
};
|
|
56
63
|
}
|
|
57
64
|
if (processedSettings.brokenLinkTest.ignoredLinks) {
|
|
58
|
-
processedSettings.brokenLinkTest.ignoredLinks =
|
|
65
|
+
processedSettings.brokenLinkTest.ignoredLinks =
|
|
66
|
+
processedSettings.brokenLinkTest.ignoredLinks.map((link) =>
|
|
67
|
+
normalizeLink(link)
|
|
68
|
+
);
|
|
59
69
|
}
|
|
60
70
|
return processedSettings;
|
|
61
71
|
};
|
|
62
72
|
|
|
63
73
|
const processUrls = (config) => {
|
|
64
74
|
const processedConfigSettings = processAllTestSettings(config.settings);
|
|
65
|
-
return config.urls.map(testUrl => {
|
|
75
|
+
return config.urls.map((testUrl) => {
|
|
66
76
|
const { rawUrl, urlSettings } = getUrl(testUrl);
|
|
67
77
|
return {
|
|
68
78
|
url: protocolify(rawUrl),
|
|
69
79
|
rawUrl,
|
|
70
|
-
settings: consolidateTestSettings(
|
|
80
|
+
settings: consolidateTestSettings(
|
|
81
|
+
defaultConfig.settings,
|
|
82
|
+
processedConfigSettings,
|
|
83
|
+
processAllTestSettings(urlSettings)
|
|
84
|
+
)
|
|
71
85
|
};
|
|
72
86
|
});
|
|
73
87
|
};
|
|
@@ -76,11 +90,15 @@ const getHtmlHintConfig = (htmlHintConfigFilename) => {
|
|
|
76
90
|
if (!fs.existsSync(htmlHintConfigFilename)) {
|
|
77
91
|
return;
|
|
78
92
|
}
|
|
79
|
-
return JSON.parse(fs.readFileSync(htmlHintConfigFilename, '
|
|
93
|
+
return JSON.parse(fs.readFileSync(htmlHintConfigFilename, 'utf8'));
|
|
80
94
|
};
|
|
81
95
|
|
|
82
96
|
const validateConfigSchema = (config) => {
|
|
83
|
-
const schema = JSON.parse(
|
|
97
|
+
const schema = JSON.parse(
|
|
98
|
+
fs.readFileSync(
|
|
99
|
+
path.join(__dirname, '../', 'schemas', 'pageanrc.schema.json')
|
|
100
|
+
)
|
|
101
|
+
);
|
|
84
102
|
const ajv = new Ajv({ allErrors: true });
|
|
85
103
|
ajvErrors(ajv);
|
|
86
104
|
const validate = ajv.compile(schema);
|
|
@@ -89,7 +107,7 @@ const validateConfigSchema = (config) => {
|
|
|
89
107
|
};
|
|
90
108
|
|
|
91
109
|
const getConfigFromFile = (configFileName) => {
|
|
92
|
-
return JSON.parse(fs.readFileSync(configFileName, '
|
|
110
|
+
return JSON.parse(fs.readFileSync(configFileName, 'utf8'));
|
|
93
111
|
};
|
|
94
112
|
|
|
95
113
|
/**
|
|
@@ -104,13 +122,17 @@ const processConfig = (configFileName) => {
|
|
|
104
122
|
const config = getConfigFromFile(configFileName);
|
|
105
123
|
const { isValid } = validateConfigSchema(config);
|
|
106
124
|
if (!isValid) {
|
|
107
|
-
throw new TypeError(
|
|
125
|
+
throw new TypeError(
|
|
126
|
+
`File ${configFileName} has an invalid pageanrc schema`
|
|
127
|
+
);
|
|
108
128
|
}
|
|
109
129
|
return {
|
|
110
130
|
project: config.project || '',
|
|
111
131
|
puppeteerLaunchOptions: config.puppeteerLaunchOptions,
|
|
112
132
|
urls: processUrls(config),
|
|
113
|
-
htmlHintConfig: getHtmlHintConfig(
|
|
133
|
+
htmlHintConfig: getHtmlHintConfig(
|
|
134
|
+
config.htmlhintrc || defaultHtmlHintConfigFilename
|
|
135
|
+
),
|
|
114
136
|
reporters: config.reporters ? config.reporters : defaultConfig.reporters
|
|
115
137
|
};
|
|
116
138
|
};
|
package/lib/default-config.json
CHANGED
|
@@ -32,12 +32,6 @@
|
|
|
32
32
|
"ignoreDuplicates": true
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
|
-
"reporters": [
|
|
36
|
-
|
|
37
|
-
"html",
|
|
38
|
-
"json"
|
|
39
|
-
],
|
|
40
|
-
"urls": [
|
|
41
|
-
"ignored, required to validate schema"
|
|
42
|
-
]
|
|
35
|
+
"reporters": ["cli", "html", "json"],
|
|
36
|
+
"urls": ["ignored, required to validate schema"]
|
|
43
37
|
}
|
|
@@ -39,7 +39,11 @@ const saveExternalScript = async (script) => {
|
|
|
39
39
|
const result = { url: script };
|
|
40
40
|
try {
|
|
41
41
|
const scriptUrl = new URL(script);
|
|
42
|
-
const pathName = path.join(
|
|
42
|
+
const pathName = path.join(
|
|
43
|
+
externalFilePath,
|
|
44
|
+
scriptUrl.hostname,
|
|
45
|
+
scriptUrl.pathname
|
|
46
|
+
);
|
|
43
47
|
if (!fs.existsSync(pathName)) {
|
|
44
48
|
// Axios will throw for any error response
|
|
45
49
|
const response = await axios.get(script);
|
|
@@ -47,9 +51,8 @@ const saveExternalScript = async (script) => {
|
|
|
47
51
|
fs.writeFileSync(pathName, response.data);
|
|
48
52
|
}
|
|
49
53
|
result.localFile = pathName;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
result.error = err.message;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
result.error = error.message;
|
|
53
56
|
}
|
|
54
57
|
return result;
|
|
55
58
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Utilities for checking page links.
|
|
5
5
|
*
|
|
6
|
-
* @module
|
|
6
|
+
* @module link-utils
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const https = require('https');
|
|
@@ -29,12 +29,12 @@ const httpResponse = Object.freeze({
|
|
|
29
29
|
unknownError: 999
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
const noRetryResponses = [httpResponse.tooManyRequests];
|
|
32
|
+
const noRetryResponses = new Set([httpResponse.tooManyRequests]);
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
/* eslint-disable jsdoc/require-description-complete-sentence */
|
|
35
35
|
/**
|
|
36
|
-
* Normalizes a URL with https://www.npmjs.com/package/normalize-url
|
|
37
|
-
*
|
|
36
|
+
* Normalizes a URL (with https://www.npmjs.com/package/normalize-url).
|
|
37
|
+
* Uses defaults plus the following overrides.
|
|
38
38
|
* 1. Set default protocol to https if protocol-relative
|
|
39
39
|
* 2. Do not remove any querystring parameters
|
|
40
40
|
* 3. Strip hash from URL
|
|
@@ -42,17 +42,17 @@ const noRetryResponses = [httpResponse.tooManyRequests];
|
|
|
42
42
|
*
|
|
43
43
|
* @public
|
|
44
44
|
* @static
|
|
45
|
-
* @param
|
|
46
|
-
* @returns {string}
|
|
45
|
+
* @param {string} url The URL to normalize.
|
|
46
|
+
* @returns {string} The normalized URL.
|
|
47
47
|
*/
|
|
48
|
-
const normalizeLink = url =>
|
|
49
|
-
{
|
|
48
|
+
const normalizeLink = (url) =>
|
|
49
|
+
normalizeUrl(url, {
|
|
50
50
|
defaultProtocol: 'https:',
|
|
51
51
|
removeQueryParameters: [],
|
|
52
52
|
stripHash: true,
|
|
53
53
|
stripWWW: false
|
|
54
54
|
});
|
|
55
|
-
|
|
55
|
+
/* eslint-enable jsdoc/require-description-complete-sentence */
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Checks settings to determine if the provided link should be ignored.
|
|
@@ -64,8 +64,8 @@ const normalizeLink = url => normalizeUrl(url,
|
|
|
64
64
|
* @param {string} link The link to check against the ignore list.
|
|
65
65
|
* @returns {boolean} True if the link should be ignored, otherwise false.
|
|
66
66
|
*/
|
|
67
|
-
const ignoreLink = (settings, link) =>
|
|
68
|
-
|
|
67
|
+
const ignoreLink = (settings, link) =>
|
|
68
|
+
settings.ignoredLinks && settings.ignoredLinks.includes(link);
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Checks a response to an HTTP request, either a response code or explicit error,
|
|
@@ -76,8 +76,9 @@ const ignoreLink = (settings, link) => settings.ignoredLinks && settings.ignored
|
|
|
76
76
|
* @param {(string|number)} response The response to an HTTP request to check for failure.
|
|
77
77
|
* @returns {boolean} True if failed, otherwise false.
|
|
78
78
|
*/
|
|
79
|
-
const isFailedResponse =
|
|
80
|
-
|
|
79
|
+
const isFailedResponse = (response) =>
|
|
80
|
+
Number.isNaN(Number(response.status)) ||
|
|
81
|
+
response.status >= httpResponse.badRequest;
|
|
81
82
|
|
|
82
83
|
/**
|
|
83
84
|
* Checks a Puppeteer page for the element specified in the hash of the provided link.
|
|
@@ -98,7 +99,6 @@ const checkSamePageLink = async (page, link) => {
|
|
|
98
99
|
return element ? httpResponse.ok : `${selector} Not Found`;
|
|
99
100
|
};
|
|
100
101
|
|
|
101
|
-
|
|
102
102
|
/**
|
|
103
103
|
* Checks the provided link for validity by loading in a Puppeteer page.
|
|
104
104
|
*
|
|
@@ -115,16 +115,14 @@ const checkExternalPageLinkBrowser = async (page, link) => {
|
|
|
115
115
|
const response = await testPage.goto(link);
|
|
116
116
|
status = response.status();
|
|
117
117
|
await testPage.close();
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
118
|
+
} catch (error) {
|
|
120
119
|
// Errors are returned in the format: "ENOTFOUND at https://this.url.does.not.exist/",
|
|
121
120
|
// so extract error only and remove URL
|
|
122
|
-
status =
|
|
121
|
+
status = error.message.replace(/^(.*) at .*$/, '$1');
|
|
123
122
|
}
|
|
124
123
|
return status;
|
|
125
124
|
};
|
|
126
125
|
|
|
127
|
-
|
|
128
126
|
/**
|
|
129
127
|
* Checks the provided link for validity by requesting with axios. If useGet if false,
|
|
130
128
|
* a HEAD request is made for efficiency. If useGet is true, a full GET request is made.
|
|
@@ -142,7 +140,10 @@ const checkExternalPageLink = async (page, link, useGet = false) => {
|
|
|
142
140
|
const userAgent = await page.evaluate('navigator.userAgent');
|
|
143
141
|
|
|
144
142
|
try {
|
|
145
|
-
const options = {
|
|
143
|
+
const options = {
|
|
144
|
+
headers: { 'User-Agent': userAgent },
|
|
145
|
+
timeout: timeoutSeconds * msPerSec
|
|
146
|
+
};
|
|
146
147
|
// Using internal browser property since not exposed
|
|
147
148
|
// eslint-disable-next-line no-underscore-dangle
|
|
148
149
|
if (page.browser()._ignoreHTTPSErrors) {
|
|
@@ -152,22 +153,24 @@ const checkExternalPageLink = async (page, link, useGet = false) => {
|
|
|
152
153
|
const httpMethod = useGet ? axios.get : axios.head;
|
|
153
154
|
const response = await httpMethod(link, options);
|
|
154
155
|
return response.status;
|
|
155
|
-
}
|
|
156
|
-
catch (err) {
|
|
156
|
+
} catch (error) {
|
|
157
157
|
// Some servers respond invalid for head request (e.g. a lot of 405 Method
|
|
158
158
|
// Not Allowed), so if a response was returned, is not a response that should
|
|
159
159
|
// skip a retry (e.g. 429), and the request was head then retry with get.
|
|
160
|
-
if (
|
|
160
|
+
if (
|
|
161
|
+
error.response &&
|
|
162
|
+
!noRetryResponses.has(error.response.status) &&
|
|
163
|
+
!useGet
|
|
164
|
+
) {
|
|
161
165
|
return checkExternalPageLink(page, link, true);
|
|
162
166
|
}
|
|
163
167
|
|
|
164
168
|
// Axios will throw for failed response (code >= 400), so return
|
|
165
169
|
// that response code or the error code if execution error
|
|
166
|
-
return
|
|
170
|
+
return error.response ? error.response.status : error.code;
|
|
167
171
|
}
|
|
168
172
|
};
|
|
169
173
|
|
|
170
|
-
|
|
171
174
|
/**
|
|
172
175
|
* Factory function returning a linkChecker object with a {@link checkLink}
|
|
173
176
|
* function that caches checked link results.
|
|
@@ -176,7 +179,6 @@ const checkExternalPageLink = async (page, link, useGet = false) => {
|
|
|
176
179
|
* @static
|
|
177
180
|
* @returns {object} Link checker object.
|
|
178
181
|
*/
|
|
179
|
-
// eslint-disable-next-line max-lines-per-function
|
|
180
182
|
const createLinkChecker = () => {
|
|
181
183
|
const checkedLinks = new Map();
|
|
182
184
|
|
|
@@ -206,18 +208,17 @@ const createLinkChecker = () => {
|
|
|
206
208
|
return httpResponse.continue;
|
|
207
209
|
}
|
|
208
210
|
|
|
209
|
-
if (
|
|
211
|
+
if (
|
|
212
|
+
context.testSettings.ignoreDuplicates &&
|
|
213
|
+
checkedLinks.has(link)
|
|
214
|
+
) {
|
|
210
215
|
return checkedLinks.get(link);
|
|
211
216
|
}
|
|
212
217
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
status = await checkExternalPageLink(context.page, normalizedLink);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
catch {
|
|
218
|
+
status = await (context.testSettings.checkWithBrowser
|
|
219
|
+
? checkExternalPageLinkBrowser(context.page, normalizedLink)
|
|
220
|
+
: checkExternalPageLink(context.page, normalizedLink));
|
|
221
|
+
} catch {
|
|
221
222
|
status = httpResponse.unknownError;
|
|
222
223
|
}
|
|
223
224
|
|
package/lib/logger.js
CHANGED
|
@@ -15,7 +15,7 @@ const testResultSymbols = Object.freeze({
|
|
|
15
15
|
warning: ' ‼'
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
const nullFunction = () => {
|
|
18
|
+
const nullFunction = () => {};
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Factory function that creates an instance of a
|
|
@@ -29,7 +29,9 @@ const nullFunction = () => { };
|
|
|
29
29
|
module.exports = (config) => {
|
|
30
30
|
const cliReporter = {
|
|
31
31
|
// If cli reporter is enabled, set console log function, otherwise null function
|
|
32
|
-
log: config.reporters.includes(reporterTypes.cli)
|
|
32
|
+
log: config.reporters.includes(reporterTypes.cli)
|
|
33
|
+
? consoleLogger.log
|
|
34
|
+
: nullFunction,
|
|
33
35
|
// The logAlways function provides a mechanism to log to the console even
|
|
34
36
|
// when the cli reporter is disabled (e.g. returning the final results)
|
|
35
37
|
logAlways: consoleLogger.log
|
|
@@ -87,7 +89,9 @@ module.exports = (config) => {
|
|
|
87
89
|
};
|
|
88
90
|
|
|
89
91
|
const outputTestSummary = () => {
|
|
90
|
-
cliReporter.logAlways({
|
|
92
|
+
cliReporter.logAlways({
|
|
93
|
+
message: `\n Tests: ${testResults.summary.tests}\n Passed: ${testResults.summary.passed}\n Warning: ${testResults.summary.warning}\n Failed: ${testResults.summary.failed}\n`
|
|
94
|
+
});
|
|
91
95
|
};
|
|
92
96
|
|
|
93
97
|
/**
|
package/lib/reporter.js
CHANGED
|
@@ -19,8 +19,10 @@ handlebars.registerHelper('json', (context) => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const saveHtmlReport = (results) => {
|
|
22
|
-
const templateFile = path.resolve(
|
|
23
|
-
|
|
22
|
+
const templateFile = path.resolve(
|
|
23
|
+
path.join(__dirname, htmlReportTemplateName)
|
|
24
|
+
);
|
|
25
|
+
const htmlReportTemplate = fs.readFileSync(templateFile, 'utf8');
|
|
24
26
|
const template = handlebars.compile(htmlReportTemplate);
|
|
25
27
|
const htmlReport = template(results);
|
|
26
28
|
fs.writeFileSync(htmlReportFileName, htmlReport);
|
|
@@ -16,14 +16,25 @@ const getDataKey = (instancePath) => {
|
|
|
16
16
|
// Convert pointer to key be splitting by /, removing first value (since pointer
|
|
17
17
|
// starts with /, so empty), unencoding values, and the re-assembling with different
|
|
18
18
|
// formatting for numeric array indices versus properties.
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
return (
|
|
20
|
+
baseKey +
|
|
21
|
+
instancePath
|
|
22
|
+
.split('/')
|
|
23
|
+
.slice(1)
|
|
24
|
+
// eslint-disable-next-line unicorn/no-array-reduce -- reduce for string concatenation
|
|
25
|
+
.reduce((accumulator, currentValue) => {
|
|
26
|
+
const unencodedValue = currentValue
|
|
27
|
+
.replace(/~0/g, '~')
|
|
28
|
+
.replace(/~1/g, '/');
|
|
29
|
+
const encodedValue = Number.isNaN(Number(unencodedValue))
|
|
30
|
+
? `.${unencodedValue}`
|
|
31
|
+
: `[${unencodedValue}]`;
|
|
32
|
+
return `${accumulator}${encodedValue}`;
|
|
33
|
+
}, '')
|
|
34
|
+
);
|
|
24
35
|
};
|
|
25
36
|
|
|
26
|
-
const
|
|
37
|
+
const processErrorParameters = (error) => {
|
|
27
38
|
let formattedMessage = error.message;
|
|
28
39
|
// Ajv includes all allowed values in params.allowedValues,
|
|
29
40
|
// so add to message if available.
|
|
@@ -44,15 +55,20 @@ const processErrorParams = (error) => {
|
|
|
44
55
|
const formatErrors = (errors) => {
|
|
45
56
|
const margin = 2;
|
|
46
57
|
let maxLength = 0;
|
|
47
|
-
|
|
58
|
+
for (const error of errors) {
|
|
48
59
|
error.dataKey = getDataKey(error.instancePath);
|
|
49
|
-
error.formattedMessage =
|
|
60
|
+
error.formattedMessage = processErrorParameters(error);
|
|
50
61
|
// Get max dataKey length for all errors to line up column in final output
|
|
51
62
|
if (error.dataKey.length > maxLength) {
|
|
52
63
|
maxLength = error.dataKey.length;
|
|
53
64
|
}
|
|
54
|
-
}
|
|
55
|
-
return errors.map(
|
|
65
|
+
}
|
|
66
|
+
return errors.map(
|
|
67
|
+
(error) =>
|
|
68
|
+
` ${error.dataKey.padEnd(maxLength + margin)}${red(
|
|
69
|
+
error.formattedMessage
|
|
70
|
+
)}`
|
|
71
|
+
);
|
|
56
72
|
};
|
|
57
73
|
|
|
58
74
|
module.exports.formatErrors = formatErrors;
|
|
@@ -14,7 +14,9 @@ const testResultStates = Object.freeze({
|
|
|
14
14
|
|
|
15
15
|
const getTestSettings = (testSettingProperty, urlSettings) => {
|
|
16
16
|
if (urlSettings[testSettingProperty] === undefined) {
|
|
17
|
-
throw new Error(
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Property '${testSettingProperty}' could not be found in test settings`
|
|
19
|
+
);
|
|
18
20
|
}
|
|
19
21
|
return urlSettings[testSettingProperty];
|
|
20
22
|
};
|
|
@@ -31,19 +33,29 @@ const getTestSettings = (testSettingProperty, urlSettings) => {
|
|
|
31
33
|
* @param {string} testSettingProperty The name of the config property
|
|
32
34
|
* with settings for the current test.
|
|
33
35
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
const pageanTest = async (
|
|
37
|
+
name,
|
|
38
|
+
testFunction,
|
|
39
|
+
testContext,
|
|
40
|
+
testSettingProperty
|
|
41
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- Allow < 10
|
|
42
|
+
) => {
|
|
43
|
+
const testSettings = getTestSettings(
|
|
44
|
+
testSettingProperty,
|
|
45
|
+
testContext.urlSettings
|
|
46
|
+
);
|
|
37
47
|
testContext.testSettings = testSettings;
|
|
38
48
|
if (testSettings.enabled) {
|
|
39
49
|
let results;
|
|
40
50
|
try {
|
|
41
51
|
results = await testFunction(testContext);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
results = { result: testResultStates.failed, data: { error } };
|
|
42
54
|
}
|
|
43
|
-
|
|
44
|
-
results
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
if (
|
|
56
|
+
results.result === testResultStates.failed &&
|
|
57
|
+
testSettings.failWarn
|
|
58
|
+
) {
|
|
47
59
|
results.result = testResultStates.warning;
|
|
48
60
|
}
|
|
49
61
|
testContext.logger.logTestResults({
|