testaro 27.0.0 → 28.0.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 (118) hide show
  1. package/CONTRIBUTING.md +3 -1
  2. package/README.md +14 -3
  3. package/package.json +2 -1
  4. package/procs/aslint.js +83 -0
  5. package/procs/nav.js +56 -14
  6. package/procs/standardize.js +36 -0
  7. package/run.js +35 -22
  8. package/tests/aslint.js +83 -0
  9. package/tests/axe.js +4 -0
  10. package/tests/qualWeb.js +6 -0
  11. package/aslint/LICENSE +0 -362
  12. package/aslint/README.md +0 -260
  13. package/aslint/app/rules/abstract-rule.ts +0 -83
  14. package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.documentation.md +0 -36
  15. package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.test.ts +0 -113
  16. package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.ts +0 -103
  17. package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.documentation.md +0 -34
  18. package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.test.ts +0 -82
  19. package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.ts +0 -44
  20. package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.documentation.md +0 -40
  21. package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.test.ts +0 -48
  22. package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.ts +0 -37
  23. package/aslint/app/rules/aslint/links-language-destination/links-language-destination.test.ts +0 -50
  24. package/aslint/app/rules/aslint/links-language-destination/links-language-destination.ts +0 -70
  25. package/aslint/app/rules/aslint/main-element-only-one/main-element-only-one.test.ts +0 -55
  26. package/aslint/app/rules/aslint/main-element-only-one/main-element-only-one.ts +0 -83
  27. package/aslint/app/rules/aslint/main-landmark-must-be-top-level/main-landmark-must-be-top-level.test.ts +0 -12
  28. package/aslint/app/rules/aslint/main-landmark-must-be-top-level/main-landmark-must-be-top-level.ts +0 -73
  29. package/aslint/app/rules/aslint/minimum-font-size/minimum-font-size.test.ts +0 -12
  30. package/aslint/app/rules/aslint/minimum-font-size/minimum-font-size.ts +0 -87
  31. package/aslint/app/rules/aslint/missing-href-on-a/missing-href-on-a.test.ts +0 -48
  32. package/aslint/app/rules/aslint/missing-href-on-a/missing-href-on-a.ts +0 -40
  33. package/aslint/app/rules/aslint/misused-aria-on-focusable-element/misused-aria-on-focusable-element.test.ts +0 -12
  34. package/aslint/app/rules/aslint/misused-aria-on-focusable-element/misused-aria-on-focusable-element.ts +0 -66
  35. package/aslint/app/rules/aslint/misused-input-attribute/misused-input-attribute.test.ts +0 -12
  36. package/aslint/app/rules/aslint/misused-input-attribute/misused-input-attribute.ts +0 -134
  37. package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.test.ts +0 -12
  38. package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.ts +0 -90
  39. package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.test.ts +0 -12
  40. package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.ts +0 -48
  41. package/aslint/app/rules/aslint/obsolete-html-attributes/obsolete-html-attributes.test.ts +0 -12
  42. package/aslint/app/rules/aslint/obsolete-html-attributes/obsolete-html-attributes.ts +0 -148
  43. package/aslint/app/rules/aslint/obsolete-html-elements/obsolete-html-elements.test.ts +0 -12
  44. package/aslint/app/rules/aslint/obsolete-html-elements/obsolete-html-elements.ts +0 -66
  45. package/aslint/app/rules/aslint/outline-zero/outline-zero.test.ts +0 -12
  46. package/aslint/app/rules/aslint/outline-zero/outline-zero.ts +0 -85
  47. package/aslint/app/rules/aslint/overlay/overlay.test.ts +0 -122
  48. package/aslint/app/rules/aslint/overlay/overlay.ts +0 -141
  49. package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.documentation.md +0 -49
  50. package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.test.ts +0 -91
  51. package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.ts +0 -62
  52. package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.documentation.md +0 -44
  53. package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.test.ts +0 -111
  54. package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.ts +0 -120
  55. package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.documentation.md +0 -45
  56. package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.test.ts +0 -63
  57. package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.ts +0 -44
  58. package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.documentation.md +0 -55
  59. package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.test.ts +0 -80
  60. package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.ts +0 -58
  61. package/aslint/app/rules/aslint/redundant/flash-content/flash-content.documentation.md +0 -48
  62. package/aslint/app/rules/aslint/redundant/flash-content/flash-content.test.ts +0 -52
  63. package/aslint/app/rules/aslint/redundant/flash-content/flash-content.ts +0 -32
  64. package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.documentation.md +0 -44
  65. package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.test.ts +0 -12
  66. package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.ts +0 -83
  67. package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.documentation.md +0 -46
  68. package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.test.ts +0 -46
  69. package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.ts +0 -36
  70. package/aslint/app/rules/aslint/role-application/role-application.test.ts +0 -48
  71. package/aslint/app/rules/aslint/role-application/role-application.ts +0 -38
  72. package/aslint/app/rules/aslint/rtl-content/rtl-content.test.ts +0 -12
  73. package/aslint/app/rules/aslint/rtl-content/rtl-content.ts +0 -75
  74. package/aslint/app/rules/aslint/unclear-uri-on-a/unclear-anchor-uri.test.ts +0 -12
  75. package/aslint/app/rules/aslint/unclear-uri-on-a/unclear-anchor-uri.ts +0 -48
  76. package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden-false.test.ts +0 -73
  77. package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden-false.ts +0 -34
  78. package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden.documentation.md +0 -32
  79. package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.docmentation.md +0 -48
  80. package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.test.ts +0 -67
  81. package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.ts +0 -63
  82. package/aslint/app/rules/aslint/unsupported-role-on-element/unsupported-role-on-element.test.ts +0 -12
  83. package/aslint/app/rules/aslint/unsupported-role-on-element/unsupported-role-on-element.ts +0 -63
  84. package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.documentation.md +0 -65
  85. package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.test.ts +0 -53
  86. package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.ts +0 -47
  87. package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.documentation.md +0 -57
  88. package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.test.ts +0 -52
  89. package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.ts +0 -63
  90. package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.documentation.md +0 -39
  91. package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.test.ts +0 -66
  92. package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.ts +0 -37
  93. package/aslint/utils/aria.test.ts +0 -12
  94. package/aslint/utils/aria.ts +0 -120
  95. package/aslint/utils/async.test.ts +0 -25
  96. package/aslint/utils/async.ts +0 -22
  97. package/aslint/utils/common.test.ts +0 -239
  98. package/aslint/utils/common.ts +0 -168
  99. package/aslint/utils/console.test.ts +0 -85
  100. package/aslint/utils/console.ts +0 -89
  101. package/aslint/utils/css.test.ts +0 -153
  102. package/aslint/utils/css.ts +0 -191
  103. package/aslint/utils/dom.test.ts +0 -627
  104. package/aslint/utils/dom.ts +0 -1051
  105. package/aslint/utils/env.test.ts +0 -14
  106. package/aslint/utils/env.ts +0 -8
  107. package/aslint/utils/func.test.ts +0 -160
  108. package/aslint/utils/func.ts +0 -70
  109. package/aslint/utils/global.test.ts +0 -12
  110. package/aslint/utils/global.ts +0 -25
  111. package/aslint/utils/object.test.ts +0 -524
  112. package/aslint/utils/object.ts +0 -278
  113. package/aslint/utils/report.test.ts +0 -56
  114. package/aslint/utils/report.ts +0 -36
  115. package/aslint/utils/text.test.ts +0 -270
  116. package/aslint/utils/text.ts +0 -165
  117. package/aslint/utils/time.test.ts +0 -43
  118. package/aslint/utils/time.ts +0 -33
