pagean 6.0.9 → 8.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 CHANGED
@@ -44,13 +44,11 @@ The console output test fails if any output is written to the browser console. A
44
44
  ```json
45
45
  [
46
46
  {
47
- "_args": [],
48
- "_location": {
49
- "lineNumber": undefined,
47
+ "type": "error",
48
+ "text": "Failed to load resource: net::ERR_NAME_NOT_RESOLVED",
49
+ "location": {
50
50
  "url": "https://this.url.does.not.exist/file.js"
51
- },
52
- "_text": "Failed to load resource: net::ERR_NAME_NOT_RESOLVED",
53
- "_type": "error"
51
+ }
54
52
  }
55
53
  ]
56
54
  ```
@@ -284,8 +282,10 @@ pagean:
284
282
  stage: test
285
283
  before_script:
286
284
  # Start static server in test cases directory, discarding any console output,
287
- # and wait until the server is running
288
- - http-server ./tests/test-cases > /dev/null 2>&1 & wait-on http://localhost:8080
285
+ # and wait until the server is running. Have wait-on check by IP based on DNS
286
+ # change in Node 17 and issues with it resolving `localhost`. Pagean is able
287
+ # to resolve localhost with no issue, see example in static-server.pageanrc.json.
288
+ - http-server ./tests/test-cases > /dev/null 2>&1 & wait-on http://127.0.0.1:8080
289
289
  script:
290
290
  - pagean -c static-server.pageanrc.json
291
291
  artifacts:
package/bin/pagean.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- const { log, levels } = require('ci-logger');
4
+ const { log, Levels } = require('ci-logger');
5
5
  const program = require('commander');
6
6
  const pagean = require('../index');
7
7
  const getConfig = require('../lib/config');
