testaro 60.16.1 → 60.17.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.
Files changed (49) hide show
  1. package/package.json +1 -1
  2. package/procs/testaro.js +3 -2
  3. package/testaro/adbID.js +2 -4
  4. package/testaro/allCaps.js +1 -2
  5. package/testaro/allSlanted.js +1 -2
  6. package/testaro/altScheme.js +1 -1
  7. package/testaro/bulk.js +1 -6
  8. package/testaro/buttonMenu.js +1 -6
  9. package/testaro/captionLoc.js +1 -1
  10. package/testaro/datalistRef.js +1 -1
  11. package/testaro/distortion.js +1 -2
  12. package/testaro/elements.js +5 -6
  13. package/testaro/embAc.js +1 -4
  14. package/testaro/focAll.js +1 -7
  15. package/testaro/focAndOp.js +1 -8
  16. package/testaro/focInd.js +3 -10
  17. package/testaro/hovInd.js +1 -1
  18. package/testaro/hover.js +1 -5
  19. package/testaro/hr.js +32 -0
  20. package/testaro/imageLink.js +2 -1
  21. package/testaro/labClash.js +1 -3
  22. package/testaro/legendLoc.js +2 -1
  23. package/testaro/lineHeight.js +1 -4
  24. package/testaro/linkAmb.js +1 -2
  25. package/testaro/linkExt.js +31 -0
  26. package/testaro/linkOldAtt.js +43 -0
  27. package/testaro/linkTo.js +37 -0
  28. package/testaro/linkUl.js +1 -6
  29. package/testaro/motion.js +3 -10
  30. package/testaro/motionSolo.js +3 -14
  31. package/testaro/optRoleSel.js +2 -1
  32. package/testaro/phOnly.js +2 -4
  33. package/testaro/pseudoP.js +54 -0
  34. package/testaro/radioSet.js +1 -3
  35. package/testaro/secHeading.js +1 -5
  36. package/testaro/styleDiff.js +1 -4
  37. package/testaro/tabNav.js +1 -2
  38. package/testaro/targetSmall.js +1 -5
  39. package/testaro/textNodes.js +6 -5
  40. package/testaro/textSem.js +2 -2
  41. package/testaro/titledEl.js +34 -0
  42. package/testaro/zIndex.js +1 -6
  43. package/tests/testaro.js +114 -136
  44. package/testaro/hr.json +0 -10
  45. package/testaro/linkExt.json +0 -10
  46. package/testaro/linkOldAtt.json +0 -10
  47. package/testaro/linkTo.json +0 -10
  48. package/testaro/pseudoP.json +0 -10
  49. package/testaro/titledEl.json +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "60.16.1",