@@ -1,83 +0,0 @@
1
- import { DomUtility } from '../../../utils/dom';
2
- import { Css } from '../../../utils/css';
3
- import { TextUtility } from '../../../utils/text';
4
- import { CATEGORY_TYPE } from '../../../constants/categoryType';
5
- import { IIssueReport } from '../../../interfaces/rule-issue.interface';
6
- import { TranslateService } from '../../../services/translate';
7
- import { $accessibilityAuditRules, $severity } from '../../../constants/accessibility';
8
- import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
9
-
10
- export class FontStyleItalic extends AbstractRule {
11
-
12
- protected selector: string = `*${[
13
- ':root',
14
- 'head',
15
- 'style',
16
- 'script',
17
- 'noscript',
18
- 'meta',
19
- 'link',
20
- 'br',
21
- 'hr',
22
- 'object',
23
- 'svg',
24
- 'path',
25
- 'defs',
26
- 'rect',
27
- 'clippath',
28
- 'use',
29
- 'g',
30
- 'b',
31
- 'filter',
32
- 'img',
33
- 'picture',
34
- 'input',
35
- 'iframe',
36
- 'code',
37
- 'metadata',
38
- ':empty'
39
- ].map((i: string): string => {
40
- return `:not(${i})`;
41
- }).join('')}`;
42
-
43
- protected ruleConfig: IAbstractRuleConfig = {
44
- id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.font_style_italic),
45
- links: [
46
- {
47
- content: 'Avoiding chunks of italic text',
48
- url: 'https://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning.html'
49
- }
50
- ],
51
- recommendations: [],
52
- severity: $severity.info,
53
- type: CATEGORY_TYPE.BEST_PRACTICE
54
- };
55
-
56
- public validate(elements: HTMLElement[]): void {
57
- const reportNode = (element: HTMLElement): void => {
58
- let isItalic: boolean = false;
59
- const textContent: string = DomUtility.getTextFromDescendantContent(element).trim();
60
- const textContentLength: number = textContent.length;
61
- const REASONABLE_LONG_TEXT: number = 80;
62
-
63
- // Note: element.style may not exists, e.g. for an element in a different namespace
64
- if (Css.getStyle(element, 'font-style') === 'italic' || typeof element.style === 'object' && element.style.fontStyle === 'italic') {
65
- isItalic = true;
66
- }
67
-
68
- if (isItalic === false || textContentLength < REASONABLE_LONG_TEXT) {
69
- return;
70
- }
71
-
72
- const report: IIssueReport = {
73
- message: TranslateService.instant('font_style_italic_report_message', [textContentLength]),
74
- node: element,
75
- ruleId: this.ruleConfig.id
76
- };
77
-
78
- this.validator.report(report);
79
- };
80
-
81
- elements.forEach(reportNode);
82
- }
83
- }
@@ -1,46 +0,0 @@
1
- # h1-must-be
2
-
3
- ## Rule id
4
-
5
- `h1-must-be`
6
-
7
- ## Definition
8
-
9
- This rule verifies if there is defined heading `h1` on the page.
10
-
11
- ## Purpose
12
-
13
- Most content on web pages should be organized into sections. When pages are organized into sections, a heading should be present.
14
-
15
- All pages should at least have a `<h1>` level heading giving the title of the page.
16
-
17
- This rule checks 1 case:
18
-
19
- * Determine if there is at least 1 element `<h1>`.
20
-
21
- **Note**: the rule does not check if the content of `<h1>` is empty.
22
-
23
- ## Test cases
24
-
25
- ### Passed
26
-
27
- The rule passes when there is at least 1 `<h1>` element.
28
-
29
- ## WCAG Success Criteria
30
-
31
- Not Applicable
32
-
33
- ## Best Practice
34
-
35
- Yes
36
-
37
- ## User Impact
38
-
39
- * **Severity**: critical
40
- * **Disabilities Affected**:
41
- * Visual:
42
- * blindness
43
-
44
- ## Resources
45
-
46
- * https://www.w3.org/WAI/tutorials/page-structure/headings/
@@ -1,46 +0,0 @@
1
- import { H1MustBe } from './h1-must-be';
2
- import { Validator } from '../../../validator';
3
- import { DomUtility } from '../../../utils/dom';
4
-
5
- describe('Rules', () => {
6
-
7
- describe('H1MustBe', () => {
8
-
9
- let fakeDom;
10
-
11
- new H1MustBe().registerValidator();
12
-
13
- beforeEach(() => {
14
- fakeDom = document.createElement('div');
15
- fakeDom.id = 'fakedom';
16
- document.body.appendChild(fakeDom);
17
-
18
- Validator.reset();
19
- });
20
-
21
- afterEach(() => {
22
- DomUtility.remove(document.getElementById('fakedom'));
23
- fakeDom = undefined;
24
- });
25
-
26
- it('should return one report when there is no elements with h1', () => {
27
- fakeDom.innerHTML = '<div><h2>h1</h2></div>';
28
-
29
- new H1MustBe().run(fakeDom);
30
-
31
- expect(Object.keys(Validator.getReports()).length).toBe(1);
32
- expect(Validator.getReport('report_0').message).toBe('Expected at least one heading <code>h1</code> element, but found none.');
33
- expect(Validator.getReport('report_0').node).toBe(null);
34
- expect(Validator.getReport('report_0').ruleId).toBe('h1-must-be');
35
- });
36
-
37
- it('should return no reports when there is element with h1', () => {
38
- fakeDom.innerHTML = '<div><h1>h1</h1></div>';
39
-
40
- new H1MustBe().run(fakeDom);
41
-
42
- expect(Object.keys(Validator.getReports()).length).toBe(0);
43
- });
44
-
45
- });
46
- });
@@ -1,36 +0,0 @@
1
- import { CATEGORY_TYPE } from '../../../constants/categoryType';
2
- import { IIssueReport } from '../../../interfaces/rule-issue.interface';
3
- import { TextUtility } from '../../../utils/text';
4
- import { TranslateService } from '../../../services/translate';
5
- import { $accessibilityAuditRules, $severity } from '../../../constants/accessibility';
6
- import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
7
-
8
- export class H1MustBe extends AbstractRule {
9
- protected selector: string = 'h1';
10
- protected ruleConfig: IAbstractRuleConfig = {
11
- id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.h1_must_be),
12
- links: [
13
- {
14
- content: 'Web Accessibility Tutorials: Headings',
15
- url: 'https://www.w3.org/WAI/tutorials/page-structure/headings/'
16
- }
17
- ],
18
- recommendations: [],
19
- severity: $severity.critical,
20
- type: CATEGORY_TYPE.BEST_PRACTICE
21
- };
22
-
23
- public validate(elements: Element[]): void {
24
- if (elements.length > 0) {
25
- return;
26
- }
27
-
28
- const report: IIssueReport = {
29
- message: TranslateService.instant('h1_must_report_message'),
30
- node: null,
31
- ruleId: this.ruleConfig.id
32
- };
33
-
34
- this.validator.report(report);
35
- }
36
- }
@@ -1,48 +0,0 @@
1
- import { RoleApplication } from './role-application';
2
- import { Validator } from '../../../validator';
3
- import { DomUtility } from '../../../utils/dom';
4
-
5
- describe('Rules', () => {
6
-
7
- describe('RoleApplication', () => {
8
-
9
- let fakeDom;
10
-
11
- new RoleApplication().registerValidator();
12
-
13
- beforeEach(() => {
14
- fakeDom = document.createElement('div');
15
- fakeDom.id = 'fakedom';
16
- document.body.appendChild(fakeDom);
17
-
18
- Validator.reset();
19
- });
20
-
21
- afterEach(() => {
22
- DomUtility.remove(document.getElementById('fakedom'));
23
- fakeDom = undefined;
24
- });
25
-
26
- it('should return correct data for p with role="application"', () => {
27
- fakeDom.innerHTML = '<p role="application"></p>';
28
- const nodes = DomUtility.querySelectorAllExclude('[role="application"]', fakeDom) as HTMLElement[];
29
-
30
- new RoleApplication().validate(nodes);
31
-
32
- expect(Object.keys(Validator.getReports()).length).toBe(1);
33
- expect(Validator.getReport('report_0').message).toBe('Use <code>role="application"</code> carefully as it is used to denote a region of a web application that is to be treated like a desktop application, not like a regular web page.');
34
- expect(Validator.getReport('report_0').node.nodeName.toLowerCase()).toBe('p');
35
- expect(Validator.getReport('report_0').ruleId).toBe('role-application');
36
- });
37
-
38
- it('should return no reports in case no elements with p with role="application"', () => {
39
- fakeDom.innerHTML = '<p>Test</p>';
40
- const nodes = DomUtility.querySelectorAllExclude('[role="application"]', fakeDom) as HTMLElement[];
41
-
42
- new RoleApplication().validate(nodes);
43
-
44
- expect(Object.keys(Validator.getReports()).length).toBe(0);
45
- });
46
-
47
- });
48
- });
@@ -1,38 +0,0 @@
1
- import { CATEGORY_TYPE } from '../../../constants/categoryType';
2
- import { IIssueReport } from '../../../interfaces/rule-issue.interface';
3
- import { TextUtility } from '../../../utils/text';
4
- import { TranslateService } from '../../../services/translate';
5
- import { $severity } from '../../../constants/accessibility';
6
- import { $accessibilityAuditRules } from '../../../constants/accessibility';
7
- import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
8
-
9
- export class RoleApplication extends AbstractRule {
10
- protected selector: string = '[role="application"]';
11
-
12
- protected ruleConfig: IAbstractRuleConfig = {
13
- id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.role_application),
14
- links: [
15
- {
16
- content: 'Using ARIA role=application',
17
- url: 'https://w3c.github.io/aria-in-html/'
18
- }
19
- ],
20
- recommendations: [],
21
- severity: $severity.critical,
22
- type: CATEGORY_TYPE.BEST_PRACTICE
23
- };
24
-
25
- public validate(elements: HTMLElement[]): void {
26
- const checkTabindex = (element: HTMLElement): void => {
27
- const report: IIssueReport = {
28
- message: TranslateService.instant('role_application_report_message'),
29
- node: element,
30
- ruleId: this.ruleConfig.id
31
- };
32
-
33
- this.validator.report(report);
34
- };
35
-
36
- elements.forEach(checkTabindex);
37
- }
38
- }
@@ -1,12 +0,0 @@
1
- import { RtlContent } from './rtl-content';
2
-
3
- describe('Rules', () => {
4
-
5
- describe('RtlContent', () => {
6
-
7
- it('should indicate that class exists', () => {
8
- expect(RtlContent).toBeDefined();
9
- });
10
-
11
- });
12
- });
@@ -1,75 +0,0 @@
1
- import { Css } from '../../../utils/css';
2
- import { CATEGORY_TYPE } from '../../../constants/categoryType';
3
- import { IIssueReport } from '../../../interfaces/rule-issue.interface';
4
- import { TextUtility } from '../../../utils/text';
5
- import { TranslateService } from '../../../services/translate';
6
- import { $severity } from '../../../constants/accessibility';
7
- import { $accessibilityAuditRules } from '../../../constants/accessibility';
8
- import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
9
-
10
- export class RtlContent extends AbstractRule {
11
- protected selector: string = `*${[
12
- ':root',
13
- 'head',
14
- 'style',
15
- 'script',
16
- 'meta',
17
- 'link',
18
- 'br',
19
- 'hr',
20
- 'object',
21
- 'path',
22
- 'g',
23
- 'filter',
24
- 'img',
25
- 'input',
26
- 'iframe',
27
- 'code',
28
- ':empty'
29
- ].map((i: string): string => {
30
- return `:not(${i})`;
31
- }).join('')}`;
32
-
33
- protected ruleConfig: IAbstractRuleConfig = {
34
- id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.rtl_content),
35
- links: [
36
- {
37
- content: 'Right to left implementation tricks',
38
- url: 'http://www.ctomczyk.pl/right-to-left-implementation-tricks/642/'
39
- }
40
- ],
41
- recommendations: [],
42
- severity: $severity.info,
43
- type: CATEGORY_TYPE.BEST_PRACTICE
44
- };
45
-
46
- public validate(elements: HTMLElement[]): any {
47
- const nodesToReport: HTMLElement[] = [];
48
-
49
- const reportRTL = (element: HTMLElement): void => {
50
- if (element.nodeType !== element.ELEMENT_NODE) {
51
- return;
52
- }
53
-
54
- const direction: string | null = Css.getStyle(element, 'direction');
55
-
56
- if (typeof direction === 'string' && direction.toLowerCase() === 'rtl') {
57
- nodesToReport.push(element);
58
- }
59
- };
60
-
61
- elements.forEach(reportRTL);
62
-
63
- const createReport = (element: HTMLElement): void => {
64
- const problem: IIssueReport = {
65
- message: TranslateService.instant('rtl_content_report_message'),
66
- node: element,
67
- ruleId: this.ruleConfig.id
68
- };
69
-
70
- this.validator.report(problem);
71
- };
72
-
73
- nodesToReport.forEach(createReport);
74
- }
75
- }
@@ -1,12 +0,0 @@
1
- import { UnclearAnchorUri } from './unclear-anchor-uri';
2
-
3
- describe('Rules', () => {
4
-
5
- describe('UnclearAnchorUri', () => {
6
-
7
- it('should indicate that class exists', () => {
8
- expect(UnclearAnchorUri).toBeDefined();
9
- });
10
-
11
- });
12
- });
@@ -1,48 +0,0 @@
1
- import { CATEGORY_TYPE } from '../../../constants/categoryType';
2
- import { IIssueReport } from '../../../interfaces/rule-issue.interface';
3
- import { TextUtility } from '../../../utils/text';
4
- import { TranslateService } from '../../../services/translate';
5
- import { $severity } from '../../../constants/accessibility';
6
- import { $accessibilityAuditRules } from '../../../constants/accessibility';
7
- import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
8
-
9
- export class UnclearAnchorUri extends AbstractRule {
10
- protected selector: string = 'a[href="#"], a[href*=javascript\\:], a[href=""]';
11
-
12
- protected ruleConfig: IAbstractRuleConfig = {
13
- id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.unclear_anchor_uri),
14
- links: [
15
- {
16
- content: 'Making AJAX applications crawlable',
17
- url: 'https://developers.google.com/webmasters/ajax-crawling/docs/learn-more#what-the-user-sees-what-the-crawler-sees'
18
- }
19
- ],
20
- recommendations: [],
21
- severity: $severity.high,
22
- type: CATEGORY_TYPE.BEST_PRACTICE
23
- };
24
-
25
- public validate(anchorElements: HTMLAnchorElement[]): void {
26
- const checkHref = (anchorElement: HTMLAnchorElement): void => {
27
- const hrefAttr: string | null = anchorElement.getAttribute('href');
28
-
29
- if (hrefAttr === null) {
30
- return;
31
- }
32
-
33
- const report: IIssueReport = {
34
- message: TranslateService.instant('unclear_uri_on_a_report_message_1', [anchorElement.href]),
35
- node: anchorElement,
36
- ruleId: this.ruleConfig.id
37
- };
38
-
39
- this.validator.report(report);
40
- };
41
-
42
- const nodesLength: number = anchorElements.length;
43
-
44
- if (nodesLength) {
45
- anchorElements.forEach(checkHref);
46
- }
47
- }
48
- }
@@ -1,73 +0,0 @@
1
- import { AriaHiddenFalse } from './aria-hidden-false';
2
- import { DomUtility } from '../../../utils/dom';
3
- import { Validator } from '../../../validator';
4
-
5
- describe('Rules', () => {
6
-
7
- describe('AriaHiddenFalse', () => {
8
-
9
- let fakeDom;
10
- const selector = 'body [aria-hidden="false"]';
11
-
12
- new AriaHiddenFalse().registerValidator();
13
-
14
- beforeEach(() => {
15
- fakeDom = document.createElement('div');
16
- fakeDom.id = 'fakedom';
17
- document.body.appendChild(fakeDom);
18
-
19
- Validator.reset();
20
- });
21
-
22
- afterEach(() => {
23
- DomUtility.remove(document.getElementById('fakedom'));
24
- fakeDom = undefined;
25
- });
26
-
27
- it('should return one report when there is an element with aria-hidden="false"', () => {
28
- fakeDom.innerHTML = '<p aria-hidden="false"></p>';
29
-
30
- const nodes: Element[] = DomUtility.querySelectorAllExclude(selector, fakeDom);
31
-
32
- new AriaHiddenFalse().validate(nodes);
33
-
34
- expect(Validator.getReport('report_0').ruleId).toBe('aria-hidden-false');
35
- expect(Validator.getReport('report_0').message).toBe('You have defined <code>aria-hidden&#x3D;&quot;false&quot;</code>. Caution, as the child content is always readable by screen readers regardless of setting <code>display: none</code> on any child element.');
36
- expect(Validator.getReport('report_0').node.nodeName.toLowerCase()).toBe('p');
37
- });
38
-
39
- it('should return 1 report when there is an element with attribute aria-hidden="false" and style="display: none"', () => {
40
- fakeDom.innerHTML = '<p aria-hidden="false" style="display: none"></p>';
41
-
42
- const nodes = DomUtility.querySelectorAllExclude(selector, fakeDom);
43
-
44
- new AriaHiddenFalse().validate(nodes);
45
-
46
- expect(Object.keys(Validator.getReports()).length).toBe(1);
47
- expect(Validator.getReport('report_0').message).toBe('You have defined <code>aria-hidden&#x3D;&quot;false&quot;</code>. Caution, as the child content is always readable by screen readers regardless of setting <code>display: none</code> on any child element.');
48
- expect(Validator.getReport('report_0').node.nodeName.toLowerCase()).toBe('p');
49
- });
50
-
51
- it('should return no report when there is an element with attribute aria-hidden="true"', () => {
52
- fakeDom.innerHTML = '<p aria-hidden="true"></p>';
53
-
54
- const nodes = DomUtility.querySelectorAllExclude(selector, fakeDom);
55
-
56
- new AriaHiddenFalse().validate(nodes);
57
-
58
- expect(Object.keys(Validator.getReports()).length).toBe(0);
59
- });
60
-
61
- it('should return no report when there is no element with attribute aria-hidden="false"', () => {
62
- fakeDom.innerHTML = '<p>test</p>';
63
-
64
- const nodes = DomUtility.querySelectorAllExclude(selector, fakeDom);
65
-
66
- new AriaHiddenFalse().validate(nodes);
67
-
68
- expect(Object.keys(Validator.getReports()).length).toBe(0);
69
- });
70
-
71
- });
72
-
73
- });
@@ -1,34 +0,0 @@
1
- import { CATEGORY_TYPE } from '../../../constants/categoryType';
2
- import { IIssueReport } from '../../../interfaces/rule-issue.interface';
3
- import { TranslateService } from '../../../services/translate';
4
- import { $severity, $accessibilityAuditRules } from '../../../constants/accessibility';
5
- import { TextUtility } from '../../../utils/text';
6
- import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
7
-
8
- export class AriaHiddenFalse extends AbstractRule {
9
- protected selector: string = 'body [aria-hidden="false"]';
10
-
11
- protected ruleConfig: IAbstractRuleConfig = {
12
- id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.aria_hidden_false),
13
- links: [],
14
- recommendations: [],
15
- severity: $severity.low,
16
- type: CATEGORY_TYPE.BEST_PRACTICE
17
- };
18
-
19
- public validate(elements: Element[]): void {
20
- const reportProblem = (element: Element): void => {
21
- const reportMessage: string = TranslateService.instant('aria_hidden_false_report_message', [TextUtility.escape('aria-hidden="false"'), TextUtility.escape('display: none')]);
22
-
23
- const problem: IIssueReport = {
24
- message: reportMessage,
25
- node: element,
26
- ruleId: this.ruleConfig.id
27
- };
28
-
29
- this.validator.report(problem);
30
- };
31
-
32
- elements.forEach(reportProblem);
33
- }
34
- }
@@ -1,32 +0,0 @@
1
- # aria-hidden
2
-
3
- ## Rule id
4
-
5
- `aria-hidden`
6
-
7
- ## Definition
8
-
9
- `aria-hidden="false"` should be used with caution.
10
-
11
- ## Purpose
12
-
13
- When `aria-hidden="false"` is defined then we need to be cautious, as the child content is always readable by screen readers regardless of setting `aria-hidden="false"` on any child element.
14
-
15
- ## WCAG Success Criteria
16
-
17
- Not Applicable
18
-
19
- ## Best Practice
20
-
21
- Yes
22
-
23
- ## User Impact
24
-
25
- * **Severity**: low
26
- * **Disabilities Affected**:
27
- * Visual:
28
- * blindness
29
-
30
- ## Resources
31
-
32
- Not available
@@ -1,48 +0,0 @@
1
- # content-editable-missing-attributes
2
-
3
- ## Rule id
4
-
5
- `content-editable-missing-attributes`
6
-
7
- ## Definition
8
-
9
- This rule verifies if element with attribute `contenteditable` have defined also following attributes:
10
-
11
- 1. `aria-multiline`
12
- 2. `aria-labelledby` or `aria-label`
13
-
14
- ## Purpose
15
-
16
- When `aria-multiline="true"` is set then Assistive Technologies informs the user that the textbox supports multi-line input, with the expectation that <kbd>Enter</kbd> or <kbd>Return</kbd> will create a line break rather than submitting the form.
17
-
18
- `aria-label` here is recommended to specify a string to be used as the accessible label.
19
-
20
- Eventually `aria-labelledby` can be used to specify the `id` of another element in the DOM as an element's label.
21
-
22
- ## Test cases
23
-
24
- ### Passed
25
-
26
- The rule passes when all of the following cases are fulfilled:
27
-
28
- 1. Attribute `contenteditable` is defined.
29
- 2. `aria-label` or `aria-labelledby` is defined. The rule does not validate `aria-labelledby` ids if the referenced elements exists.
30
-
31
- ## WCAG Success Criteria
32
-
33
- Not Applicable
34
-
35
- ## Best Practice
36
-
37
- Yes
38
-
39
- ## User Impact
40
-
41
- * **Severity**: high
42
- * **Disabilities Affected**:
43
- * Visual:
44
- * blindness
45
-
46
- ## Resources
47
-
48
- Not available