testaro 61.0.0 → 61.1.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
@@ -731,7 +731,7 @@ This instance says that a `button` element violates a rule named `rule01`.
731
731
 
732
732
  The element has no `id` attribute to distinguish it from other `button` elements, but the tool describes its location. This tool uses an XPath to do that. Tools use various methods for location description, namely:
733
733
 
734
- - `line` (line number in the code of the page): Nu Html Checker
734
+ - `code` (line, starting column, and ending column): Nu Html Checker (API and installed)
735
735
  - `selector` (CSS selector): Axe, QualWeb, WAVE
736
736
  - `xpath`: Alfa, ASLint, Equal Access
737
737
  - `box` (coordinates, width, and height of the element box): Editoria11y, Testaro
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "61.0.0",
3
+ "version": "61.1.0",
4
4
  "description": "Run 1000 web accessibility tests from 11 tools and get a standardized report",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -30,31 +30,24 @@ const cap = rawString => {
30
30
  };
31
31
  // Returns whether an id attribute value is valid without character escaping.
32
32
  const isBadID = id => /[^-\w]|^\d|^--|^-\d/.test(id);
33
- // Returns the tag name and the value of an id attribute from a substring of HTML code.
33
+ // Returns a tag name and the value of an id attribute from a substring of HTML code.
34
34
  const getIdentifiers = code => {
35
- let tagName = '';
36
- let id = '';
37
- // If the substring includes the start tag of an element:
38
- if (code && typeof code === 'string' && code.length && /<\s*[a-zA-Z]/.test(code)) {
39
- // Get the first start tag in the substring.
40
- const startTag = code.replace(/^.*?<(?=[a-zA-Z])/s, '').replace(/[^a-zA-Z0-9].*$/s, '').trim();
41
- // If it exists:
42
- if (startTag && startTag.length) {
43
- // Get its tag name, upper-cased.
44
- tagName = startTag.replace(/\s.*$/s, '').toUpperCase();
45
- // Get the value of the id attribute of the start tag, if any.
46
- const idArray = startTag.match(/\sid="([^"<>]+)"/);
47
- if (idArray && idArray.length === 2) {
48
- id = idArray[1];
49
- }
50
- // If the id value is invalid without character escaping:
51
- if (isBadID(id)) {
52
- // Remove it.
53
- id = '';
54
- }
55
- }
35
+ // Normalize the code.
36
+ code = code.replace(/\s+/g, ' ').replace(/\\"/g, '"');
37
+ // Get the first start tag of an element, if any.
38
+ const startTagData = code.match(/^.*?< ?([^>]*)/);
39
+ // If there is any:
40
+ if (startTagData) {
41
+ // Get the tag name.
42
+ const tagNameData = startTagData[1].match(/^[A-Za-z]+/);
43
+ const tagName = tagNameData ? tagNameData[0].toUpperCase() : '';
44
+ // Get the value of the id attribute, if any.
45
+ const idData = startTagData[1].match(/ id="([^"]+)"/);
46
+ const id = idData ? idData[1] : '';
47
+ // Return the tag name and the value of the id attribute, if any.
48
+ return [tagName, id];
56
49
  }
57
- return [tagName, id];
50
+ return ['', ''];
58
51
  };
59
52
  /*
60
53
  Differentiates some rule IDs of aslint.
@@ -221,30 +214,34 @@ const doNuVal = (result, standardResult, docType) => {
221
214
  const items = result[docType] && result[docType].messages;
222
215
  if (items && items.length) {
223
216
  items.forEach(item => {
224
- const identifiers = getIdentifiers(item.extract);
225
- if (! identifiers[0] && item.message) {
226
- const tagNameLCArray = item.message.match(
217
+ const {extract, firstColumn, lastColumn, lastLine, message, subType, type} = item;
218
+ const identifiers = getIdentifiers(extract);
219
+ if (! identifiers[0] && message) {
220
+ const tagNameLCArray = message.match(
227
221
  /^Element ([^ ]+)|^An (img) element| (meta|script) element| element (script)| tag (script)/
228
222
  );
229
223
  if (tagNameLCArray && tagNameLCArray[1]) {
230
224
  identifiers[0] = tagNameLCArray[1].toUpperCase();
231
225
  }
232
226
  }
233
- // Include the message twice. A scoring procedure may replace the ruleID with a pattern.
227
+ let spec = '';
228
+ const locationSegments = [lastLine, firstColumn, lastColumn];
229
+ if (locationSegments.every(segment => typeof segment === 'number')) {
230
+ spec = locationSegments.join(':');
231
+ }
234
232
  const instance = {
235
- ruleID: item.message,
236
- what: item.message,
233
+ ruleID: message,
234
+ what: message,
237
235
  ordinalSeverity: -1,
238
236
  tagName: identifiers[0],
239
237
  id: identifiers[1],
240
238
  location: {
241
239
  doc: docType === 'pageContent' ? 'dom' : 'source',
242
- type: 'line',
243
- spec: item && item.lastLine && item.lastLine.toString() || ''
240
+ type: 'code',
241
+ spec
244
242
  },
245
- excerpt: cap(item.extract)
243
+ excerpt: cap(extract)
246
244
  };
247
- const {type, subType} = item;
248
245
  if (type === 'info' && subType === 'warning') {
249
246
  instance.ordinalSeverity = 0;
250
247
  }
@@ -260,30 +257,34 @@ const doNuVnu = (result, standardResult, docType) => {
260
257
  const items = result[docType] && result[docType].messages;
261
258
  if (items && items.length) {
262
259
  items.forEach(item => {
263
- const identifiers = getIdentifiers(item.extract);
264
- if (! identifiers[0] && item.message) {
265
- const tagNameLCArray = item.message.match(
260
+ const {extract, firstColumn, lastColumn, lastLine, message, subType, type} = item;
261
+ const identifiers = getIdentifiers(extract);
262
+ if (! identifiers[0] && message) {
263
+ const tagNameLCArray = message.match(
266
264
  /^Element ([^ ]+)|^An (img) element| (meta|script) element| element (script)| tag (script)/
267
265
  );
268
266
  if (tagNameLCArray && tagNameLCArray[1]) {
269
267
  identifiers[0] = tagNameLCArray[1].toUpperCase();
270
268
  }
271
269
  }
272
- // Include the message twice. A scoring procedure may replace the ruleID with a pattern.
270
+ let spec = '';
271
+ const locationSegments = [lastLine, firstColumn, lastColumn];
272
+ if (locationSegments.every(segment => typeof segment === 'number')) {
273
+ spec = locationSegments.join(':');
274
+ }
273
275
  const instance = {
274
- ruleID: item.message,
275
- what: item.message,
276
+ ruleID: message,
277
+ what: message,
276
278
  ordinalSeverity: -1,
277
279
  tagName: identifiers[0],
278
280
  id: identifiers[1],
279
281
  location: {
280
282
  doc: docType === 'pageContent' ? 'dom' : 'source',
281
- type: 'line',
282
- spec: item && item.lastLine && item.lastLine.toString() || ''
283
+ type: 'code',
284
+ spec
283
285
  },
284
- excerpt: cap(item.extract)
286
+ excerpt: cap(extract)
285
287
  };
286
- const {type, subType} = item;
287
288
  if (type === 'info' && subType === 'warning') {
288
289
  instance.ordinalSeverity = 0;
289
290
  }