testaro 64.9.3 → 64.9.5

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": "64.9.3",
3
+ "version": "64.9.5",
4
4
  "description": "Run 1000 web accessibility tests from 11 tools and get a standardized report",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -106,8 +106,8 @@ exports.getLocationData = async (page, excerpt) => {
106
106
  const testaroIDArray = excerpt.match(/data-testaro-id="(\d+)#([^"]*)"/);
107
107
  // If the extract contains a Testaro identifier:
108
108
  if (testaroIDArray) {
109
- const testaroID = `${testaroIDArray[1]}#${testaroIDArray[2]}`;
110
- return await page.evaluate(testaroID => {
109
+ return await page.evaluate(testaroIDArray => {
110
+ const testaroID = `${testaroIDArray[1]}#${testaroIDArray[2]}`;
111
111
  const element = document.querySelector(`[data-testaro-id="${testaroID}"]`);
112
112
  // If any element has that identifier:
113
113
  if (element) {
@@ -123,8 +123,8 @@ exports.getLocationData = async (page, excerpt) => {
123
123
  if (typeof box.x === 'number') {
124
124
  boxID = Object.values(box).join(':');
125
125
  }
126
- // Get a path ID for the element.
127
- let pathID = testaroID.replace(/^.*?#/, '');
126
+ // Get a path ID from the Testaro identifier or, if necessary, the element.
127
+ let pathID = testaroIDArray[2];
128
128
  if (! pathID) {
129
129
  pathID = window.getXPath(element);
130
130
  }
@@ -149,7 +149,7 @@ exports.getLocationData = async (page, excerpt) => {
149
149
  boxID: '',
150
150
  pathID: ''
151
151
  };
152
- }, testaroID);
152
+ }, testaroIDArray);
153
153
  }
154
154
  // Otherwise, i.e. if the extract contains no Testaro identifier:
155
155
  else {
package/procs/identify.js CHANGED
@@ -54,6 +54,21 @@ const boxToString = exports.boxToString = box => {
54
54
  return '';
55
55
  }
56
56
  };
57
+ // Normalizes an XPath.
58
+ const getNormalizedXPath = exports.getNormalizedXPath = xPath => {
59
+ xPath = xPath.replace(/^\.\/\//, '/');
60
+ const segments = xPath.split('/');
61
+ const normalizedSegments = [];
62
+ segments.forEach(segment => {
63
+ if (segment === '' || ['html', 'body'].includes(segment) || segment.endsWith(']')) {
64
+ normalizedSegments.push(segment);
65
+ }
66
+ else {
67
+ normalizedSegments.push(`${segment}[1]`);
68
+ }
69
+ });
70
+ return normalizedSegments.join('/');
71
+ };
57
72
  // Adds a box ID and a path ID to an object.
58
73
  const addIDs = async (locator, recipient) => {
59
74
  const locatorCount = await locator.count();
@@ -84,20 +99,7 @@ const addIDs = async (locator, recipient) => {
84
99
  }
85
100
  }
86
101
  // Normalize the path ID.
87
- const xPathSegments = recipient.pathID.split('/');
88
- const normalizedSegments = xPathSegments.map(segment => {
89
- if (segment === '') {
90
- return '';
91
- }
92
- if (['html', 'body'].includes(segment)) {
93
- return segment;
94
- }
95
- if (segment.endsWith(']')) {
96
- return segment;
97
- }
98
- return `${segment}[1]`;
99
- });
100
- recipient.pathID = normalizedSegments.join('/');
102
+ recipient.pathID = getNormalizedXPath(recipient.pathID);
101
103
  }
102
104
  };
103
105
  // Sanitizes a tag name.
@@ -13,6 +13,10 @@
13
13
  Converts test results to the standard format.
14
14
  */
15
15
 
16
+ // IMPORTS
17
+
18
+ const {getNormalizedXPath} = require('./identify');
19
+
16
20
  // FUNCTIONS
17
21
 
18
22
  // Limits the length of and unilinearizes a string.
@@ -485,19 +489,30 @@ const convert = (toolName, data, result, standardResult) => {
485
489
  finalRuleID = changer[changer.length - 1];
486
490
  }
487
491
  }
488
- // Get the instance properties.
489
- const xpath = ruleResult.element && ruleResult.element.xpath || '';
490
- let tagName = xpath
491
- && xpath.replace(/^.*\//, '').replace(/[^-\w].*$/, '').toUpperCase()
492
+ // Initialize the path ID of the violating element as any normalized reported XPath.
493
+ let pathID = getNormalizedXPath(ruleResult.element && ruleResult.element.xpath) || '';
494
+ const {locationData} = ruleResult;
495
+ // If an XPath was obtained from the excerpt:
496
+ if (locationData && locationData.pathID) {
497
+ // Replace the path ID with it, because some ASLint-reported XPaths are abbreviated.
498
+ ({pathID} = locationData);
499
+ }
500
+ // Get and normalize the reported excerpt.
501
+ const excerpt = ruleResult.element
502
+ && ruleResult.element.html
503
+ && ruleResult.element.html.replace(/\s+/g, ' ')
492
504
  || '';
505
+ // Get the tag name from the XPath, if possible.
506
+ let tagName = pathID && pathID.replace(/[^-\w].*$/, '').toUpperCase() || '';
493
507
  if (! tagName && finalRuleID.endsWith('_svg')) {
494
508
  tagName = 'SVG';
495
509
  }
496
- const excerpt = ruleResult.element && ruleResult.element.html.replace(/\s+/g, ' ')
497
- || '';
510
+ // If that was impossible but there is a tag name in the excerpt:
498
511
  if (! tagName && /^<[a-z]+[ >]/.test(excerpt)) {
512
+ // Get it.
499
513
  tagName = excerpt.slice(1).replace(/[ >].+/, '').toUpperCase();
500
514
  }
515
+ // Get the ID, if any.
501
516
  const idDraft = excerpt && excerpt.replace(/^[^[>]+id="/, 'id=').replace(/".*$/, '');
502
517
  const idFinal = idDraft && idDraft.length > 3 && idDraft.startsWith('id=')
503
518
  ? idDraft.slice(3)
@@ -512,9 +527,11 @@ const convert = (toolName, data, result, standardResult) => {
512
527
  location: {
513
528
  doc: 'dom',
514
529
  type: 'xpath',
515
- spec: xpath
530
+ spec: pathID
516
531
  },
517
- excerpt
532
+ excerpt,
533
+ boxID: '',
534
+ pathID
518
535
  };
519
536
  standardResult.instances.push(instance);
520
537
  }
package/run.js CHANGED
@@ -412,7 +412,7 @@ const launch = exports.launch = async (
412
412
  get: () => ['en-US', 'en']
413
413
  });
414
414
  });
