testaro 12.4.2 → 12.5.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "12.4.2",
3
+ "version": "12.5.1",
4
4
  "description": "Automation of accessibility testing",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/tests/dupAtt.js CHANGED
@@ -38,22 +38,39 @@ exports.reporter = async (page, withItems) => {
38
38
  return {result: data};
39
39
  }
40
40
  }
41
- // Extract its elements, in a uniform format.
42
- const elements = rawPage
43
- .match(/<[^/<>]+>/g)
44
- .map(element => element.slice(1, -1).trim().replace(/\s*=\s*/g, '='))
45
- .map(element => element.replace(/\s+/g, ' '));
41
+ // Change any spacing character sequences in it to single spaces.
42
+ rawPage = rawPage.replace(/\s+/g, ' ');
43
+ // Remove any escaped quotation marks from it.
44
+ rawPage = rawPage.replace(/\\"|\\'/g, '');
45
+ // Remove any quoted text from it.
46
+ rawPage = rawPage.replace(/"[^<>\r\n"]*"|'[^<>\r\n']*'/g, '');
47
+ // Remove any script code from it.
48
+ rawPage = rawPage.replace(/<(script [^<>]+)>.*?<\/script>/g, '$1');
49
+ // Remove any comments from it.
50
+ rawPage = rawPage.replace(/<!--.*?-->/g, '');
51
+ // Extract the opening tags of its elements.
52
+ let elements = rawPage.match(/<[a-zA-Z][^<>]+>/g);
53
+ // Delete their enclosing angle brackets and the values of any attributes in them.
54
+ elements = elements.map(el => el.replace(/^< *| *= *"[^"]*"|= *[^ ]+| *>$/g, ''));
46
55
  // For each element:
47
56
  elements.forEach(element => {
48
- // Identify its attributes.
49
- const attributes = element.split(' ').slice(1).map(attVal => attVal.replace(/=.+/, ''));
50
- // If any is duplicated:
51
- const attSet = new Set(attributes);
52
- if (attSet.size < attributes.length) {
53
- // Add this to the data.
54
- data.total++;
55
- if (withItems) {
56
- data.items.push(element);
57
+ // Identify its tag name and attributes.
58
+ const terms = element.split(' ');
59
+ // If it has 2 or more attributes:
60
+ if (terms.length > 2) {
61
+ // If any is duplicated:
62
+ const tagName = terms[0].toUpperCase();
63
+ const attributes = terms.slice(1);
64
+ const attSet = new Set(attributes);
65
+ if (attSet.size < attributes.length) {
66
+ // Add this to the data.
67
+ data.total++;
68
+ if (withItems) {
69
+ data.items.push({
70
+ tagName,
71
+ attributes
72
+ });
73
+ }
57
74
  }
58
75
  }
59
76
  });
package/tests/nuVal.js CHANGED
@@ -1,92 +1,85 @@
1
1
  /*
2
2
  nuVal
3
- This test subjects a page to the Nu Html Checker.
4
- That API erratically replaces left and right double quotation marks with invalid UTF-8, which
3
+ This test subjects a page and its source to the Nu Html Checker, thereby testing scripted
4
+ content found only in the loaded page and erroneous content before the browser corrects it.
5
+ The API erratically replaces left and right double quotation marks with invalid UTF-8, which
5
6
  appears as 2 or 3 successive instances of the replacement character (U+fffd). Therefore, this
6
7
  test removes all such quotation marks and the replacement character. That causes
7
8
  'Bad value “” for' to become 'Bad value for'. Since the corruption of quotation marks is
8
9
  erratic, no better solution is known.
9
10
  */
10
- const https = require('https');
11
+
12
+ // ########## IMPORTS
13
+
14
+ // Module to make HTTP requests.
15
+ const fetch = require('node-fetch');
16
+ // Module to process files.
17
+ const fs = require('fs/promises');
18
+
19
+ // ########## FUNCTIONS
20
+
11
21
  exports.reporter = async (page, messages) => {
22
+ // Get the browser-parsed page.
12
23
  const pageContent = await page.content();
13
- // Get the data from a Nu validation.
14
- const dataPromise = new Promise(resolve => {
24
+ // Get the page source.
25
+ const url = page.url();
26
+ const scheme = url.replace(/:.+/, '');
27
+ let rawPage;
28
+ if (scheme === 'file') {
29
+ const filePath = url.slice(7);
30
+ rawPage = await fs.readFile(filePath, 'utf8');
31
+ }
32
+ else {
15
33
  try {
16
- const request = https.request(
17
- {
18
- /*
19
- Alternatives (more timeout-prone): host=validator.nu; path=/?parser=html@out=json
20
- That host crashes instead of ending with a fatal error.
21
- */
22
- host: 'validator.w3.org',
23
- path: '/nu/?parser=html&out=json',
24
- method: 'POST',
25
- headers: {
26
- 'User-Agent': 'Mozilla/5.0',
27
- 'Content-Type': 'text/html; charset=utf-8'
28
- }
29
- },
30
- response => {
31
- let report = '';
32
- response.on('data', chunk => {
33
- report += chunk;
34
- });
35
- // When the data arrive:
36
- response.on('end', async () => {
37
- try {
38
- // Delete left and right quotation marks and their erratic invalid replacements.
39
- const result = JSON.parse(report.replace(/[\u{fffd}“”]/ug, ''));
40
- return resolve(result);
41
- }
42
- catch (error) {
43
- console.log(`ERROR: Validation failed (${error.message})`);
44
- return resolve({
45
- prevented: true,
46
- error: error.message,
47
- report
48
- });
49
- }
50
- });
51
- }
52
- );
53
- request.write(pageContent);
54
- request.end();
55
- request.on('error', error => {
56
- console.log(error.message);
57
- return resolve({
58
- prevented: true,
59
- error: error.message
60
- });
61
- });
34
+ const rawPageResponse = await fetch(url);
35
+ rawPage = await rawPageResponse.text();
62
36
  }
63
37
  catch(error) {
64
- console.log(error.message);
65
- return resolve({
38
+ console.log(`ERROR getting page for nuVal test (${error.message})`);
39
+ return {result: {
66
40
  prevented: true,
67
- error: error.message
68
- });
41
+ error: 'ERROR getting page for nuVal test'
42
+ }};
43
+ }
44
+ }
45
+ // Get the data from Nu validations.
46
+ const fetchOptions = {
47
+ method: 'post',
48
+ headers: {
49
+ 'User-Agent': 'Mozilla/5.0',
50
+ 'Content-Type': 'text/html; charset=utf-8'
69
51
  }
70
- });
71
- const timeoutPromise = new Promise(resolve => {
72
- const timeLimit = 12;
73
- const timeoutID = setTimeout(() => {
74
- resolve({
52
+ };
53
+ // More reliable service than validator.nu.
54
+ const nuURL = 'https://validator.w3.org/nu/?parser=html&out=json';
55
+ const data = {};
56
+ // For each page type:
57
+ for (const page of [['pageContent', pageContent], ['rawPage', rawPage]]) {
58
+ try {
59
+ // Get a Nu Html Checker report on it.
60
+ fetchOptions.body = page[1];
61
+ const nuResult = await fetch(nuURL, fetchOptions);
62
+ const nuData = await nuResult.json();
63
+ const nuDataClean = JSON.parse(JSON.stringify(nuData).replace(/[\u{fffd}“”]/ug, ''));
64
+ // Delete left and right quotation marks and their erratic invalid replacements.
65
+ data[page[0]] = nuDataClean;
66
+ // If there is a report and restrictions on the report messages were specified:
67
+ if (! data[page[0]].error && messages && Array.isArray(messages) && messages.length) {
68
+ // Remove all messages except those specified.
69
+ const messageSpecs = messages.map(messageSpec => messageSpec.split(':', 2));
70
+ data[page[0]].messages = data[page[0]].messages.filter(message => messageSpecs.some(
71
+ messageSpec => message.type === messageSpec[0]
72
+ && message.message.startsWith(messageSpec[1])
73
+ ));
74
+ }
75
+ }
76
+ catch (error) {
77
+ console.log(`ERROR: nuVal report validation failed (${error.message})`);
78
+ return {result: {
75
79
  prevented: true,
76
- error: `ERROR: Validation timed out at ${timeLimit} seconds`
77
- });
78
- clearTimeout(timeoutID);
79
- }, 1000 * timeLimit);
80
- });
81
- // Get the result, or an error report if nuVal timed out after 12 seconds.
82
- const data = await Promise.race([dataPromise, timeoutPromise]);
83
- // If there is a report and restrictions on the report messages were specified:
84
- if (! data.error && messages && Array.isArray(messages) && messages.length) {
85
- // Remove all messages except those specified.
86
- const messageSpecs = messages.map(messageSpec => messageSpec.split(':', 2));
87
- data.messages = data.messages.filter(message => messageSpecs.some(
88
- messageSpec => message.type === messageSpec[0] && message.message.startsWith(messageSpec[1])
89
- ));
80
+ error: 'nuVal report validation failed',
81
+ }};
82
+ }
90
83
  }
91
84
  return {result: data};
92
85
  };