3
+ "version": "60.17.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": {
package/procs/testaro.js CHANGED
@@ -169,12 +169,13 @@ exports.doTest = async (
169
169
  const candidates = document.body.querySelectorAll(candidateSelector);
170
170
  let violationCount = 0;
171
171
  const instances = [];
172
- // Get a violation function.
172
+ // Get a function that returns a violation description, if any, for the candidate.
173
173
  const getBadWhat = eval(`(${getBadWhatString})`);
174
174
  // For each candidate:
175
175
  for (const candidate of candidates) {
176
+ // Get the violation description, if any.
176
177
  const violationWhat = await getBadWhat(candidate);
177
- // If it violates the rule:
178
+ // If the candidate violates the rule:
178
179
  if (violationWhat) {
179
180
  // Increment the violation count.
180
181
  violationCount++;
package/testaro/adbID.js CHANGED
@@ -11,10 +11,8 @@
11
11
 
12
12
  /*
13
13
  adbID
14
- Clean-room rule:This test reports elements referencing aria-describedby targets that are missing
15
- or, because of duplicate IDs, ambiguous. An earlier version of this test was
16
- originally developed under a clean-room procedure to ensure its independence from
17
- the implementation of a test for a similar rule in the Tenon tool.
14
+ Clean-room rule
15
+ This test reports elements referencing aria-describedby targets that are missing or, because of duplicate IDs, ambiguous. An earlier version of this test was originally developed under a clean-room procedure to ensure its independence from the implementation of a test for a similar rule in the Tenon tool.
18
16
  */
19
17
 
20
18
  // IMPORTS
@@ -11,8 +11,7 @@
11
11
  /*
12
12
  allCaps
13
13
  Related to Tenon rule 153.
14
- This test reports elements with native or transformed upper-case text at least 8 characters long.
15
- Blocks of upper-case text are difficult to read.
14
+ This test reports elements with native or transformed upper-case text at least 8 characters long. Blocks of upper-case text are difficult to read.
16
15
  */
17
16
 
18
17
  // ########## IMPORTS
@@ -11,8 +11,7 @@
11
11
  /*
12
12
  allSlanted
13
13
  Related to Tenon rule 154.
14
- This test reports elements with italic or oblique text at least 40 characters long. Blocks of
15
- slanted text are difficult to read.
14
+ This test reports elements with italic or oblique text at least 40 characters long. Blocks of slanted text are difficult to read.
16
15
  */
17
16
 
18
17
  // ########## IMPORTS
@@ -11,7 +11,7 @@
11
11
 
12
12
  /*
13
13
  altScheme
14
- Identify img elements whose alt attribute is a URL or file name.
14
+ This test reports img elements whose alt attributes are URLs or file names.
15
15
  */
16
16
 
17
17
  // IMPORTS
package/testaro/bulk.js CHANGED
@@ -10,12 +10,7 @@
10
10
 
11
11
  /*
12
12
  bulk
13
- This test reports the count of visible elements.
14
-
15
- The test assumes that simplicity and compactness, with one page having one purpose,
16
- is an accessibility virtue. Users with visual, motor, and cognitive disabilities
17
- often have trouble finding what they want or understanding the purpose of a page
18
- if the page is cluttered with content.
13
+ This test reports the count of visible elements. The test assumes that simplicity and compactness, with one page having one purpose, is an accessibility virtue. Users with visual, motor, and cognitive disabilities often have trouble finding what they want or understanding the purpose of a page if the page is cluttered with content.
19
14
  */
20
15
  exports.reporter = async page => {
21
16
  // Get a count of elements deemed visible by Playwright.
@@ -10,12 +10,7 @@
10
10
 
11
11
  /*
12
12
  buttonMenu
13
- This test reports nonstandard navigation among menu items of button-controlled menus.
14
- Standards are based on https://www.w3.org/TR/wai-aria-practices-1.1/#menu. The trialKeys argument
15
- is an array of strings, each of which may be 'Home', 'End', '+', or '-'. The '+' string represents
16
- the ArrowDown or ArrowRight key, and the '-' string represents the ArrowUp or ArrowLeft key,
17
- depending on the orientation of the current menu. When the trialKeys argument is missing or is an
18
- empty array, 12 keys are selected at random.
13
+ This test reports nonstandard navigation among menu items of button-controlled menus. Standards are based on https://www.w3.org/TR/wai-aria-practices-1.1/#menu. The trialKeys argument is an array of strings, each of which may be 'Home', 'End', '+', or '-'. The '+' string represents the ArrowDown or ArrowRight key, and the '-' string represents the ArrowUp or ArrowLeft key, depending on the orientation of the current menu. When the trialKeys argument is missing or is an empty array, 12 keys are selected at random.
19
14
  */
20
15
 
21
16
  // ########## IMPORTS
@@ -11,7 +11,7 @@
11
11
 
12
12
  /*
13
13
  captionLoc
14
- Report caption elements that are not the first children of table elements.
14
+ This test reports caption elements that are not the first children of table elements.
15
15
  */
16
16
 
17
17
  // IMPORTS
@@ -11,7 +11,7 @@
11
11
 
12
12
  /*
13
13
  datalistRef
14
- Report inputs whose list attribute references a missing or ambiguous datalist
14
+ This test reports inputs whose list attributes reference missing or ambiguous datalists.
15
15
  */
16
16
 
17
17
  // IMPORTS
@@ -11,8 +11,7 @@
11
11
  /*
12
12
  distortion
13
13
  Related to Tenon rule 271.
14
- This test reports elements whose transform style properties distort the content. Distortion makes
15
- text difficult to read.
14
+ This test reports elements whose transform style properties distort the content. Distortion makes text difficult to read.
16
15
  */
17
16
 
18
17
  // ########## IMPORTS
@@ -9,12 +9,11 @@
9
9
 
10
10
  /*
11
11
  elements
12
- This test reports data about specified elements within the document body.
13
- Meanings of detailLevel values:
14
- 0. Only total element count; no detail.
15
- 1. Also data on each specified element.
16
- 2. Data on each specified element also include the text content of the parent element.
17
- 3. Data on each specified element also include data on its sibling nodes.
12
+ This test reports data about specified elements within the document body. Meanings of detailLevel values:
13
+ 0. Only total element count; no detail.
14
+ 1. Also data on each specified element.
15
+ 2. Data on each specified element also include the text content of the parent element.
16
+ 3. Data on each specified element also include data on its sibling nodes.
18
17
  */
19
18
  exports.reporter = async (
20
19
  page, withItems, detailLevel = 0, tagName = null, onlyVisible = false, attribute
package/testaro/embAc.js CHANGED
@@ -9,10 +9,7 @@
9
9
 
10
10
  /*
11
11
  embAc
12
- This test reports interactive elements (links, buttons, inputs, and select lists)
13
- contained by links or buttons. Such embedding not only violates the HTML standard,
14
- but also complicates user interaction and creates risks of error. It becomes
15
- non-obvious what a user will activate with a click.
12
+ This test reports interactive elements (links, buttons, inputs, and select lists) contained by links or buttons. Such embedding not only violates the HTML standard, but also complicates user interaction and creates risks of error. It becomes non-obvious what a user will activate with a click.
16
13
  */
17
14
 
18
15
  // IMPORTS
package/testaro/focAll.js CHANGED
@@ -10,13 +10,7 @@
10
10
 
11
11
  /*
12
12
  focAll
13
- This test reports discrepancies between focusable and Tab-focused element counts. The test first
14
- counts all the visible focusable (i.e. with tabIndex 0) elements (except counting each group of
15
- radio buttons as only one focusable element). Then it repeatedly presses the Tab (or Option-Tab
16
- in webkit) key until it has reached all the elements it can and counts those elements. If the
17
- two counts differ, navigation can be made more difficult. The cause may be surprising changes in
18
- content during navigation with the Tab key, or inability to reach every focusable element (or
19
- widget, such as one radio button or tab in each group) merely by pressing the Tab key.
13
+ This test reports discrepancies between focusable and Tab-focused element counts. The test first counts all the visible focusable (i.e. with tabIndex 0) elements (except counting each group of radio buttons as only one focusable element). Then it repeatedly presses the Tab (or Option-Tab in webkit) key until it has reached all the elements it can and counts those elements. If the two counts differ, navigation can be made more difficult. The cause may be surprising changes in content during navigation with the Tab key, or inability to reach every focusable element (or widget, such as one radio button or tab in each group) merely by pressing the Tab key.
20
14
  */
21
15
  exports.reporter = async page => {
22
16
  // Get locators of visible elements.
@@ -12,14 +12,7 @@
12
12
  focAndOp
13
13
  Related to Tenon rule 190.
14
14
 
15
- This test reports discrepancies between Tab-focusability and operability. The standard practice
16
- is to make focusable elements operable and operable elements focusable. If focusable elements are
17
- not operable, users are likely to be surprised that nothing happens when they try to operate such
18
- elements. Conversely, if operable elements are not focusable, users who navigate with a
19
- keyboard are prevented from operating those elements. The test considers an element
20
- Tab-focusable if its tabIndex property has the value 0. The test considers an element operable if
21
- it has a non-inherited pointer cursor and is not a 'LABEL' element, has an operable tag name, has
22
- an interactive explicit role, or has an 'onclick' attribute.
15
+ This test reports discrepancies between Tab-focusability and operability. The standard practice is to make focusable elements operable and operable elements focusable. If focusable elements are not operable, users are likely to be surprised that nothing happens when they try to operate such elements. Conversely, if operable elements are not focusable, users who navigate with a keyboard are prevented from operating those elements. The test considers an element Tab-focusable if its tabIndex property has the value 0. The test considers an element operable if it has a non-inherited pointer cursor and is not a 'LABEL' element, has an operable tag name, has an interactive explicit role, or has an 'onclick' attribute.
23
16
  */
24
17
 
25
18
  // IMPORTS
package/testaro/focInd.js CHANGED
@@ -11,18 +11,11 @@
11
11
  /*
12
12
  focInd
13
13
 
14
- This test reports focusable elements without standard focus indicators. The standard focus
15
- indicator is deemed to be a solid outline with a line thickness of at least 2 pixels and a
16
- non-transparent color, and only if the element, when not focused, has no outline.
14
+ This test reports focusable elements without standard focus indicators. The standard focus indicator is deemed to be a solid outline with a line thickness of at least 2 pixels and a non-transparent color, and only if the element, when not focused, has no outline.
17
15
 
18
- The focus indicator is checked immediately after the element is focused. Thus, a delayed focus
19
- indicator is ignored. Indication delayed is treated as indication denied. The bases for this
20
- treatment are that delayed indication interferes with rapid human or mechanized document
21
- consumption and also, if it must be respected, slows accessibility testing.
16
+ The focus indicator is checked immediately after the element is focused. Thus, a delayed focus indicator is ignored. Indication delayed is treated as indication denied. The bases for this treatment are that delayed indication interferes with rapid human or mechanized document consumption and also, if it must be respected, slows accessibility testing.
22
17
 
23
- Solid outlines are the standard and thus most familiar focus indicator. Other focus indicators
24
- are likely to be misunderstood. For example, underlines may be mistaken for selection or link
25
- indicators.
18
+ Solid outlines are the standard and thus most familiar focus indicator. Other focus indicators are likely to be misunderstood. For example, underlines may be mistaken for selection or link indicators.
26
19
 
27
20
  WARNING: This test fails to recognize outlines when run with firefox.
28
21
  */
package/testaro/hovInd.js CHANGED
@@ -11,7 +11,7 @@
11
11
  /*
12
12
  hovInd
13
13
  This test reports nonstandard hover indication.
14
- */
14
+ */
15
15
 
16
16
  // IMPORTS
17
17
 
package/testaro/hover.js CHANGED
@@ -10,11 +10,7 @@
10
10
 
11
11
  /*
12
12
  hover
13
- This test reports unexpected impacts of hovering. The elements that are subjected to hovering
14
- (called “triggers”) include all the elements that have attributes associated with control over
15
- the visibility of other elements. If hovering over an element results in an increase or decrease
16
- in the total count of visible elements in the tree rooted in the grandparent of the trigger,
17
- the rule is considered violated.
13
+ This test reports unexpected impacts of hovering. The elements that are subjected to hovering (called “triggers”) include all the elements that have attributes associated with control over the visibility of other elements. If hovering over an element results in an increase or decrease in the total count of visible elements in the tree rooted in the grandparent of the trigger, the rule is considered violated.
18
14
  */
19
15
 
20
16
  // IMPORTS
package/testaro/hr.js ADDED
@@ -0,0 +1,32 @@
1
+ /*
2
+ © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2025 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or
6
+ https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+
11
+ /*
12
+ hr
13
+ This test reports the use of hr elements.
14
+ */
15
+
16
+ // IMPORTS
17
+
18
+ const {doTest} = require('../procs/testaro');
19
+
20
+ // FUNCTIONS
21
+
22
+ // Runs the test and returns the result.
23
+ exports.reporter = async (page, withItems) => {
24
+ const getBadWhat = element => {
25
+ // Return a violation description.
26
+ return `hr element is used for vertical segmentation`;
27
+ }
28
+ const whats = 'HR elements are used for vertical segmentation';
29
+ return await doTest(
30
+ page, withItems, 'hr', 'hr', whats, 0, 'HR', getBadWhat.toString()
31
+ );
32
+ };
@@ -10,7 +10,8 @@
10
10
 
11
11
  /*
12
12
  imageLink
13
- Clean-room rule: flag anchor elements whose `href` points to an image file.
13
+ Clean-room rule.
14
+ This test reports anchor elements whose href attributes point to image files.
14
15
  */
15
16
 
16
17
  const {simplify} = require('../procs/testaro');
@@ -10,9 +10,7 @@
10
10
 
11
11
  /*
12
12
  labClash
13
- This test reports redundant labeling of buttons, non-hidden inputs, select lists, and text areas.
14
- Redundant labels are labels that are superseded by other labels. Explicit and implicit (wrapped)
15
- labels are additive, not conflicting.
13
+ This test reports redundant labeling of buttons, non-hidden inputs, select lists, and text areas. Redundant labels are labels that are superseded by other labels. Explicit and implicit (wrapped) labels are additive, not conflicting.
16
14
  */
17
15
 
18
16
  // IMPORTS
@@ -10,7 +10,8 @@
10
10
 
11
11
  /*
12
12
  legendLoc
13
- Clean-room rule: flag legend elements that are not the first child of a fieldset element.
13
+ Clean-room rule.
14
+ This test reports legend elements that are not the first children of fieldset elements.
14
15
  */
15
16
 
16
17
  const {simplify} = require('../procs/testaro');
@@ -11,10 +11,7 @@
11
11
  /*
12
12
  lineHeight
13
13
  Related to Tenon rule 144.
14
- This test reports elements whose line heights are less than 1.5 times their font sizes. Even
15
- such elements with no text create accessibility risk, because any text node added to one of
16
- them would have a substandard line height. Nonetheless, elements with no non-spacing text in
17
- their subtrees are excluded.
14
+ This test reports elements whose line heights are less than 1.5 times their font sizes. Even such elements with no text create accessibility risk, because any text node added to one of them would have a substandard line height. Nonetheless, elements with no non-spacing text in their subtrees are excluded.
18
15
  */
19
16
 
20
17
  // IMPORTS
@@ -11,8 +11,7 @@
11
11
  /*
12
12
  linkAmb
13
13
  Related to Tenon rule 98.
14
- This test reports text contents that are shared by links with distinct destinations.
15
- Text contents are compared case-insensitively.
14
+ This test reports text contents that are shared by links with distinct destinations. Text contents are compared case-insensitively.
16
15
  */
17
16
 
18
17
  // FUNCTIONS
@@ -0,0 +1,31 @@
1
+ /*
2
+ © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2025 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or
6
+ https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+
11
+ /*
12
+ linkExt
13
+ This test reports links with target=_blank attributes.
14
+ */
15
+
16
+ // IMPORTS
17
+
18
+ const {doTest} = require('../procs/testaro');
19
+
20
+ // FUNCTIONS
21
+
22
+ exports.reporter = async (page, withItems) => {
23
+ const getBadWhat = element => {
24
+ // Return a violation description.
25
+ return `Link has a target=_blank attribute`;
26
+ };
27
+ const whats = 'Links have target=_blank attributes';
28
+ return await doTest(
29
+ page, withItems, 'linkExt', 'a[target=_blank]', whats, 0, 'A', getBadWhat.toString()
30
+ );
31
+ };
@@ -0,0 +1,43 @@
1
+ /*
2
+ © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2025 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or
6
+ https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+
11
+ /*
12
+ linkOldAtt
13
+ This test reports links with deprecated attributes.
14
+ */
15
+
16
+ // IMPORTS
17
+
18
+ const {doTest} = require('../procs/testaro');
19
+
20
+ // FUNCTIONS
21
+
22
+ exports.reporter = async (page, withItems) => {
23
+ const getBadWhat = element => {
24
+ const attNames = element.getAttributeNames();
25
+ const allBadAttNames = ['charset', 'coords', 'name', 'rev', 'shape'];
26
+ const elementBadAttNames = allBadAttNames.filter(att => attNames.includes(att));
27
+ // If the element has 1 deprecated attribute:
28
+ if (elementBadAttNames.length === 1) {
29
+ // Return a violation description.
30
+ return `${elementBadAttNames[0]} attribute is deprecated`;
31
+ }
32
+ // Otherwise, if the element has 2 or more deprecated attributes:
33
+ if (elementBadAttNames.length > 1) {
34
+ // Return a violation description.
35
+ return `Element has deprecated attributes: ${elementBadAttNames.join(', ')}`;
36
+ }
37
+ };
38
+ const selector = 'a[charset], a[coords], a[name], a[rev], a[shape]';
39
+ const whats = 'Links have deprecated attributes';
40
+ return await doTest(
41
+ page, withItems, 'linkOldAtt', selector, whats, 1, 'A', getBadWhat.toString()
42
+ );
43
+ };
@@ -0,0 +1,37 @@
1
+ /*
2
+ © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2025 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or
6
+ https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+ /*
11
+ linkTo
12
+ This test reports links without href attributes.
13
+ */
14
+ // IMPORTS
15
+
16
+ const {doTest} = require('../procs/testaro');
17
+
18
+ // FUNCTIONS
19
+
20
+ exports.reporter = async (page, withItems) => {
21
+ const getBadWhat = element => {
22
+ const isVisible = element.checkVisibility({
23
+ contentVisibilityAuto: true,
24
+ opacityProperty: true,
25
+ visibilityProperty: true
26
+ });
27
+ // If the element is visible:
28
+ if (isVisible) {
29
+ // Return a violation description.
30
+ return `Element has no href attribute`;
31
+ }
32
+ };
33
+ const whats = 'Links are missing href attributes';
34
+ return await doTest(
35
+ page, withItems, 'linkTo', 'a:not([href]', whats, 2, 'A', getBadWhat.toString()
36
+ );
37
+ };
package/testaro/linkUl.js CHANGED
@@ -10,12 +10,7 @@
10
10
 
11
11
  /*
12
12
  linkUl
13
- This test reports failures to underline inline links. Underlining and color are the traditional
14
- style properties that identify links. Lists of links containing only links can be recognized
15
- without underlines, but other links are difficult or impossible to distinguish visually from
16
- surrounding text if not underlined. Underlining adjacent links only on hover provides an
17
- indicator valuable only to mouse users, and even they must traverse the text with a mouse
18
- merely to discover which passages are links.
13
+ This test reports failures to underline inline links. Underlining and color are the traditional style properties that identify links. Lists of links containing only links can be recognized without underlines, but other links are difficult or impossible to distinguish visually from surrounding text if not underlined. Underlining adjacent links only on hover provides an indicator valuable only to mouse users, and even they must traverse the text with a mouse merely to discover which passages are links.
19
14
  */
20
15
 
21
16
  // ########## IMPORTS
package/testaro/motion.js CHANGED
@@ -5,18 +5,11 @@
5
5
 
6
6
  /*
7
7
  motion
8
- This test reports motion in a page by comparing the first and last of the screenshots previously
9
- made by the shoot0 and shoot1 tests.
8
+ This test reports motion in a page by comparing the first and last of the screenshots previously made by the shoot0 and shoot1 tests.
10
9
 
11
- For minimal accessibility, standards require motion to be brief, or else stoppable by the user.
12
- But stopping motion can be difficult or impossible, and, by the time a user manages to stop
13
- motion, the motion may have caused annoyance or harm. For superior accessibility, a page contains
14
- no motion until and unless the user authorizes it. The test reports a rule violation if any
15
- pixels differ between the screenshots. The larger the change fraction, the greater the
16
- ordinal severity.
10
+ For minimal accessibility, standards require motion to be brief, or else stoppable by the user. But stopping motion can be difficult or impossible, and, by the time a user manages to stop motion, the motion may have caused annoyance or harm. For superior accessibility, a page contains no motion until and unless the user authorizes it. The test reports a rule violation if any pixels differ between the screenshots. The larger the change fraction, the greater the ordinal severity.
17
11
 
18
- WARNING: The shoot test uses the procs/screenShot module. See the warning in that module about
19
- browser types.
12
+ WARNING: The shoot test uses the procs/screenShot module. See the warning in that module about browser types.
20
13
  */
21
14
 
22
15
  // IMPORTS
@@ -10,22 +10,11 @@
10
10
 
11
11
  /*
12
12
  motion
13
- This test reports motion in a page. For minimal accessibility, standards require motion to be
14
- brief, or else stoppable by the user. But stopping motion can be difficult or impossible, and,
15
- by the time a user manages to stop motion, the motion may have caused annoyance or harm. For
16
- superior accessibility, a page contains no motion until and unless the user authorizes it. The
17
- test compares two screen shots of the viewport 2 seconds and 6 seconds after page load. It
18
- reports a rule violation if any pixels change. The larger the change fraction, the greater the
19
- ordinal severity.
13
+ This test reports motion in a page. For minimal accessibility, standards require motion to be brief, or else stoppable by the user. But stopping motion can be difficult or impossible, and, by the time a user manages to stop motion, the motion may have caused annoyance or harm. For superior accessibility, a page contains no motion until and unless the user authorizes it. The test compares two screen shots of the viewport 2 seconds and 6 seconds after page load. It reports a rule violation if any pixels change. The larger the change fraction, the greater the ordinal severity.
20
14
 
21
- This test is an alternative to the motion test. Whereas the motion test relies on screenshots made
22
- earlier in the same job by the shoot test, this test makes its own screenshots. MotionSolo waits
23
- several seconds between its screenshots to allow time for motion to occur. That mait makes
24
- motionSolo, and any job containing it, take longer than the combination of shoot tests and the
25
- motion test.
15
+ This test is an alternative to the motion test. Whereas the motion test relies on screenshots made earlier in the same job by the shoot test, this test makes its own screenshots. MotionSolo waits several seconds between its screenshots to allow time for motion to occur. That wait makes motionSolo, and any job containing it, take longer than the combination of shoot tests and the motion test.
26
16
 
27
- WARNING: This test uses the procs/visChange module. See the warning in that module about browser
28
- types.
17
+ WARNING: This test uses the procs/visChange module. See the warning in that module about browser types.
29
18
  */
30
19
 
31
20
  // IMPORTS
@@ -10,7 +10,8 @@
10
10
 
11
11
  /*
12
12
  optRoleSel
13
- Clean-room rule: elements with role="option" should have an aria-selected attribute.
13
+ Clean-room rule.
14
+ This test reports elements with role="option" that are missing aria-selected attributes.
14
15
  */
15
16
 
16
17
  const {simplify} = require('../procs/testaro');
package/testaro/phOnly.js CHANGED
@@ -11,10 +11,8 @@
11
11
 
12
12
  /*
13
13
  phOnly
14
- Clean-room rule: This test reports input elements that have placeholders but no accessible names.
15
- The standard for accessible name computation is employed; it accepts title attributes as
16
- sources for accessible names. Thus, this test does not report reliance on title attributes for
17
- accessible names, although such reliance is generally considered a poor practice.
14
+ Clean-room rule.
15
+ This test reports input elements that have placeholders but no accessible names. The standard for accessible name computation is employed; it accepts title attributes as sources for accessible names. Thus, this test does not report reliance on title attributes for accessible names, although such reliance is generally considered a poor practice.
18
16
  */
19
17
 
20
18
  // IMPORTS
@@ -0,0 +1,54 @@
1
+ /*
2
+ © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2025 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or
6
+ https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+ /*
11
+ pseudoP
12
+ This test reports 2 or more sequential br elements without intervening text content. They may be inferior substitutes for p elements.
13
+ */
14
+
15
+ // IMPORTS
16
+
17
+ const {doTest} = require('../procs/testaro');
18
+
19
+ // FUNCTIONS
20
+
21
+ exports.reporter = async (page, withItems) => {
22
+ const getBadWhat = element => {
23
+ // Get the node before the element node.
24
+ const previousNode = element.previousSibling;
25
+ let isBad = false;
26
+ // If it is a br element:
27
+ if (previousNode && previousNode.nodeType === Node.ELEMENT_NODE && previousNode.tagName === 'BR') {
28
+ // Classify the element as a violator.
29
+ isBad = true;
30
+ }
31
+ // Otherwise, if it is a text node:
32
+ else if (previousNode && previousNode.nodeType === Node.TEXT_NODE) {
33
+ // If the text node contains only whitespace:
34
+ if (previousNode.textContent.trim() === '') {
35
+ // Get the node before the text node.
36
+ const beforeText = previousNode.previousSibling;
37
+ // If that node is a br element:
38
+ if (beforeText && beforeText.nodeType === Node.ELEMENT_NODE && beforeText.tagName === 'BR') {
39
+ // Classify the element as a violator.
40
+ isBad = true;
41
+ }
42
+ }
43
+ }
44
+ // If the element is a violator:
45
+ if (isBad) {
46
+ // Return a violation description.
47
+ return `Element follows another br element, possibly constituting a pseudo-paragraph`;
48
+ }
49
+ };
50
+ const whats = 'br elements follow other br elements, possibly constituting pseudo-paragraphs';
51
+ return await doTest(
52
+ page, withItems, 'pseudoP', 'body br', whats, 0, 'BR', getBadWhat.toString()
53
+ );
54
+ };
@@ -10,9 +10,7 @@
10
10
 
11
11
  /*
12
12
  radioSet
13
- This test reports nonstandard groupings of radio buttons. It defines a standard grouping to
14
- require that two or more radio buttons with the same name, and no other radio buttons, be grouped
15
- in a fieldset element with a valid legend element.
13
+ This test reports nonstandard groupings of radio buttons. It defines a standard grouping to require that two or more radio buttons with the same name, and no other radio buttons, be grouped in a fieldset element with a valid legend element.
16
14
  */
17
15
 
18
16
  // IMPORTS
@@ -11,11 +11,7 @@
11
11
 
12
12
  /*
13
13
  secHeading
14
- This test reports sectioning containers that have child headings of which the first has a depth
15
- (i.e. level) lower than at least one of the others. An example is a section element whose first
16
- heading child is an h3 element and whose subsequent heading children include an h2 element. The
17
- first child heading is presumed the principal heading of the container, so this pattern merits
18
- scrutiny.
14
+ This test reports sectioning containers that have child headings of which the first has a depth (i.e. level) lower than at least one of the others. An example is a section element whose first heading child is an h3 element and whose subsequent heading children include an h2 element. The first child heading is presumed the principal heading of the container, so this pattern merits scrutiny.
19
15
  */
20
16
 
21
17
  // IMPORTS
@@ -9,10 +9,7 @@
9
9
 
10
10
  /*
11
11
  styleDiff
12
- This test reports style differences among links, buttons, and headings. It assumes
13
- that an accessible page employs few or only one style for adjacent links, and likewise
14
- for list links, buttons, and headings at each level. The test considers only
15
- particular style properties, listed in the 'mainStyles' and 'headingStyles' arrays.
12
+ This test reports style differences among links, buttons, and headings. It assumes that an accessible page employs few or only one style for adjacent links, and likewise for list links, buttons, and headings at each level. The test considers only particular style properties, listed in the 'mainStyles' and 'headingStyles' arrays.
16
13
  */
17
14
 
18
15
  // FUNCTIONS
package/testaro/tabNav.js CHANGED
@@ -10,8 +10,7 @@
10
10
 
11
11
  /*
12
12
  tabNav
13
- This test reports nonstandard keyboard navigation among tab elements in visible tab lists.
14
- Standards are based on https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel.
13
+ This test reports nonstandard keyboard navigation among tab elements in visible tab lists. Standards are based on https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel.
15
14
  */
16
15
 
17
16
  // CONSTANTS
@@ -11,11 +11,7 @@
11
11
  /*
12
12
  targetSmall
13
13
  Related to Tenon rule 152.
14
- This test reports visible pointer targets, i.e. labels, buttons, inputs, and links, that are
15
- small enough or near enough to other targets to make pointer interaction difficult. This test
16
- relates to WCAG 2.2 Success Criteria 2.5.5 and 2.5.8, but does not attempt to implement either
17
- of them precisely. For example, the test reports a small pointer target that is far from all
18
- other targets, although it conforms to the Success Criteria.
14
+ This test reports visible pointer targets, i.e. labels, buttons, inputs, and links, that are small enough or near enough to other targets to make pointer interaction difficult. This test relates to WCAG 2.2 Success Criteria 2.5.5 and 2.5.8, but does not attempt to implement either of them precisely. For example, the test reports a small pointer target that is far from all other targets, although it conforms to the Success Criteria.
19
15
  */
20
16
 
21
17
  // FUNCTIONS
@@ -9,12 +9,13 @@
9
9
 
10
10
  /*
11
11
  textNodes
12
- This test reports data about specified text nodes.
13
- Meanings of detailLevel values:
14
- 0. Only total node count; no detail.
15
- 1-3. Count of ancestry levels to provide data on (1 = text node, 2 = also parent,
16
- 3 = also grandparent)
12
+ This test reports data about specified text nodes. Meanings of detailLevel values:
13
+ 0. Only total node count; no detail.
14
+ 1-3. Count of ancestry levels to provide data on (1 = text node, 2 = also parent, 3 = also grandparent)
17
15
  */
16
+
17
+ // FUNCTIONS
18
+
18
19
  exports.reporter = async (page, withItems, detailLevel, text = '') => {
19
20
  let data = {};
20
21
  // Get the data on the text nodes.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  © 2025 CVS Health and/or one of its affiliates. All rights reserved.
3
- © 2025 Juan S. Casado.
3
+ © 2025 Jonathan Robert Pool.
4
4
 
5
5
  Licensed under the MIT License. See LICENSE file at the project root or
6
6
  https://opensource.org/license/mit/ for details.
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  textSem
13
- Report semantically vague inline elements: i, b, small
13
+ This test reports semantically vague inline elements: i, b, small.
14
14
  */
15
15
 
16
16
  // IMPORTS
@@ -0,0 +1,34 @@
1
+ /*
2
+ © 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2025 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or
6
+ https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+
11
+ /*
12
+ titledEl
13
+ This test reports suspicious use of title attributes.
14
+ */
15
+
16
+ // IMPORTS
17
+
18
+ const {doTest} = require('../procs/testaro');
19
+
20
+ // FUNCTIONS
21
+
22
+ // Runs the test and returns the result.
23
+ exports.reporter = async (page, withItems) => {
24
+ const getBadWhat = element => {
25
+ const elementType = element.tagName.toLowerCase();
26
+ // Return a violation description.
27
+ return `Likely ineffective title attribute is used on the ${elementType} element`;
28
+ }
29
+ const selector = '[title]:not(iframe, link, style)';
30
+ const whats = 'title attributes are used on elements they are likely ineffective on';
31
+ return await doTest(
32
+ page, withItems, 'titledEl', selector, whats, 0, null, getBadWhat.toString()
33
+ );
34
+ };
package/testaro/zIndex.js CHANGED
@@ -10,12 +10,7 @@
10
10
 
11
11
  /*
12
12
  zIndex
13
- This test reports elements with abnormal Z indexes. It assumes that pages are most accessible
14
- when they do not require users to perceive a third dimension (depth). Layers, popups, and dialogs
15
- that cover other content make it difficult for some or all users to interpret the content and
16
- know what parts of the content can be acted on. Layering also complicates accessibility testing.
17
- Tests for visibility of focus, for example, may fail if incapable of detecting that a focused
18
- element is covered by another element. Z indexes other than auto and 0 are considered abnormal.
13
+ This test reports elements with abnormal Z indexes. It assumes that pages are most accessible when they do not require users to perceive a third dimension (depth). Layers, popups, and dialogs that cover other content make it difficult for some or all users to interpret the content and know what parts of the content can be acted on. Layering also complicates accessibility testing. Tests for visibility of focus, for example, may fail if incapable of detecting that a focused element is covered by another element. Z indexes other than auto and 0 are considered abnormal.
19
14
  */
20
15
 
21
16
  // IMPORTS
package/tests/testaro.js CHANGED
@@ -547,158 +547,136 @@ exports.reporter = async (page, report, actIndex) => {
547
547
  };
548
548
  browser.on('disconnected', disconnectHandler);
549
549
  }
550
- // Initialize an argument array for reporter or jsonTest.
550
+ // Initialize an argument array for the reporter.
551
551
  const ruleArgs = [page, withItems];
552
- const ruleFileNames = await fs.readdir(`${__dirname}/../testaro`);
553
- const isJS = ruleFileNames.includes(`${ruleID}.js`);
554
- const isJSON = ruleFileNames.includes(`${ruleID}.json`);
555
- // If the rule is defined with JavaScript or JSON but not both:
556
- if ((isJS || isJSON) && ! (isJS && isJSON)) {
557
- // If with JavaScript and it has extra arguments:
558
- if (isJS && argRules && argRules.includes(ruleID)) {
559
- // Add them to the argument array.
560
- ruleArgs.push(... args[ruleID]);
561
- }
562
- result[ruleID] ??= {};
563
- const ruleResult = result[ruleID];
564
- const {what} = rule;
565
- ruleResult.what = what || '';
566
- const startTime = Date.now();
567
- let timeout;
568
- let testRetries = 2;
569
- let testSuccess = false;
570
- while (testRetries > 0 && ! testSuccess) {
571
- try {
572
- // Apply a time limit to the test.
573
- const timeLimit = 1000 * timeoutMultiplier * rule.timeOut;
574
- // If the time limit expires during the test:
575
- const timer = new Promise(resolve => {
576
- timeout = setTimeout(() => {
577
- // Add data about the test, including its prevention, to the result.
578
- const endTime = Date.now();
579
- testTimes.push([rule, Math.round((endTime - startTime) / 1000)]);
580
- data.rulePreventions.push(ruleID);
581
- data.rulePreventionMessages[ruleID] = 'Timeout';
582
- ruleResult.totals = [0, 0, 0, 0];
583
- ruleResult.standardInstances = [];
584
- console.log(`ERROR: Test of testaro rule ${ruleID} timed out`);
585
- resolve({timedOut: true});
586
- }, timeLimit);
587
- });
588
- // Perform the test, subject to the time limit.
589
- const ruleReport = isJS
590
- ? require(`../testaro/${ruleID}`).reporter(... ruleArgs)
591
- : jsonTest(ruleID, ruleArgs);
592
- // Get the test result or a timeout result.
593
- const ruleOrTimeoutReport = await Promise.race([timer, ruleReport]);
594
- // If the test was completed:
595
- if (! ruleOrTimeoutReport.timedOut) {
596
- // Add data from the test to the result.
552
+ // If the rule has extra arguments:
553
+ if (argRules && argRules.includes(ruleID)) {
554
+ // Add them to the argument array.
555
+ ruleArgs.push(... args[ruleID]);
556
+ }
557
+ result[ruleID] ??= {};
558
+ const ruleResult = result[ruleID];
559
+ const {what} = rule;
560
+ ruleResult.what = what || '';
561
+ const startTime = Date.now();
562
+ let timeout;
563
+ let testRetries = 2;
564
+ let testSuccess = false;
565
+ // Until all permitted retries are exhausted or the test succeeds:
566
+ while (testRetries > 0 && ! testSuccess) {
567
+ try {
568
+ // Apply a time limit to the test.
569
+ const timeLimit = 1000 * timeoutMultiplier * rule.timeOut;
570
+ // If the time limit expires during the test:
571
+ const timer = new Promise(resolve => {
572
+ timeout = setTimeout(() => {
573
+ // Add data about the test, including its prevention, to the result.
597
574
  const endTime = Date.now();
598
- testTimes.push([ruleID, Math.round((endTime - startTime) / 1000)]);
599
- Object.keys(ruleOrTimeoutReport).forEach(key => {
600
- ruleResult[key] = ruleOrTimeoutReport[key];
601
- });
602
- // If the test was prevented:
603
- if (ruleResult.data?.prevented && ruleResult.data.error) {
604
- // Add this to the result.
605
- data.rulePreventions.push(ruleID);
606
- data.rulePreventionMessages[ruleID] = ruleResult.data.error;
607
- }
608
- // If the result includes totals:
609
- if (ruleResult.totals) {
610
- // Round them.
611
- ruleResult.totals = ruleResult.totals.map(total => Math.round(total));
612
- }
613
- // Prevent a retry of the test.
614
- testSuccess = true;
615
- // If testing is to stop after a failure and the page failed the test:
616
- if (stopOnFail && ruleResult.totals && ruleResult.totals.some(total => total)) {
617
- // Stop testing.
618
- break;
619
- }
620
- }
621
- // Otherwise, i.e. if the test timed out:
622
- else {
623
- // Report this.
575
+ testTimes.push([rule, Math.round((endTime - startTime) / 1000)]);
624
576
  data.rulePreventions.push(ruleID);
625
577
  data.rulePreventionMessages[ruleID] = 'Timeout';
626
- // Stop retrying the test.
578
+ ruleResult.totals = [0, 0, 0, 0];
579
+ ruleResult.standardInstances = [];
580
+ console.log(`ERROR: Test of testaro rule ${ruleID} timed out`);
581
+ resolve({timedOut: true});
582
+ }, timeLimit);
583
+ });
584
+ // Perform the test, subject to the time limit.
585
+ const ruleReport = require(`../testaro/${ruleID}`).reporter(... ruleArgs);
586
+ // Get the test result or a timeout result.
587
+ const ruleOrTimeoutReport = await Promise.race([timer, ruleReport]);
588
+ // If the test was completed:
589
+ if (! ruleOrTimeoutReport.timedOut) {
590
+ // Add data from the test to the result.
591
+ const endTime = Date.now();
592
+ testTimes.push([ruleID, Math.round((endTime - startTime) / 1000)]);
593
+ Object.keys(ruleOrTimeoutReport).forEach(key => {
594
+ ruleResult[key] = ruleOrTimeoutReport[key];
595
+ });
596
+ // If the test was prevented:
597
+ if (ruleResult.data?.prevented && ruleResult.data.error) {
598
+ // Add this to the result.
599
+ data.rulePreventions.push(ruleID);
600
+ data.rulePreventionMessages[ruleID] = ruleResult.data.error;
601
+ }
602
+ // If the result includes totals:
603
+ if (ruleResult.totals) {
604
+ // Round them.
605
+ ruleResult.totals = ruleResult.totals.map(total => Math.round(total));
606
+ }
607
+ // Prevent a retry of the test.
608
+ testSuccess = true;
609
+ // If testing is to stop after a failure and the page failed the test:
610
+ if (stopOnFail && ruleResult.totals && ruleResult.totals.some(total => total)) {
611
+ // Stop testing.
627
612
  break;
628
613
  }
629
614
  }
630
- // If an error is thrown by the test:
631
- catch(error) {
632
- const isPageClosed = ['closed', 'Protocol error', 'Target page'].some(phrase =>
633
- error.message.includes(phrase)
615
+ // Otherwise, i.e. if the test timed out:
616
+ else {
617
+ // Report this.
618
+ data.rulePreventions.push(ruleID);
619
+ data.rulePreventionMessages[ruleID] = 'Timeout';
620
+ // Stop retrying the test.
621
+ break;
622
+ }
623
+ }
624
+ // If an error is thrown by the test:
625
+ catch(error) {
626
+ const isPageClosed = ['closed', 'Protocol error', 'Target page'].some(phrase =>
627
+ error.message.includes(phrase)
628
+ );
629
+ // If the page has closed and there are retries left:
630
+ if (isPageClosed && testRetries) {
631
+ // Report this and decrement the allowed retry count.
632
+ console.log(
633
+ `WARNING: Retry ${3 - testRetries--} of test ${ruleID} starting after page closed`
634
634
  );
635
- // If the page has closed and there are retries left:
636
- if (isPageClosed && testRetries) {
637
- // Report this and decrement the allowed retry count.
638
- console.log(
639
- `WARNING: Retry ${3 - testRetries--} of test ${ruleID} starting after page closed`
640
- );
641
- await wait(2000);
642
- // Replace the browser and the page in the run module and navigate to the target.
643
- await launch(
644
- report,
645
- actIndex,
646
- headEmulation,
647
- report.browserID,
648
- url
649
- );
650
- page = require('../run').page;
651
- // If the page replacement failed:
652
- if (! page) {
653
- // Report this.
654
- console.log(`ERROR: Browser relaunch to retry test ${ruleID} failed`);
655
- data.rulePreventions.push(ruleID);
656
- data.rulePreventionMessages[ruleID] = 'Retry failure due to browser relaunch failure';
657
- // Stop retrying the test.
658
- break;
659
- }
660
- // Update the rule arguments with the current page.
661
- ruleArgs[0] = page;
662
- }
663
- // Otherwise, i.e. if the page is open or it is closed but no retries are left:
664
- else {
665
- // Treat the test as prevented.
635
+ await wait(2000);
636
+ // Replace the browser and the page in the run module and navigate to the target.
637
+ await launch(
638
+ report,
639
+ actIndex,
640
+ headEmulation,
641
+ report.browserID,
642
+ url
643
+ );
644
+ page = require('../run').page;
645
+ // If the page replacement failed:
646
+ if (! page) {
647
+ // Report this.
648
+ console.log(`ERROR: Browser relaunch to retry test ${ruleID} failed`);
666
649
  data.rulePreventions.push(ruleID);
667
- data.rulePreventionMessages[ruleID] = error.message;
668
- console.log(`ERROR: Test of testaro rule ${ruleID} prevented (${error.message})`);
669
- // Do not retry the test even if retries are left.
650
+ data.rulePreventionMessages[ruleID] = 'Retry failure due to browser relaunch failure';
651
+ // Stop retrying the test.
670
652
  break;
671
653
  }
654
+ // Update the rule arguments with the current page.
655
+ ruleArgs[0] = page;
672
656
  }
673
- finally {
674
- // Clear the timeout.
675
- clearTimeout(timeout);
657
+ // Otherwise, i.e. if the page is open or it is closed but no retries are left:
658
+ else {
659
+ // Treat the test as prevented.
660
+ data.rulePreventions.push(ruleID);
661
+ data.rulePreventionMessages[ruleID] = error.message;
662
+ console.log(`ERROR: Test of testaro rule ${ruleID} prevented (${error.message})`);
663
+ // Do not retry the test even if retries are left.
664
+ break;
676
665
  }
677
666
  }
678
- // Clear the error listeners.
679
- if (page && ! page.isClosed() && crashHandler) {
680
- page.off('crash', crashHandler);
681
- crashHandler = null;
682
- }
683
- if (browser && disconnectHandler) {
684
- browser.off('disconnected', disconnectHandler);
685
- disconnectHandler = null;
667
+ finally {
668
+ // Clear the timeout.
669
+ clearTimeout(timeout);
686
670
  }
687
671
  }
688
- // Otherwise, i.e. if the rule is undefined or doubly defined:
689
- else {
690
- // Report this.
691
- data.rulesInvalid.push(rule);
692
- console.log(`ERROR: Rule ${rule.id} not validly defined`);
693
- // Clear the crash listener.
694
- if (page && ! page.isClosed() && crashHandler) {
695
- page.off('crash', crashHandler);
696
- crashHandler = null;
697
- }
698
- if (browser && disconnectHandler) {
699
- browser.off('disconnected', disconnectHandler);
700
- disconnectHandler = null;
701
- }
672
+ // Clear the error listeners.
673
+ if (page && ! page.isClosed() && crashHandler) {
674
+ page.off('crash', crashHandler);
675
+ crashHandler = null;
676
+ }
677
+ if (browser && disconnectHandler) {
678
+ browser.off('disconnected', disconnectHandler);
679
+ disconnectHandler = null;
702
680
  }
703
681
  // Force a garbage collection.
704
682
  try {
package/testaro/hr.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "ruleID": "hr",
3
- "selector": "body hr",
4
- "complaints": {
5
- "instance": "Element instead of styling is used for vertical segmentation",
6
- "summary": "Elements instead of styling are used for vertical segmentation"
7
- },
8
- "ordinalSeverity": 0,
9
- "summaryTagName": "HR"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "ruleID": "linkExt",
3
- "selector": "a[target=_blank]",
4
- "complaints": {
5
- "instance": "Link has a target=_blank attribute",
6
- "summary": "Links have target=_blank attributes"
7
- },
8
- "ordinalSeverity": 0,
9
- "summaryTagName": "A"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "ruleID": "linkOldAtt",
3
- "selector": "a[charset], a[coords], a[name], a[rev], a[shape]",
4
- "complaints": {
5
- "instance": "Element has a deprecated attribute",
6
- "summary": "Links have deprecated attributes"
7
- },
8
- "ordinalSeverity": 1,
9
- "summaryTagName": "A"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "ruleID": "linkTo",
3
- "selector": "a:not([href]):visible",
4
- "complaints": {
5
- "instance": "Element has no href attribute",
6
- "summary": "Links are missing href attributes"
7
- },
8
- "ordinalSeverity": 2,
9
- "summaryTagName": "A"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "ruleID": "pseudoP",
3
- "selector": "body br + br",
4
- "complaints": {
5
- "instance": "br element follows another br element, likely acting as a pseudo-paragraph",
6
- "summary": "br elements follow other br elements, likely acting as pseudo-paragraphs"
7
- },
8
- "ordinalSeverity": 0,
9
- "summaryTagName": "BR"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "ruleID": "titledEl",
3
- "selector": "[title]:not(button, iframe, input, link, select, textarea)",
4
- "complaints": {
5
- "instance": "Ineligible element has a title attribute",
6
- "summary": "Ineligible elements have title attributes"
7
- },
8
- "ordinalSeverity": 2,
9
- "summaryTagName": ""
10
- }