415
- const xPathNeeders = ['testaro', 'htmlcs', 'nuVal', 'nuVnu', 'qualWeb', 'wax'];
415
+ const xPathNeeders = ['aslint', 'htmlcs', 'nuVal', 'nuVnu', 'qualWeb', 'testaro', 'wax'];
416
416
  const needsXPath = act.type === 'test' && xPathNeeders.includes(act.which);
417
417
  // If the launch is for a test act that requires XPaths:
418
418
  if (needsXPath) {
package/tests/aslint.js CHANGED
@@ -15,13 +15,19 @@
15
15
 
16
16
  // IMPORTS
17
17
 
18
+ // Function to add unique identifiers to the elements in the page.
19
+ const {addTestaroIDs} = require('../procs/testaro');
18
20
  // Module to handle files.
19
21
  const fs = require('fs/promises');
22
+ // Function to get location data from an element.
23
+ const {getLocationData} = require('../procs/getLocatorData');
20
24
 
21
25
  // FUNCTIONS
22
26
 
23
27
  // Conducts and reports the ASLint tests.
24
28
  exports.reporter = async (page, report, actIndex, timeLimit) => {
29
+ // Add unique identifiers to the elements in the page.
30
+ await addTestaroIDs(page);
25
31
  // Initialize the act report.
26
32
  let data = {};
27
33
  let result = {};
@@ -82,13 +88,11 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
82
88
  if (! data.prevented) {
83
89
  // Get their text.
84
90
  const actReport = await reportLoc.textContent();
85
- // Populate the act report.
86
91
  result = JSON.parse(actReport);
87
92
  // If any rules were reported violated:
88
93
  if (result.rules) {
89
94
  // For each such rule:
90
- Object.keys(result.rules).forEach(ruleID => {
91
- // If the rule was passed or skipped or rules to be tested were specified and exclude it:
95
+ for (const ruleID of Object.keys(result.rules)) {
92
96
  const excluded = act.rules && ! act.rules.includes(ruleID);
93
97
  const instanceType = result.rules[ruleID].status.type;
94
98
  // If rules to be tested were specified and exclude it or the rule was passed or skipped:
@@ -96,7 +100,22 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
96
100
  // Delete the rule report.
97
101
  delete result.rules[ruleID];
98
102
  }
99
- });
103
+ // Otherwise, i.e. if the rule was violated:
104
+ else {
105
+ const ruleResults = result.rules[ruleID].results;
106
+ // For each violation:
107
+ for (const ruleResult of ruleResults) {
108
+ const excerpt = ruleResult.element
109
+ && ruleResult.element.html.replace(/\s+/g, ' ')
110
+ || '';
111
+ // If an element excerpt was reported:
112
+ if (excerpt) {
113
+ // Use it to add location data to the violation data in the result.
114
+ ruleResult.locationData = await getLocationData(page, excerpt);
115
+ }
116
+ };
117
+ }
118
+ };
100
119
  }
101
120
  }
102
121
  // Return the act report.
package/tests/ed11y.js CHANGED
@@ -17,6 +17,8 @@
17
17
 
18
18
  // Module to handle files.
19
19
  const fs = require('fs/promises');
20
+ // Module to normalize XPaths.
21
+ const {getNormalizedXPath} = require('../procs/identify');
20
22
  // Module to get the XPath of an element.
21
23
  const {xPath} = require('playwright-dompath');
22
24
 
@@ -109,7 +111,7 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
109
111
  elText = element.outerHTML;
110
112
  }
