pagean 10.2.0 → 11.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 +132 -135
- package/bin/pagean.js +16 -21
- package/bin/pageanrc-lint.js +9 -9
- package/index.js +41 -19
- package/lib/config.js +29 -19
- package/lib/default-config.json +16 -16
- package/lib/external-file-utils.js +16 -10
- package/lib/link-utils.js +21 -23
- package/lib/logger.js +31 -8
- package/lib/report-template.handlebars +18 -1
- package/lib/reporter.js +8 -7
- package/lib/schema-errors.js +4 -5
- package/lib/sitemap.js +26 -21
- package/lib/test-utils.js +7 -9
- package/lib/tests.js +31 -22
- package/lib/utils.js +45 -0
- package/package.json +17 -15
- package/schemas/pageanrc.schema.json +1 -1
package/README.md
CHANGED
|
@@ -45,79 +45,96 @@ a headless Chrome browser. The URLs defined in the configuration file are each
|
|
|
45
45
|
loaded once, and after page load the applicable tests are executed. Test
|
|
46
46
|
results are `passed` or `failed`, but can be configured to report `warning`
|
|
47
47
|
instead of failure. Only a `failed` test causes the test process to fail and
|
|
48
|
-
exit with an error code (a `warning`
|
|
48
|
+
exit with an error code (a `warning` does not). If a page URL fails to load,
|
|
49
|
+
it is retried up to two additional times and if unsuccessful the URL is
|
|
50
|
+
logged as a `page error` with the error message.
|
|
49
51
|
|
|
50
|
-
###
|
|
52
|
+
### Broken link test
|
|
51
53
|
|
|
52
|
-
The
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
The broken link test checks for broken links on the page. It checks any `<a>`
|
|
55
|
+
tag on the page with `href` pointing to another location on the current page or
|
|
56
|
+
another page (that is, only `http(s)` or `file` protocols).
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
- For links within the page, this test checks for existence of the element on
|
|
59
|
+
the page, passing if the element exists and failing otherwise (and passing
|
|
60
|
+
for cases that are always valid, for example `#` or `#top` for the current
|
|
61
|
+
page). It doesn't check the visibility of the element. Failing tests return a
|
|
62
|
+
response of "#element Not Found" (where `#element` identifies the specific
|
|
63
|
+
element).
|
|
64
|
+
- For links to other pages, the test tries to most efficiently confirm whether
|
|
65
|
+
the target link is valid. It first makes a `HEAD` request for that URL and
|
|
66
|
+
checks the response. If an erroneous response is returned (>= 400 with no
|
|
67
|
+
execution error) and not code 429 (Too Many Requests), the request is retried
|
|
68
|
+
with a `GET` request. The test passes for HTTP responses < 400 and fails
|
|
69
|
+
otherwise (if HTTP response is >= 400 or another error occurs).
|
|
70
|
+
- This can result in false failure indications, specifically for `file:`
|
|
71
|
+
links (`404` or `ECONNREFUSED`) or where the browser passes a domain
|
|
72
|
+
identity with the request (page loads when tested, but `401` response for
|
|
73
|
+
links to that page). For these cases, or other false failures, the test
|
|
74
|
+
configuration allows a Boolean `checkWithBrowser` option that instead
|
|
75
|
+
checks links by loading the target in the browser (via `puppeteer`). Note
|
|
76
|
+
this can increase test execution time, in some cases substantially, due to
|
|
77
|
+
the time to open a new browser tab and plus load the page and all assets.
|
|
78
|
+
- Note that `file:` links can only be tested with the `checkWithBrowser`
|
|
79
|
+
option.
|
|
80
|
+
- If the link to another page includes a hash it's removed prior to checking.
|
|
81
|
+
The test in this case is confirming a valid link, not that the element
|
|
82
|
+
exists, which is only done for the current page.
|
|
83
|
+
- The test configuration allows an `ignoredLinks` array listing link URLs to
|
|
84
|
+
ignore for this test. Note this only applies to links to other pages, not
|
|
85
|
+
links within the page, which are always checked.
|
|
86
|
+
- To optimize performance, link test results are cached and those links aren't
|
|
87
|
+
re-tested for the entire test run (across all tested URLs). The test
|
|
88
|
+
configuration allows a Boolean `ignoreDuplicates` option that can be set to
|
|
89
|
+
`false` to bypass this behavior and re-test all links. The results for any
|
|
90
|
+
failed links are included in the reports in any case.
|
|
57
91
|
|
|
58
|
-
|
|
59
|
-
|
|
92
|
+
For any failing test, the `data` array in the test report includes the original
|
|
93
|
+
URL and the response code or error as shown below.
|
|
60
94
|
|
|
61
95
|
```json
|
|
62
96
|
[
|
|
63
97
|
{
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
98
|
+
"href": "https://about.gitlab.com/not-found",
|
|
99
|
+
"status": 404
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"href": "http://localhost:3000/brokenLinks.html#notlinked",
|
|
103
|
+
"status": "#notlinked Not Found"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"href": "https://this.url.does.not.exist/",
|
|
107
|
+
"status": "ENOTFOUND"
|
|
69
108
|
}
|
|
70
109
|
]
|
|
71
110
|
```
|
|
72
111
|
|
|
112
|
+
Note: this test checks all links on the page, and doesn't respect mechanisms
|
|
113
|
+
intended to limit web crawlers such as `robots.txt` or `noindex` tags.
|
|
114
|
+
|
|
73
115
|
### Console error test
|
|
74
116
|
|
|
75
117
|
The console error test fails if any error is written to the browser console,
|
|
76
|
-
but is otherwise
|
|
77
|
-
for testing for console errors, but allowing any other console output.
|
|
118
|
+
but is otherwise simply a subset of the console output test. This separation
|
|
119
|
+
allows for testing for console errors, but allowing any other console output.
|
|
78
120
|
|
|
79
|
-
###
|
|
121
|
+
### Console output test
|
|
80
122
|
|
|
81
|
-
The
|
|
82
|
-
|
|
83
|
-
HTML is returned and checked with
|
|
84
|
-
[HTML Hint](https://www.npmjs.com/package/htmlhint) and the test fails if any
|
|
85
|
-
issues are found. An array is included in the report with all HTML Hint issues,
|
|
86
|
-
as shown below:
|
|
123
|
+
The console output test fails if any output is written to the browser console.
|
|
124
|
+
An array is included in the report with all entries, as shown below:
|
|
87
125
|
|
|
88
126
|
```json
|
|
89
127
|
[
|
|
90
128
|
{
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"rule": {
|
|
97
|
-
"description": "The value of id attributes must be unique.",
|
|
98
|
-
"id": "id-unique",
|
|
99
|
-
"link": "https://github.com/thedaviddias/HTMLHint/wiki/id-unique"
|
|
100
|
-
},
|
|
101
|
-
"type": "error"
|
|
129
|
+
"type": "error",
|
|
130
|
+
"text": "Failed to load resource: net::ERR_NAME_NOT_RESOLVED",
|
|
131
|
+
"location": {
|
|
132
|
+
"url": "https://this.url.does.not.exist/file.js"
|
|
133
|
+
}
|
|
102
134
|
}
|
|
103
135
|
]
|
|
104
136
|
```
|
|
105
137
|
|
|
106
|
-
An htmlhintrc file can be specified in the configuration file, otherwise the
|
|
107
|
-
default "./.htmlhintrc" file is used (if it exists). See the Configuration
|
|
108
|
-
section below.
|
|
109
|
-
|
|
110
|
-
Note: this test may not find some errors in the original HTML that are
|
|
111
|
-
removed/resolved as the page is parsed (for example closing tags with no
|
|
112
|
-
opening tags).
|
|
113
|
-
|
|
114
|
-
### Page load time test
|
|
115
|
-
|
|
116
|
-
The page load time test fails if the page load time (from start through the
|
|
117
|
-
`load` event) exceeds the defined threshold in the configuration file (or the
|
|
118
|
-
default of 2 seconds). The actual load time is included in the report. Tests
|
|
119
|
-
time out at twice the page load time threshold.
|
|
120
|
-
|
|
121
138
|
### External script test
|
|
122
139
|
|
|
123
140
|
The external script test is intended to identify any externally loaded
|
|
@@ -157,68 +174,53 @@ saved filename or applicable error, as shown below.
|
|
|
157
174
|
Each external script is saved only once, but is reported on any page where it's
|
|
158
175
|
referenced.
|
|
159
176
|
|
|
160
|
-
###
|
|
177
|
+
### Horizontal scrollbar test
|
|
161
178
|
|
|
162
|
-
The
|
|
163
|
-
|
|
164
|
-
|
|
179
|
+
The horizontal scrollbar test fails if the rendered page has a horizontal
|
|
180
|
+
scrollbar. If a specific browser viewport size is desired for this test, that
|
|
181
|
+
can be configured in the `puppeteerLaunchOptions`.
|
|
165
182
|
|
|
166
|
-
|
|
167
|
-
the page, passing if the element exists and failing otherwise (and passing
|
|
168
|
-
for cases that are always valid, for example `#` or `#top` for the current
|
|
169
|
-
page). It doesn't check the visibility of the element. Failing tests return a
|
|
170
|
-
response of "#element Not Found" (where `#element` identifies the specific
|
|
171
|
-
element).
|
|
172
|
-
- For links to other pages, the test tries to most efficiently confirm whether
|
|
173
|
-
the target link is valid. It first makes a `HEAD` request for that URL and
|
|
174
|
-
checks the response. If an erroneous response is returned (>= 400 with no
|
|
175
|
-
execution error) and not code 429 (Too Many Requests), the request is retried
|
|
176
|
-
with a `GET` request. The test passes for HTTP responses < 400 and fails
|
|
177
|
-
otherwise (if HTTP response is >= 400 or another error occurs).
|
|
178
|
-
- This can result in false failure indications, specifically for `file:`
|
|
179
|
-
links (`404` or `ECONNREFUSED`) or where the browser passes a domain
|
|
180
|
-
identity with the request (page loads when tested, but `401` response for
|
|
181
|
-
links to that page). For these cases, or other false failures, the test
|
|
182
|
-
configuration allows a Boolean `checkWithBrowser` option that instead
|
|
183
|
-
checks links by loading the target in the browser (via `puppeteer`). Note
|
|
184
|
-
this can increase test execution time, in some cases substantially, due to
|
|
185
|
-
the time to open a new browser tab and plus load the page and all assets.
|
|
186
|
-
- Note that `file:` links can only be tested with the `checkWithBrowser`
|
|
187
|
-
option.
|
|
188
|
-
- If the link to another page includes a hash it's removed prior to checking.
|
|
189
|
-
The test in this case is confirming a valid link, not that the element
|
|
190
|
-
exists, which is only done for the current page.
|
|
191
|
-
- The test configuration allows an `ignoredLinks` array listing link URLs to
|
|
192
|
-
ignore for this test. Note this only applies to links to other pages, not
|
|
193
|
-
links within the page, which are always checked.
|
|
194
|
-
- To optimize performance, link test results are cached and those links aren't
|
|
195
|
-
re-tested for the entire test run (across all tested URLs). The test
|
|
196
|
-
configuration allows a Boolean `ignoreDuplicates` option that can be set to
|
|
197
|
-
`false` to bypass this behavior and re-test all links. The results for any
|
|
198
|
-
failed links are included in the reports in any case.
|
|
183
|
+
### Page load time test
|
|
199
184
|
|
|
200
|
-
|
|
201
|
-
|
|
185
|
+
The page load time test fails if the page load time (from start through the
|
|
186
|
+
`load` event) exceeds the defined threshold in the configuration file (or the
|
|
187
|
+
default of 2 seconds). The actual load time is included in the report. Tests
|
|
188
|
+
time out at twice the page load time threshold.
|
|
189
|
+
|
|
190
|
+
### Rendered HTML test
|
|
191
|
+
|
|
192
|
+
The rendered HTML test is intended for cases where content is dynamically
|
|
193
|
+
created prior to page load (that is, the `load` event firing). The rendered
|
|
194
|
+
HTML is returned and checked with
|
|
195
|
+
[HTML Hint](https://www.npmjs.com/package/htmlhint) and the test fails if any
|
|
196
|
+
issues are found. An array is included in the report with all HTML Hint issues,
|
|
197
|
+
as shown below:
|
|
202
198
|
|
|
203
199
|
```json
|
|
204
200
|
[
|
|
205
201
|
{
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
202
|
+
"col": 9,
|
|
203
|
+
"evidence": " <div id=\"div1\"></div>",
|
|
204
|
+
"line": 6,
|
|
205
|
+
"message": "The id value [ div1 ] must be unique.",
|
|
206
|
+
"raw": " id=\"div1\"",
|
|
207
|
+
"rule": {
|
|
208
|
+
"description": "The value of id attributes must be unique.",
|
|
209
|
+
"id": "id-unique",
|
|
210
|
+
"link": "https://github.com/thedaviddias/HTMLHint/wiki/id-unique"
|
|
211
|
+
},
|
|
212
|
+
"type": "error"
|
|
216
213
|
}
|
|
217
214
|
]
|
|
218
215
|
```
|
|
219
216
|
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
An htmlhintrc file can be specified in the configuration file, otherwise the
|
|
218
|
+
default "./.htmlhintrc" file is used (if it exists). See the Configuration
|
|
219
|
+
section below.
|
|
220
|
+
|
|
221
|
+
Note: this test may not find some errors in the original HTML that are
|
|
222
|
+
removed/resolved as the page is parsed (for example closing tags with no
|
|
223
|
+
opening tags).
|
|
222
224
|
|
|
223
225
|
## Reports
|
|
224
226
|
|
|
@@ -227,14 +229,15 @@ console and saved in two reports in the project root directory (any or all of
|
|
|
227
229
|
the three):
|
|
228
230
|
|
|
229
231
|
- A JSON report named
|
|
230
|
-
[`pagean-results.json`](https://gitlab-ci-utils.gitlab.io/pagean/pagean-results.json)
|
|
232
|
+
[`pagean-results.json`](https://gitlab-ci-utils.gitlab.io/pagean/pagean-results.json).
|
|
231
233
|
- An HTML report named
|
|
232
|
-
[`pagean-results.html`](https://gitlab-ci-utils.gitlab.io/pagean/pagean-results.html)
|
|
234
|
+
[`pagean-results.html`](https://gitlab-ci-utils.gitlab.io/pagean/pagean-results.html).
|
|
233
235
|
|
|
234
236
|
Both reports contain:
|
|
235
237
|
|
|
236
|
-
- The time of test execution
|
|
237
|
-
- A summary of the total tests and results (passed, warning, failed
|
|
238
|
+
- The time of test execution.
|
|
239
|
+
- A summary of the total tests and results (passed, warning, failed, and page
|
|
240
|
+
errors).
|
|
238
241
|
- The detailed test results, including the URL tested, list of tests performed
|
|
239
242
|
on that URL with results, and, if applicable, any relevant data associated
|
|
240
243
|
with the test failure (for example the console errors if the console error
|
|
@@ -256,12 +259,11 @@ Below is an example `.pageanrc.json` file, which is broken into seven major
|
|
|
256
259
|
properties:
|
|
257
260
|
|
|
258
261
|
- `htmlhintrc`: An optional path to an htmlhintrc file to be used in the
|
|
259
|
-
rendered HTML test
|
|
262
|
+
rendered HTML test.
|
|
260
263
|
- `project`: An optional name of the project, which is included in HTML and
|
|
261
264
|
JSON reports.
|
|
262
265
|
- `puppeteerLaunchOptions`: An optional set of options to pass to Puppeteer on
|
|
263
|
-
launch.
|
|
264
|
-
can be found at
|
|
266
|
+
launch. The complete list of available options can be found at
|
|
265
267
|
https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions.
|
|
266
268
|
- `reporters`: An optional array of reporters indicating the test reports that
|
|
267
269
|
should be provided. There are three possible options - `cli`, `html`, and
|
|
@@ -302,8 +304,6 @@ is equivalent to the longhand:
|
|
|
302
304
|
}
|
|
303
305
|
```
|
|
304
306
|
|
|
305
|
-
All available settings with the default values are shown below.
|
|
306
|
-
|
|
307
307
|
- `sitemap`: Specify a sitemap with URLs to test. If a sitemap is specified,
|
|
308
308
|
the URLs from the sitemap are added to the `urls` array. If a URL is in the
|
|
309
309
|
`urls` array with `settings`, those settings are retained. Note that
|
|
@@ -327,14 +327,23 @@ All available settings with the default values are shown below.
|
|
|
327
327
|
testing that URL. The `url` string can be either an actual URL or a local
|
|
328
328
|
file, as shown in the example below.
|
|
329
329
|
|
|
330
|
+
The following shows all available settings, except `sitemap`, with the default
|
|
331
|
+
values.
|
|
332
|
+
|
|
330
333
|
```json
|
|
331
334
|
{
|
|
332
335
|
"puppeteerLaunchOptions": {
|
|
333
|
-
"
|
|
336
|
+
"headless": "new"
|
|
334
337
|
},
|
|
335
338
|
"reporters": ["cli", "html", "json"],
|
|
336
339
|
"settings": {
|
|
337
|
-
"
|
|
340
|
+
"brokenLinkTest": {
|
|
341
|
+
"enabled": true,
|
|
342
|
+
"failWarn": false,
|
|
343
|
+
"checkWithBrowser": false,
|
|
344
|
+
"ignoreDuplicates": true
|
|
345
|
+
},
|
|
346
|
+
"consoleErrorTest": {
|
|
338
347
|
"enabled": true,
|
|
339
348
|
"failWarn": false
|
|
340
349
|
},
|
|
@@ -342,11 +351,11 @@ All available settings with the default values are shown below.
|
|
|
342
351
|
"enabled": true,
|
|
343
352
|
"failWarn": false
|
|
344
353
|
},
|
|
345
|
-
"
|
|
354
|
+
"externalScriptTest": {
|
|
346
355
|
"enabled": true,
|
|
347
|
-
"failWarn":
|
|
356
|
+
"failWarn": true
|
|
348
357
|
},
|
|
349
|
-
"
|
|
358
|
+
"horizontalScrollbarTest": {
|
|
350
359
|
"enabled": true,
|
|
351
360
|
"failWarn": false
|
|
352
361
|
},
|
|
@@ -355,35 +364,23 @@ All available settings with the default values are shown below.
|
|
|
355
364
|
"failWarn": false,
|
|
356
365
|
"pageLoadTimeThreshold": 2
|
|
357
366
|
},
|
|
358
|
-
"
|
|
359
|
-
"enabled": true,
|
|
360
|
-
"failWarn": true
|
|
361
|
-
},
|
|
362
|
-
"brokenLinkTest": {
|
|
367
|
+
"renderedHtmlTest": {
|
|
363
368
|
"enabled": true,
|
|
364
|
-
"failWarn": false
|
|
365
|
-
"checkWithBrowser": false,
|
|
366
|
-
"ignoreDuplicates": true,
|
|
367
|
-
"ignoredLinks": []
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
"urls": [
|
|
371
|
-
"https://gitlab.com/gitlab-ci-utils/pagean/",
|
|
372
|
-
{
|
|
373
|
-
"url": "./tests/fixtures/site/consoleLog.html",
|
|
374
|
-
"settings": {
|
|
375
|
-
"consoleOutputTest": false
|
|
376
|
-
}
|
|
369
|
+
"failWarn": false
|
|
377
370
|
}
|
|
378
|
-
|
|
371
|
+
}
|
|
379
372
|
}
|
|
380
373
|
```
|
|
381
374
|
|
|
375
|
+
Numerous example config files used in the tests can be found
|
|
376
|
+
[here](tests/fixtures/configs/).
|
|
377
|
+
|
|
382
378
|
## Container images
|
|
383
379
|
|
|
384
380
|
Provided with the Pagean project are container images configured to run the
|
|
385
|
-
tests. All available image tags can be found in the
|
|
386
|
-
|
|
381
|
+
tests. All available image tags can be found in the
|
|
382
|
+
`registry.gitlab.com/gitlab-ci-utils/pagean` repository
|
|
383
|
+
[here](https://gitlab.com/gitlab-ci-utils/pagean/container_registry).
|
|
387
384
|
Details on each release can be found on the
|
|
388
385
|
[Releases](https://gitlab.com/gitlab-ci-utils/pagean/releases) page.
|
|
389
386
|
|
|
@@ -419,7 +416,7 @@ pagean:
|
|
|
419
416
|
- pagean-external-scripts/
|
|
420
417
|
```
|
|
421
418
|
|
|
422
|
-
### Testing with static HTTP server
|
|
419
|
+
### Testing with a static HTTP server
|
|
423
420
|
|
|
424
421
|
The container image shown previously includes
|
|
425
422
|
[`serve`](https://www.npmjs.com/package/serve) and
|
package/bin/pagean.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import { Levels, log } from 'ci-logger';
|
|
4
|
+
import { program } from 'commander';
|
|
5
|
+
|
|
6
|
+
import { executeAllTests } from '../index.js';
|
|
7
|
+
import getConfig from '../lib/config.js';
|
|
8
|
+
import { pkg } from '../lib/utils.js';
|
|
9
9
|
|
|
10
10
|
const defaultConfigFileName = './.pageanrc.json';
|
|
11
11
|
|
|
@@ -19,19 +19,14 @@ program
|
|
|
19
19
|
.parse(process.argv);
|
|
20
20
|
const options = program.opts();
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
log({
|
|
32
|
-
errorCode: 1,
|
|
33
|
-
exitOnError: true,
|
|
34
|
-
level: Levels.Error,
|
|
35
|
-
message: `Error executing pagean tests\n${error.message}`
|
|
36
|
-
});
|
|
22
|
+
try {
|
|
23
|
+
const config = await getConfig(options.config);
|
|
24
|
+
executeAllTests(config);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
log({
|
|
27
|
+
errorCode: 1,
|
|
28
|
+
exitOnError: true,
|
|
29
|
+
level: Levels.Error,
|
|
30
|
+
message: `Error executing pagean tests\n${error.message}`
|
|
37
31
|
});
|
|
32
|
+
}
|
package/bin/pageanrc-lint.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
import { Levels, log } from 'ci-logger';
|
|
4
|
+
import kleur from 'kleur';
|
|
5
|
+
import { program } from 'commander';
|
|
6
|
+
|
|
7
|
+
import { formatErrors } from '../lib/schema-errors.js';
|
|
8
|
+
import { lintConfigFile } from '../lib/config.js';
|
|
9
|
+
import { pkg } from '../lib/utils.js';
|
|
10
10
|
|
|
11
11
|
const defaultConfigFileName = './.pageanrc.json';
|
|
12
12
|
|
|
@@ -34,9 +34,9 @@ const outputJsonResults = (configFileName, lintResults) => {
|
|
|
34
34
|
|
|
35
35
|
const outputConsoleResults = (configFileName, lintResults) => {
|
|
36
36
|
if (lintResults.isValid) {
|
|
37
|
-
log({ message: `\n${configFileName}: ${green('valid')}\n` });
|
|
37
|
+
log({ message: `\n${configFileName}: ${kleur.green('valid')}\n` });
|
|
38
38
|
} else {
|
|
39
|
-
logError(`\n${underline(configFileName)}`, false);
|
|
39
|
+
logError(`\n${kleur.underline(configFileName)}`, false);
|
|
40
40
|
for (const error of formatErrors(lintResults.errors)) {
|
|
41
41
|
logError(error, false);
|
|
42
42
|
}
|
package/index.js
CHANGED
|
@@ -1,38 +1,43 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Pagean test framework.
|
|
5
3
|
*
|
|
6
4
|
* @module pagean
|
|
7
5
|
*/
|
|
8
|
-
const puppeteer = require('puppeteer');
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
import puppeteer from 'puppeteer';
|
|
8
|
+
|
|
9
|
+
import * as testFunctions from './lib/tests.js';
|
|
10
|
+
import { createLinkChecker } from './lib/link-utils.js';
|
|
11
|
+
import { saveReports } from './lib/reporter.js';
|
|
12
|
+
import testLogger from './lib/logger.js';
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* @typedef {object} PageOptions
|
|
17
16
|
* @property {number} retryCount - The number of times to retry navigation.
|
|
18
17
|
* @property {number} timeout - The timeout for navigation.
|
|
19
18
|
*/
|
|
19
|
+
|
|
20
|
+
/** @type {PageOptions} */
|
|
20
21
|
const defaultPageOptions = {
|
|
21
22
|
retryCount: 2,
|
|
22
23
|
timeout: 60_000
|
|
23
24
|
};
|
|
24
25
|
|
|
26
|
+
/** @typedef {import('puppeteer').Page} Page */
|
|
27
|
+
|
|
25
28
|
/**
|
|
26
29
|
* Opens the specified URL in the given page, with retry logic.
|
|
27
30
|
*
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
30
|
-
* @param
|
|
31
|
+
* @param {Page} page The puppeteer page object.
|
|
32
|
+
* @param {string} url The URL to navigate to.
|
|
33
|
+
* @param {PageOptions} options The options for navigating to the URL.
|
|
34
|
+
* @throws {Error} If the navigation fails.
|
|
31
35
|
* @static
|
|
32
36
|
* @private
|
|
33
37
|
*/
|
|
34
38
|
const gotoPage = async (page, url, options) => {
|
|
35
39
|
let retryCount = 0;
|
|
40
|
+
let lastError;
|
|
36
41
|
while (retryCount < options.retryCount) {
|
|
37
42
|
try {
|
|
38
43
|
/* eslint-disable no-await-in-loop -- loop for retry only */
|
|
@@ -44,24 +49,33 @@ const gotoPage = async (page, url, options) => {
|
|
|
44
49
|
});
|
|
45
50
|
/* eslint-enable no-await-in-loop -- loop for retry only */
|
|
46
51
|
break;
|
|
47
|
-
} catch {
|
|
52
|
+
} catch (error) {
|
|
53
|
+
lastError = error;
|
|
48
54
|
retryCount++;
|
|
49
|
-
console.error(
|
|
50
|
-
`Failed to navigate to ${url}. Retrying (${retryCount}/${options.retryCount})...`
|
|
51
|
-
);
|
|
52
55
|
}
|
|
53
56
|
}
|
|
57
|
+
|
|
58
|
+
// Normalize URLs for comparison, prevents cases like trailing slashes
|
|
59
|
+
// from causing false negatives.
|
|
60
|
+
const desiredUrl = new URL(url);
|
|
61
|
+
const currentUrl = new URL(page.url());
|
|
62
|
+
if (currentUrl.href !== desiredUrl.href) {
|
|
63
|
+
throw lastError;
|
|
64
|
+
}
|
|
54
65
|
};
|
|
55
66
|
|
|
67
|
+
/** @typedef {import('./lib/config.js').PageanConfig} PageanConfig */
|
|
68
|
+
|
|
56
69
|
/* eslint-disable no-await-in-loop, max-lines-per-function --
|
|
57
70
|
no-await-in-loop - tests are deliberately performed synchronously,
|
|
58
71
|
max-lines-per-function - allowed to test executor */
|
|
59
72
|
/**
|
|
60
73
|
* Executes Pagean tests as specified in config and reports results.
|
|
61
74
|
*
|
|
62
|
-
* @param {
|
|
75
|
+
* @param {PageanConfig} config The Pagean test configuration.
|
|
63
76
|
* @static
|
|
64
77
|
*/
|
|
78
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- Allow < 10
|
|
65
79
|
const executeAllTests = async (config) => {
|
|
66
80
|
const logger = testLogger(config);
|
|
67
81
|
const linkChecker = createLinkChecker();
|
|
@@ -79,7 +93,15 @@ const executeAllTests = async (config) => {
|
|
|
79
93
|
type: message.type()
|
|
80
94
|
})
|
|
81
95
|
);
|
|
82
|
-
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await gotoPage(page, testUrl.url, defaultPageOptions);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
logger.logPageError(error.message);
|
|
101
|
+
/* eslint-disable-next-line no-continue -- tests should not be
|
|
102
|
+
executed if navigation fails */
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
83
105
|
|
|
84
106
|
const testContext = {
|
|
85
107
|
consoleLog,
|
|
@@ -99,9 +121,9 @@ const executeAllTests = async (config) => {
|
|
|
99
121
|
}
|
|
100
122
|
await browser.close();
|
|
101
123
|
const testResults = logger.getTestResults();
|
|
102
|
-
|
|
124
|
+
saveReports(testResults, config.reporters);
|
|
103
125
|
|
|
104
|
-
if (testResults.summary.failed > 0) {
|
|
126
|
+
if (testResults.summary.failed > 0 || testResults.summary.pageError > 0) {
|
|
105
127
|
// For test harness want process to exit with error code
|
|
106
128
|
// eslint-disable-next-line unicorn/no-process-exit, no-magic-numbers -- exit code
|
|
107
129
|
process.exit(2);
|
|
@@ -109,4 +131,4 @@ const executeAllTests = async (config) => {
|
|
|
109
131
|
};
|
|
110
132
|
/* eslint-enable no-await-in-loop, max-lines-per-function -- enable */
|
|
111
133
|
|
|
112
|
-
|
|
134
|
+
export { executeAllTests };
|