testaro 18.5.0 → 18.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "18.5.0",
3
+ "version": "18.6.0",
4
4
  "description": "Run 920 web accessibility tests from 9 tools and get a standardized report",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/procs/testaro.js CHANGED
@@ -8,9 +8,9 @@ const {getLocatorData} = require('../procs/getLocatorData');
8
8
  // ########## FUNCTIONS
9
9
 
10
10
  // Initializes locators and a result.
11
- exports.init = async (page, locAllSelector) => {
11
+ exports.init = async (page, locAllSelector, options = {}) => {
12
12
  // Get locators for the specified elements.
13
- const locAll = page.locator(locAllSelector);
13
+ const locAll = page.locator(locAllSelector, options);
14
14
  const allLocs = await locAll.all();
15
15
  const result = {
16
16
  data: {},
@@ -30,8 +30,16 @@ exports.report = async (withItems, all, ruleID, whats, ordinalSeverity, tagName
30
30
  const {locs, result} = all;
31
31
  const {totals, standardInstances} = result;
32
32
  // For each instance locator:
33
- for (const loc of locs) {
33
+ for (const locItem of locs) {
34
34
  // Get data on its element.
35
+ let loc, whatParam;
36
+ if (Array.isArray(locItem)) {
37
+ loc = locItem[0];
38
+ whatParam = locItem[1];
39
+ }
40
+ else {
41
+ loc = locItem;
42
+ }
35
43
  const elData = await getLocatorData(loc);
36
44
  // Add to the totals.
37
45
  totals[ordinalSeverity]++;
@@ -40,7 +48,7 @@ exports.report = async (withItems, all, ruleID, whats, ordinalSeverity, tagName
40
48
  // Add a standard instance to the result.
41
49
  standardInstances.push({
42
50
  ruleID,
43
- what: whats[0],
51
+ what: whatParam ? whats[0].replace('__param__', whatParam) : whats[0],
44
52
  ordinalSeverity,
45
53
  tagName: elData.tagName,
46
54
  id: elData.id,
@@ -49,8 +57,8 @@ exports.report = async (withItems, all, ruleID, whats, ordinalSeverity, tagName
49
57
  });
50
58
  }
51
59
  }
52
- // If itemization is not required:
53
- if (! withItems) {
60
+ // If itemization is not required and any instances exist:
61
+ if (! withItems && locs.length) {
54
62
  // Add a summary standard instance to the result.
55
63
  standardInstances.push({
56
64
  ruleID,
@@ -1,96 +1,50 @@
1
1
  /*
2
2
  allCaps
3
3
  Related to Tenon rule 153.
4
- This test reports normalized text nodes containing at least one substring of upper-case letters,
5
- hyphen-minuses, and spaces at least 8 characters long. Blocks of upper-case text are difficult
6
- to read.
4
+ This test reports elements with native or transformed upper-case text at least 8 characters long.
5
+ Blocks of upper-case text are difficult to read.
7
6
  */
8
7
 
9
8
  // ########## IMPORTS
10
9
 
11
- // Module to get text nodes.
12
- const {getTextNodes} = require('../procs/getTextNodes');
10
+ // Module to perform common operations.
11
+ const {init, report} = require('../procs/testaro');
13
12
 
14
13
  // ########## FUNCTIONS
15
14
 
16
- // Runs the test and returns the results.
15
+ // Runs the test and returns the result.
17
16
  exports.reporter = async (page, withItems) => {
18
- // Get the text nodes of the page and their parent elements.
19
- const textNodesData = await getTextNodes(page);
20
- // Get data on the qualifying text nodes.
21
- const result = await textNodesData.evaluate((textNodesData, withItems) => {
22
- // Initialize the result.
23
- const result = {
24
- data: {},
25
- totals: [0, 0, 0, 0],
26
- standardInstances: []
27
- };
28
- // For each text node:
29
- for (const textNodeData of textNodesData) {
30
- // If it qualifies:
31
- let isCap = false;
32
- if (/[- A-Z]{8}/.test(textNodeData[0])) {
33
- isCap = true;
17
+ // Initialize the locators and result.
18
+ const all = await init(page, 'body *:not(style):not(script):not(svg)');
19
+ // For each locator:
20
+ for (const loc of all.allLocs) {
21
+ // Get whether its element violates the rule.
22
+ const isBad = await loc.evaluate(el => {
23
+ const elText = Array
24
+ .from(el.childNodes)
25
+ .filter(node => node.nodeType === Node.TEXT_NODE)
26
+ .map(textNode => textNode.nodeValue)
27
+ .join(' ');
28
+ // If the element text includes 8 sequential upper-case letters, spaces, or hyphen-minuses:
29
+ if (/[- A-Z]{8}/.test(elText)) {
30
+ // Report this.
31
+ return true;
34
32
  }
35
- else if (/[- A-Za-z]{8}/.test(textNodeData[0])) {
36
- const styleDec = window.getComputedStyle(textNodeData[1]);
37
- if (styleDec.textTransform === 'uppercase') {
38
- isCap = true;
39
- }
33
+ // Otherwise:
34
+ else {
35
+ // Report whether its text is at least 8 characters long and transformed to upper case.
36
+ const elStyleDec = window.getComputedStyle(el);
37
+ const transformStyle = elStyleDec.textTransform;
38
+ return transformStyle === 'uppercase' && elText.length > 7;
40
39
  }
41
- if (isCap) {
42
- // Add to the totals.
43
- result.totals[0]++;
44
- // If itemization is required:
45
- if (withItems) {
46
- // Add a standard instance.
47
- const {id} = textNodeData[1];
48
- let spec;
49
- if (id) {
50
- spec = `#${id}`;
51
- }
52
- else {
53
- const domRect = textNodeData[1].getBoundingClientRect();
54
- spec = {
55
- x: Math.round(domRect.x),
56
- y: Math.round(domRect.y),
57
- width: Math.round(domRect.width),
58
- height: Math.round(domRect.height)
59
- };
60
- }
61
- result.standardInstances.push({
62
- ruleID: 'allCaps',
63
- what: 'Text is entirely upper-case',
64
- ordinalSeverity: 0,
65
- tagName: textNodeData[1].tagName,
66
- id: id || '',
67
- location: {
68
- doc: 'dom',
69
- type: id ? 'selector' : 'box',
70
- spec
71
- },
72
- excerpt: textNodeData[0]
73
- });
74
- }
75
- }
76
- }
77
- return result;
78
- }, withItems);
79
- if (! withItems) {
80
- result.standardInstances.push({
81
- ruleID: 'allCaps',
82
- what: 'Texts are entirely upper-case',
83
- ordinalSeverity: 0,
84
- count: result.totals[0],
85
- tagName: '',
86
- id: '',
87
- location: {
88
- doc: '',
89
- type: '',
90
- spec: ''
91
- },
92
- excerpt: ''
93
40
  });
41
+ // If it does:
42
+ if (isBad) {
43
+ // Add the locator to the array of violators.
44
+ all.locs.push(loc);
45
+ }
94
46
  }
95
- return result;
47
+ // Populate and return the result.
48
+ const whats = ['Element contains all-capital text', 'Elements contain all-capital text'];
49
+ return await report(withItems, all, 'allCaps', whats, 0);
96
50
  };
@@ -1,93 +1,39 @@
1
1
  /*
2
2
  allSlanted
3
3
  Related to Tenon rule 154.
4
- This test reports normalized text nodes containing at least one substring of italic or
5
- oblique characters at least 40 characters long. Blocks of slanted text are difficult
6
- to read.
4
+ This test reports elements with italic or oblique text at least 40 characters long. Blocks of
5
+ slanted text are difficult to read.
7
6
  */
8
7
 
9
8
  // ########## IMPORTS
10
9
 
11
- // Module to get text nodes.
12
- const {getTextNodes} = require('../procs/getTextNodes');
10
+ // Module to perform common operations.
11
+ const {init, report} = require('../procs/testaro');
13
12
 
14
13
  // ########## FUNCTIONS
15
14
 
16
- // Runs the test and returns the results.
15
+ // Runs the test and returns the result.
17
16
  exports.reporter = async (page, withItems) => {
18
- // Get the text nodes of the page and their parent elements.
19
- const textNodesData = await getTextNodes(page);
20
- // Get data on the qualifying text nodes.
21
- const result = await textNodesData.evaluate((textNodesData, withItems) => {
22
- // Initialize the result.
23
- const result = {
24
- data: {},
25
- totals: [0, 0, 0, 0],
26
- standardInstances: []
27
- };
28
- // For each text node:
29
- for (const textNodeData of textNodesData) {
30
- // If it qualifies:
31
- let isSlanted = false;
32
- if (/.{40}/.test(textNodeData[0])) {
33
- const styleDec = window.getComputedStyle(textNodeData[1]);
34
- if (['italic', 'oblique'].includes(styleDec.fontStyle)) {
35
- isSlanted = true;
36
- }
37
- }
38
- if (isSlanted) {
39
- // Add to the totals.
40
- result.totals[0]++;
41
- // If itemization is required:
42
- if (withItems) {
43
- // Add a standard instance.
44
- const {id} = textNodeData[1];
45
- let spec;
46
- if (id) {
47
- spec = `#${id}`;
48
- }
49
- else {
50
- const domRect = textNodeData[1].getBoundingClientRect();
51
- spec = {
52
- x: Math.round(domRect.x),
53
- y: Math.round(domRect.y),
54
- width: Math.round(domRect.width),
55
- height: Math.round(domRect.height)
56
- };
57
- }
58
- result.standardInstances.push({
59
- ruleID: 'allSlanted',
60
- what: 'Text is entirely italic or oblique',
61
- ordinalSeverity: 0,
62
- tagName: textNodeData[1].tagName,
63
- id: id || '',
64
- location: {
65
- doc: 'dom',
66
- type: id ? 'selector' : 'box',
67
- spec
68
- },
69
- excerpt: textNodeData[0]
70
- });
71
- }
72
- }
73
- }
74
- return result;
75
- }, withItems);
76
- if (! withItems) {
77
- result.standardInstances.push({
78
- ruleID: 'allSlanted',
79
- what: 'Texts are entirely italic or oblique',
80
- ordinalSeverity: 0,
81
- count: result.totals[0],
82
- tagName: '',
83
- id: '',
84
- location: {
85
- doc: '',
86
- type: '',
87
- spec: ''
88
- },
89
- excerpt: ''
17
+ // Initialize the locators and result.
18
+ const all = await init(page, 'body *:not(style):not(script):not(svg)');
19
+ // For each locator:
20
+ for (const loc of all.allLocs) {
21
+ // Get whether its element violates the rule.
22
+ const isBad = await loc.evaluate(el => {
23
+ const elStyleDec = window.getComputedStyle(el);
24
+ const elText = el.textContent;
25
+ return ['italic', 'oblique'].includes(elStyleDec.fontStyle) && elText.length > 39;
90
26
  });
27
+ // If it does:
28
+ if (isBad) {
29
+ // Add the locator to the array of violators.
30
+ all.locs.push(loc);
31
+ }
91
32
  }
92
- return result;
33
+ // Populate and return the result.
34
+ const whats = [
35
+ 'Element contains all-italic or all-oblique text',
36
+ 'Elements contain all-italic or all-oblique text'
37
+ ];
38
+ return await report(withItems, all, 'allSlanted', whats, 0);
93
39
  };
package/testaro/attVal.js CHANGED
@@ -5,69 +5,30 @@
5
5
 
6
6
  // ########## IMPORTS
7
7
 
8
- // Module to get locator data.
9
- const {getLocatorData} = require('../procs/getLocatorData');
8
+ // Module to perform common operations.
9
+ const {init, report} = require('../procs/testaro');
10
10
 
11
11
  // ########## FUNCTIONS
12
12
 
13
- // Runs the test and returns the results.
13
+ // Runs the test and returns the result.
14
14
  exports.reporter = async (page, withItems, attributeName, areLicit, values) => {
15
- // Get locators for all elements with the attribute.
16
- const locAll = page.locator(`[${attributeName}]`);
17
- const locsAll = await locAll.all();
18
- const locs = [];
19
- // Get those that have illicit values on the attribute.
20
- for (const loc of locsAll) {
15
+ // Initialize the locators and result.
16
+ const all = await init(page, `[${attributeName}]`);
17
+ // For each locator:
18
+ for (const loc of all.allLocs) {
19
+ // Get whether its element violates the rule.
21
20
  const value = await loc.getAttribute(attributeName);
22
- if (areLicit !== values.includes(value)) {
23
- locs.push(loc);
21
+ const isBad = areLicit !== values.includes(value);
22
+ // If it does:
23
+ if (isBad) {
24
+ // Add the locator to the array of violators.
25
+ all.locs.push([loc, value]);
24
26
  }
25
27
  }
26
- // Initialize the results.
27
- const data = {};
28
- const totals = [0, 0, locs.length, 0];
29
- const standardInstances = [];
30
- // If itemization is required:
31
- if (withItems) {
32
- // For each qualifying locator:
33
- for (const loc of locs) {
34
- // Get data on its element.
35
- const elData = await getLocatorData(loc);
36
- // Get the illicit value of the attribute.
37
- const badValue = await loc.getAttribute(attributeName);
38
- // Add a standard instance.
39
- standardInstances.push({
40
- ruleID: 'attVal',
41
- what: `Element has attribute ${attributeName} with illicit value ${badValue}`,
42
- ordinalSeverity: 2,
43
- tagName: elData.tagName,
44
- id: elData.id,
45
- location: elData.location,
46
- excerpt: elData.excerpt
47
- });
48
- }
49
- }
50
- // Otherwise, i.e. if itemization is not required and any instances exist:
51
- else if (totals[2]) {
52
- // Add a summary standard instance.
53
- standardInstances.push({
54
- ruleID: 'attVal',
55
- what: `Elements have attribute ${attributeName} with illicit values`,
56
- ordinalSeverity: 2,
57
- count: totals[2],
58
- tagName: '',
59
- id: '',
60
- location: {
61
- doc: '',
62
- type: '',
63
- spec: ''
64
- },
65
- excerpt: ''
66
- });
67
- }
68
- return {
69
- data,
70
- totals,
71
- standardInstances
72
- };
28
+ // Populate and return the result.
29
+ const whats = [
30
+ `Element has attribute ${attributeName} with illicit value “__param__”`,
31
+ `Elements have attribute ${attributeName} with illicit values`
32
+ ];
33
+ return await report(withItems, all, 'attVal', whats, 2);
73
34
  };
@@ -12,7 +12,7 @@ const {init, report} = require('../procs/testaro');
12
12
 
13
13
  // ########## FUNCTIONS
14
14
 
15
- // Runs the test and returns the results.
15
+ // Runs the test and returns the result.
16
16
  exports.reporter = async (page, withItems) => {
17
17
  // Initialize the locators and result.
18
18
  const all = await init(page, 'body *');
@@ -10,7 +10,7 @@ const {init, report} = require('../procs/testaro');
10
10
 
11
11
  // ########## FUNCTIONS
12
12
 
13
- // Runs the test and returns the results.
13
+ // Runs the test and returns the result.
14
14
  exports.reporter = async (page, withItems) => {
15
15
  // Initialize the locators and result.
16
16
  const all = await init(page, 'body *');
@@ -30,6 +30,16 @@
30
30
  "=",
31
31
  0
32
32
  ],
33
+ [
34
+ "standardResult.instances.0.ruleID",
35
+ "=",
36
+ "allCaps"
37
+ ],
38
+ [
39
+ "standardResult.instances.0.what",
40
+ "i",
41
+ "Element contains"
42
+ ],
33
43
  [
34
44
  "standardResult.instances.0.tagName",
35
45
  "=",
@@ -112,6 +122,11 @@
112
122
  "=",
113
123
  0
114
124
  ],
125
+ [
126
+ "standardResult.instances.0.what",
127
+ "i",
128
+ "Elements contain"
129
+ ],
115
130
  [
116
131
  "standardResult.instances.0.count",
117
132
  "=",
@@ -30,6 +30,16 @@
30
30
  "=",
31
31
  0
32
32
  ],
33
+ [
34
+ "standardResult.instances.0.ruleID",
35
+ "=",
36
+ "allSlanted"
37
+ ],
38
+ [
39
+ "standardResult.instances.0.what",
40
+ "i",
41
+ "Element contains"
42
+ ],
33
43
  [
34
44
  "standardResult.instances.0.tagName",
35
45
  "=",
@@ -40,11 +50,6 @@
40
50
  "=",
41
51
  0
42
52
  ],
43
- [
44
- "standardResult.instances.0.what",
45
- "i",
46
- "Text is entirely"
47
- ],
48
53
  [
49
54
  "standardResult.instances.0.location.type",
50
55
  "=",
@@ -88,7 +88,7 @@
88
88
  [
89
89
  "standardResult.instances.0.what",
90
90
  "i",
91
- "illicit value en"
91
+ "Element has attribute"
92
92
  ],
93
93
  [
94
94
  "standardResult.instances.0.location.doc",