111
113
  if (elText.length > 400) {
112
- elText = `${elText.slice(0, 200)}…${elText.slice(-200)}`;
114
+ elText = `${elText.slice(0, 300)}…${elText.slice(-200)}`;
113
115
  }
114
116
  violationFacts.excerpt = elText.replace(/\s+/g, ' ');
115
117
  violationFacts.boxID = ['x', 'y', 'width', 'height']
@@ -165,11 +167,11 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
165
167
  const elementJSHandles = await elementsJSHandle.getProperties();
166
168
  // For each violation:
167
169
  for (const index in violations) {
168
- // Get its path ID from the identically indexed element.
170
+ // Get its Playwright path ID from the identically indexed element.
169
171
  const elementHandle = elementJSHandles.get(index).asElement();
170
- const pathID = await xPath(elementHandle);
171
- // Add the path ID to the violation facts of the result.
172
- violations[index].pathID = pathID;
172
+ const pwPathID = await xPath(elementHandle);
173
+ // Add the normalized path ID to the violation facts of the result.
174
+ violations[index].pathID = getNormalizedXPath(pwPathID);
173
175
  };
174
176
  }
175
177
  // Return the data and result, discarding the separate element data.
package/tests/wax.js CHANGED
@@ -15,9 +15,9 @@
15
15
 
16
16
  // IMPORTS
17
17
 
18
- // Module to add and use unique element IDs.
18
+ // Function to add and use unique element IDs.
19
19
  const {addTestaroIDs} = require('../procs/testaro');
20
- // Module to get location data from an element.
20
+ // Function to get location data from an element.
21
21
  const {getLocationData} = require('../procs/getLocatorData');
22
22
  // Modules to run WAX.
23
23
  const runWax = require('@wally-ax/wax-dev');