@@ -25,7 +25,7 @@ try {
25
25
  } catch (error) {
26
26
  log({
27
27
  message: `Error executing pagean tests\n${error.message}`,
28
- level: levels.error,
28
+ level: Levels.Error,
29
29
  exitOnError: true,
30
30
  errorCode: 1
31
31
  });
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- const { log, levels } = require('ci-logger');
4
+ const { log, Levels } = require('ci-logger');
5
5
  const program = require('commander');
6
6
  const { green, underline } = require('kleur');
7
7
  const { lintConfigFile } = require('../lib/config');
@@ -19,7 +19,7 @@ program
19
19
  const options = program.opts();
20
20
 
21
21
  const logError = (message, exitOnError = true) => {
22
- log({ message, level: levels.error, exitOnError, errorCode: 1 });
22
+ log({ message, level: Levels.Error, exitOnError, errorCode: 1 });
23
23
  };
24
24
 
25
25
  const outputJsonResults = (configFileName, lintResults) => {
package/index.js CHANGED
@@ -15,8 +15,8 @@ const { createLinkChecker } = require('./lib/link-utils');
15
15
  /**
16
16
  * Executes Pagean tests as specified in config and reports results.
17
17
  *
18
- * @static
19
18
  * @param {object} config The Pagean test configuration.
19
+ * @static
20
20
  */
21
21
  // eslint-disable-next-line max-lines-per-function
22
22
  const executeAllTests = async (config) => {
@@ -29,15 +29,11 @@ const executeAllTests = async (config) => {
29
29
 
30
30
  const consoleLog = [];
31
31
  const page = await browser.newPage();
32
- // Object property names defined by puppeteer API
33
32
  page.on('console', (message) =>
34
33
  consoleLog.push({
35
- // eslint-disable-next-line no-underscore-dangle
36
- _type: message._type,
37
- // eslint-disable-next-line no-underscore-dangle
38
- _text: message._text,
39
- // eslint-disable-next-line no-underscore-dangle
40
- _stackTraceLocations: message._stackTraceLocations
34
+ type: message.type(),
35
+ text: message.text(),
36
+ location: message.location()
41
37
  })
42
38
  );
43
39
  await page.goto(testUrl.url, { waitUntil: 'load' });
package/lib/config.js CHANGED
@@ -51,8 +51,8 @@ const consolidateTestSettings = (
51
51
  globalSettings,
52
52
  urlSettings
53
53
  ) => {
54
- const sanitizedGlobalSettings = globalSettings ? globalSettings : {};
55
- const sanitizedUrlSettings = urlSettings ? urlSettings : {};
54
+ const sanitizedGlobalSettings = globalSettings || {};
55
+ const sanitizedUrlSettings = urlSettings || {};
56
56
  const processedSettings = {};
57
57
  for (const key of Object.keys(defaultSettings)) {
58
58
  processedSettings[key] = {
@@ -114,9 +114,10 @@ const getConfigFromFile = (configFileName) => {
114
114
  * Loads config from file and returns consolidated config with
115
115
  * defaults where values are not specified.
116
116
  *
117
+ * @param {string} configFileName Pagean configuration file name.
118
+ * @returns {object} Consolidated Pagean configuration.
119
+ * @throws {TypeError} Throws if config file has an invalid schema.
117
120
  * @static
118
- * @param {string} configFileName Pagean configuration file name.
119
- * @returns {object} Consolidated Pagean configuration.
120
121
  */
121
122
  const processConfig = (configFileName) => {
122
123
  const config = getConfigFromFile(configFileName);
@@ -133,16 +134,16 @@ const processConfig = (configFileName) => {
133
134
  htmlHintConfig: getHtmlHintConfig(
134
135
  config.htmlhintrc || defaultHtmlHintConfigFilename
135
136
  ),
136
- reporters: config.reporters ? config.reporters : defaultConfig.reporters
137
+ reporters: config.reporters || defaultConfig.reporters
137
138
  };
138
139
  };
139
140
 
140
141
  /**
141
142
  * Lints the configuration file schema.
142
143
  *
143
- * @static
144
144
  * @param {string} configFileName Pagean configuration file name.
145
145
  * @returns {boolean} True if file has valid Pagean config schema.
146
+ * @static
146
147
  */
147
148
  const lintConfigFile = (configFileName) => {
148
149
  const config = getConfigFromFile(configFileName);
@@ -15,10 +15,10 @@ const externalFilePath = 'pagean-external-scripts';
15
15
  /**
16
16
  * Checks if the JavaScript is external to the page and should be saved.
17
17
  *
18
- * @static
19
18
  * @param {string} script The URL of the JavaScript file.
20
19
  * @param {string} page The URL of the current page.
21
20
  * @returns {boolean} True if the script is external to the page.
21
+ * @static
22
22
  */
23
23
  const shouldSaveFile = (script, page) => {
24
24
  const scriptUrl = new URL(script);
@@ -30,10 +30,10 @@ const shouldSaveFile = (script, page) => {
30
30
  * Loads the JavaScript file from the specified URL and
31
31
  * saves it to disc.
32
32
  *
33
- * @static
34
33
  * @param {string} script The URL of the JavaScript file.
35
34
  * @returns {object} An object with original script
36
35
  * URL and local file name.
36
+ * @static
37
37
  */
38
38
  const saveExternalScript = async (script) => {
39
39
  const result = { url: script };
package/lib/link-utils.js CHANGED
@@ -16,9 +16,9 @@ const timeoutSeconds = 120;
16
16
  /**
17
17
  * Enum for HTTP responses.
18
18
  *
19
- * @public
20
19
  * @readonly
21
20
  * @enum {number}
21
+ * @public
22
22
  */
23
23
  const httpResponse = Object.freeze({
24
24
  continue: 100,
@@ -31,19 +31,18 @@ const httpResponse = Object.freeze({
31
31
 
32
32
  const noRetryResponses = new Set([httpResponse.tooManyRequests]);
33
33
 
34
- // eslint-disable-next-line jsdoc/require-description-complete-sentence
35
34
  /**
36
- * Normalizes a URL with https://www.npmjs.com/package/normalize-url
37
- * using defaults plus the following overrides:
38
- * 1. Set default protocol to https if protocol-relative
39
- * 2. Do not remove any querystring parameters
40
- * 3. Strip hash from URL
41
- * 4. Do not strip "www." from the URL
35
+ * Normalizes a URL (with https://www.npmjs.com/package/normalize-url).
36
+ * Uses defaults plus the following overrides.
37
+ * 1. Set default protocol to https if protocol-relative.
38
+ * 2. Do not remove any querystring parameters.
39
+ * 3. Strip hash from URL.
40
+ * 4. Do not strip "www." from the URL.
42
41
  *
43
- * @public
42
+ * @param {string} url The URL to normalize.
43
+ * @returns {string} The normalized URL.
44
44
  * @static
45
- * @param {string} url The URL to normalize.
46
- * @returns {string} The normalized URL.
45
+ * @public
47
46
  */
48
47
  const normalizeLink = (url) =>
49
48
  normalizeUrl(url, {
@@ -52,16 +51,17 @@ const normalizeLink = (url) =>
52
51
  stripHash: true,
53
52
  stripWWW: false
54
53
  });
54
+ /* eslint-enable jsdoc/require-description-complete-sentence */
55
55
 
56
56
  /**
57
57
  * Checks settings to determine if the provided link should be ignored.
58
58
  *
59
- * @private
59
+ * @param {object} settings Test settings object, which may contain an
60
+ * ignoredLinks array.
61
+ * @param {string} link The link to check against the ignore list.
62
+ * @returns {boolean} True if the link should be ignored, otherwise false.
60
63
  * @static
61
- * @param {object} settings Test settings object, which may contain an
62
- * ignoredLinks array.
63
- * @param {string} link The link to check against the ignore list.
64
- * @returns {boolean} True if the link should be ignored, otherwise false.
64
+ * @private
65
65
  */
66
66
  const ignoreLink = (settings, link) =>
67
67
  settings.ignoredLinks && settings.ignoredLinks.includes(link);
@@ -70,10 +70,10 @@ const ignoreLink = (settings, link) =>
70
70
  * Checks a response to an HTTP request, either a response code or explicit error,
71
71
  * to identify any failed responses.
72
72
  *
73
- * @public
74
- * @static
75
73
  * @param {(string|number)} response The response to an HTTP request to check for failure.
76
74
  * @returns {boolean} True if failed, otherwise false.
75
+ * @static
76
+ * @public
77
77
  */
78
78
  const isFailedResponse = (response) =>
79
79
  Number.isNaN(Number(response.status)) ||
@@ -82,11 +82,11 @@ const isFailedResponse = (response) =>
82
82
  /**
83
83
  * Checks a Puppeteer page for the element specified in the hash of the provided link.
84
84
  *
85
- * @private
86
- * @static
87
85
  * @param {object} page A Puppeteer page object.
88
86
  * @param {string} link The link to check.
89
87
  * @returns {(string|number)} The link status (HTTP response code or error).
88
+ * @static
89
+ * @private
90
90
  */
91
91
  const checkSamePageLink = async (page, link) => {
92
92
  const selector = link.slice(page.url().length);
@@ -101,11 +101,11 @@ const checkSamePageLink = async (page, link) => {
101
101
  /**
102
102
  * Checks the provided link for validity by loading in a Puppeteer page.
103
103
  *
104
- * @private
105
- * @static
106
104
  * @param {object} page A Puppeteer page object.
107
105
  * @param {string} link The link to check.
108
106
  * @returns {(string|number)} The link status (HTTP response code or error).
107
+ * @static
108
+ * @private
109
109
  */
110
110
  const checkExternalPageLinkBrowser = async (page, link) => {
111
111
  let status;
@@ -126,12 +126,12 @@ const checkExternalPageLinkBrowser = async (page, link) => {
126
126
  * Checks the provided link for validity by requesting with axios. If useGet if false,
127
127
  * a HEAD request is made for efficiency. If useGet is true, a full GET request is made.
128
128
  *
129
- * @private
130
- * @static
131
129
  * @param {object} page A Puppeteer page object.
132
130
  * @param {string} link The link to check.
133
131
  * @param {boolean} [useGet] Used to identify the request method to use (HEAD or GET).
134
132
  * @returns {(string|number)} The link status (HTTP response code or error).
133
+ * @static
134
+ * @private
135
135
  */
136
136
  // eslint-disable-next-line sonarjs/cognitive-complexity -- Allow less than 10
137
137
  const checkExternalPageLink = async (page, link, useGet = false) => {
@@ -174,9 +174,9 @@ const checkExternalPageLink = async (page, link, useGet = false) => {
174
174
  * Factory function returning a linkChecker object with a {@link checkLink}
175
175
  * function that caches checked link results.
176
176
  *
177
- * @public
178
- * @static
179
177
  * @returns {object} Link checker object.
178
+ * @static
179
+ * @public
180
180
  */
181
181
  const createLinkChecker = () => {
182
182
  const checkedLinks = new Map();
@@ -186,11 +186,11 @@ const createLinkChecker = () => {
186
186
  * Checks the provided link for validity using context object for a
187
187
  * reference to the Puppeteer page and applicable settings.
188
188
  *
189
- * @public
190
189
  * @instance
191
190
  * @param {object} context A Pagean test context object.
192
191
  * @param {string} link The link to check.
193
192
  * @returns {(string|number)} The link status (HTTP response code or error).
193
+ * @public
194
194
  */
195
195
  // eslint-disable-next-line sonarjs/cognitive-complexity
196
196
  checkLink: async (context, link) => {
package/lib/logger.js CHANGED
@@ -21,9 +21,9 @@ const nullFunction = () => {};
21
21
  * Factory function that creates an instance of a
22
22
  * logger object to manage logging functions.
23
23
  *
24
- * @static
25
24
  * @param {object} config Pagean configuration.
26
25
  * @returns {object} A logger object.
26
+ * @static
27
27
  */
28
28
  // eslint-disable-next-line max-lines-per-function
29
29
  module.exports = (config) => {
@@ -13,9 +13,9 @@
13
13
  color: #333333;
14
14
  font-family: Arial, Helvetica, sans-serif;
15
15
  font-size: 0.85rem;
16
- padding: 1rem;
17
16
  margin: auto;
18
17
  max-width: 1000px;
18
+ padding: 1rem;
19
19
  }
20
20
 
21
21
  ul {
@@ -31,9 +31,9 @@
31
31
  }
32
32
 
33
33
  h1 {
34
+ margin: 1rem 0 0.75rem;
34
35
  margin-block: 0;
35
36
  margin-inline: 0;
36
- margin: 1rem 0 0.75rem;
37
37
  }
38
38
 
39
39
  h2 {
package/lib/reporter.js CHANGED
@@ -41,9 +41,9 @@ const reporterTypes = Object.freeze({
41
41
  /**
42
42
  * Outputs the given results with specified reporters.
43
43
  *
44
- * @static
45
44
  * @param {object} results Consolidated Pagean results for a all tests.
46
45
  * @param {string[]} reporters The configured reporters.
46
+ * @static
47
47
  */
48
48
  const saveReports = (results, reporters) => {
49
49
  if (reporters.includes(reporterTypes.json)) {
@@ -48,9 +48,9 @@ const processErrorParameters = (error) => {
48
48
  * Generates formatted schema strings for output to stdout for all
49
49
  * schema errors.
50
50
  *
51
- * @static
52
51
  * @param {object[]} errors Array of Pagean config schema errors.
53
52
  * @returns {string[]} Array of formatted schema error strings.
53
+ * @static
54
54
  */
55
55
  const formatErrors = (errors) => {
56
56
  const margin = 2;
package/lib/test-utils.js CHANGED
@@ -26,12 +26,12 @@ const getTestSettings = (testSettingProperty, urlSettings) => {
26
26
  * test-specific settings from configuration, passing the test context,
27
27
  * and logging results.
28
28
  *
29
- * @static
30
29
  * @param {string} name The name of the test.
31
30
  * @param {Function} testFunction The test function to be executed.
32
31
  * @param {object} testContext The test execution context.
33
32
  * @param {string} testSettingProperty The name of the config property
34
33
  * with settings for the current test.
34
+ * @static
35
35
  */
36
36
  const pageanTest = async (
37
37
  name,
package/lib/tests.js CHANGED
@@ -16,8 +16,8 @@ const msPerSec = 1000;
16
16
  /**
17
17
  * Tests the current page for the existence of a horizontal scroll bar.
18
18
  *
19
- * @static
20
19
  * @param {object} context Test execution context.
20
+ * @static
21
21
  */
22
22
  const horizontalScrollbarTest = async (context) => {
23
23
  await pageanTest(
@@ -44,8 +44,8 @@ const horizontalScrollbarTest = async (context) => {
44
44
  /**
45
45
  * Tests the current page for any console output.
46
46
  *
47
- * @static
48
47
  * @param {object} context Test execution context.
48
+ * @static
49
49
  */
50
50
  const consoleOutputTest = (context) => {
51
51
  pageanTest(
@@ -71,8 +71,8 @@ const consoleOutputTest = (context) => {
71
71
  /**
72
72
  * Tests the current page for any console errors.
73
73
  *
74
- * @static
75
74
  * @param {object} context Test execution context.
75
+ * @static
76
76
  */
77
77
  const consoleErrorTest = (context) => {
78
78
  pageanTest(
@@ -80,9 +80,7 @@ const consoleErrorTest = (context) => {
80
80
  // eslint-disable-next-line no-shadow -- less intuitive
81
81
  (context) => {
82
82
  const browserErrorLog = context.consoleLog.filter(
83
- // Object property names defined by puppeteer API
84
- // eslint-disable-next-line no-underscore-dangle
85
- (log) => log._type === 'error'
83
+ (log) => log.type === 'error'
86
84
  );
87
85
  const testResult = {
88
86
  result:
@@ -103,8 +101,8 @@ const consoleErrorTest = (context) => {
103
101
  /**
104
102
  * Tests the current page for any HTML lint issues.
105
103
  *
106
- * @static
107
104
  * @param {object} context Test execution context.
105
+ * @static
108
106
  */
109
107
  const renderedHtmlTest = async (context) => {
110
108
  await pageanTest(
@@ -135,8 +133,8 @@ const renderedHtmlTest = async (context) => {
135
133
  /**
136
134
  * Tests the current page for load time.
137
135
  *
138
- * @static
139
136
  * @param {object} context Test execution context.
137
+ * @static
140
138
  */
141
139
  // eslint-disable-next-line max-lines-per-function
142
140
  const pageLoadTimeTest = async (context) => {
@@ -178,8 +176,8 @@ const pageLoadTimeTest = async (context) => {
178
176
  * Tests the current page for any external JavaScript files and
179
177
  * downloads the files for further analysis.
180
178
  *
181
- * @static
182
179
  * @param {object} context Test execution context.
180
+ * @static
183
181
  */
184
182
  // eslint-disable-next-line max-lines-per-function
185
183
  const externalScriptTest = async (context) => {
@@ -222,8 +220,8 @@ const externalScriptTest = async (context) => {
222
220
  /**
223
221
  * Tests the current page for any broken links (external or within the page).
224
222
  *
225
- * @static
226
223
  * @param {object} context Test execution context.
224
+ * @static
227
225
  */
228
226
  // eslint-disable-next-line max-lines-per-function
229
227
  const brokenLinkTest = async (context) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagean",
3
- "version": "6.0.9",
3
+ "version": "8.0.0",
4
4
  "description": "Pagean is a web page analysis tool designed to automate tests requiring web pages to be loaded in a browser window (e.g. horizontal scrollbar, console errors)",
5
5
  "bin": {
6
6
  "pagean": "./bin/pagean.js",
@@ -37,7 +37,7 @@
37
37
  "author": "Aaron Goldenthal <npm@aarongoldenthal.com>",
38
38
  "license": "MIT",
39
39
  "engines": {
40
- "node": "^12.20.0 || ^14.15.0 || >=16.0.0"
40
+ "node": "^14.15.0 || ^16.13.0 || >=18.0.0"
41
41
  },
42
42
  "files": [
43
43
  "index.js",
@@ -51,28 +51,28 @@
51
51
  },
52
52
  "homepage": "https://gitlab.com/gitlab-ci-utils/pagean",
53
53
  "devDependencies": {
54
- "@aarongoldenthal/eslint-config-standard": "^14.0.0",
55
- "@aarongoldenthal/stylelint-config-standard": "^8.0.0",
56
- "bin-tester": "^2.0.1",
57
- "eslint": "^8.14.0",
58
- "jest": "^28.0.2",
59
- "jest-junit": "^13.2.0",
60
- "markdownlint-cli": "^0.31.1",
61
- "prettier": "^2.6.2",
54
+ "@aarongoldenthal/eslint-config-standard": "^17.0.1",
55
+ "@aarongoldenthal/stylelint-config-standard": "^11.2.1",
56
+ "bin-tester": "^3.0.0",
57
+ "eslint": "^8.26.0",
58
+ "jest": "^29.2.2",
59
+ "jest-junit": "^14.0.1",
60
+ "markdownlint-cli": "^0.32.2",
61
+ "prettier": "^2.7.1",
62
62
  "strip-ansi": "^6.0.1",
63
- "stylelint": "^14.8.0"
63
+ "stylelint": "^14.14.0"
64
64
  },
65
65
  "dependencies": {
66
66
  "ajv": "^8.11.0",
67
67
  "ajv-errors": "^3.0.0",
68
- "axios": "^0.27.2",
69
- "ci-logger": "^4.0.2",
70
- "commander": "^9.2.0",
68
+ "axios": "^1.1.3",
69
+ "ci-logger": "^5.1.0",
70
+ "commander": "^9.4.1",
71
71
  "handlebars": "^4.7.7",
72
72
  "htmlhint": "^1.1.4",
73
- "kleur": "^4.1.4",
73
+ "kleur": "^4.1.5",
74
74
  "normalize-url": "^6.1.0",
75
75
  "protocolify": "^3.0.0",
76
- "puppeteer": "^13.6.0"
76
+ "puppeteer": "^19.2.0"
77
77
  }
78
78
  }