@uuv/a11y 1.0.0-beta.2 → 1.0.0-beta.21

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 (63) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/CONTRIBUTING.md +46 -0
  3. package/LICENSE +1 -1
  4. package/README.md +32 -249
  5. package/STRUCTURE.md +10 -0
  6. package/bundle/uuv-a11y.bundle.js +2 -2
  7. package/bundle/uuv-a11y.bundle.js.LICENSE.txt +1 -19
  8. package/dist/CHANGELOG.md +169 -0
  9. package/dist/CONTRIBUTING.md +46 -0
  10. package/dist/README.md +32 -249
  11. package/dist/STRUCTURE.md +10 -0
  12. package/dist/lib/engine/engine.js +28 -16
  13. package/dist/lib/model/index.d.ts +1 -1
  14. package/dist/lib/model/index.js +1 -1
  15. package/dist/lib/model/result.d.ts +2 -1
  16. package/dist/lib/model/rule.d.ts +0 -7
  17. package/dist/lib/model/rule.js +0 -2
  18. package/dist/lib/query/00-query.d.ts +6 -1
  19. package/dist/lib/query/00-query.js +10 -0
  20. package/dist/lib/query/accessible-name.query.d.ts +4 -2
  21. package/dist/lib/query/accessible-name.query.js +10 -7
  22. package/dist/lib/query/by-role.query.d.ts +4 -3
  23. package/dist/lib/query/by-role.query.js +22 -6
  24. package/dist/lib/query/by-sibling.query.d.ts +12 -0
  25. package/dist/lib/query/by-sibling.query.js +100 -0
  26. package/dist/lib/query/by-tag.query.d.ts +2 -2
  27. package/dist/lib/query/by-tag.query.js +4 -5
  28. package/dist/lib/query/compliant-attributes/attribut-specification.d.ts +34 -0
  29. package/dist/lib/query/compliant-attributes/attribut-specification.js +96 -0
  30. package/dist/lib/query/compliant-attributes/attribute-checker.d.ts +47 -0
  31. package/dist/lib/query/compliant-attributes/attribute-checker.js +73 -0
  32. package/dist/lib/query/compliant-attributes/compliant-attributes.query.d.ts +9 -0
  33. package/dist/lib/query/compliant-attributes/compliant-attributes.query.js +24 -0
  34. package/dist/lib/query/doctype.query.d.ts +2 -2
  35. package/dist/lib/query/doctype.query.js +2 -1
  36. package/dist/lib/query/form.query.d.ts +2 -2
  37. package/dist/lib/query/index.d.ts +7 -0
  38. package/dist/lib/query/index.js +7 -0
  39. package/dist/lib/query/operators/and-query.d.ts +8 -0
  40. package/dist/lib/query/operators/and-query.js +25 -0
  41. package/dist/lib/query/operators/operator-query.d.ts +8 -0
  42. package/dist/lib/query/operators/operator-query.js +14 -0
  43. package/dist/lib/query/operators/or-query.d.ts +8 -0
  44. package/dist/lib/query/operators/or-query.js +24 -0
  45. package/dist/lib/reference/rgaa/coverage/coverage-statement.json +56 -17
  46. package/dist/lib/reference/rgaa/rules/1-image.d.ts +0 -1
  47. package/dist/lib/reference/rgaa/rules/1-image.js +51 -77
  48. package/dist/lib/reference/rgaa/rules/11-form.d.ts +0 -1
  49. package/dist/lib/reference/rgaa/rules/11-form.js +0 -1
  50. package/dist/lib/reference/rgaa/rules/2-frame.d.ts +0 -1
  51. package/dist/lib/reference/rgaa/rules/2-frame.js +8 -7
  52. package/dist/lib/reference/rgaa/rules/3-color.d.ts +0 -1
  53. package/dist/lib/reference/rgaa/rules/3-color.js +0 -3
  54. package/dist/lib/reference/rgaa/rules/5-table.d.ts +12 -1
  55. package/dist/lib/reference/rgaa/rules/5-table.js +292 -1
  56. package/dist/lib/reference/rgaa/rules/6-link.d.ts +12 -1
  57. package/dist/lib/reference/rgaa/rules/6-link.js +147 -1
  58. package/dist/lib/reference/rgaa/rules/8-required-element.d.ts +0 -1
  59. package/dist/lib/reference/rgaa/rules/8-required-element.js +57 -9
  60. package/dist/lib/reference/rgaa/selector-helper.d.ts +40 -1
  61. package/dist/lib/reference/rgaa/selector-helper.js +82 -10
  62. package/dist/package.json +15 -4
  63. package/package.json +15 -4
@@ -1,7 +1,6 @@
1
1
  import { Query } from "../query/00-query";
2
2
  export interface A11yRule {
3
3
  attributes: string[];
4
- reference: string;
5
4
  check: RuleCheckEnum;
6
5
  criterion: string;
7
6
  wcag: string;
@@ -14,7 +13,6 @@ export interface A11yRule {
14
13
  }
15
14
  export declare class AutoCheckA11yRule implements A11yRule {
16
15
  attributes: string[];
17
- reference: string;
18
16
  check: RuleCheckEnum;
19
17
  criterion: string;
20
18
  wcag: string;
@@ -26,7 +24,6 @@ export declare class AutoCheckA11yRule implements A11yRule {
26
24
  shouldNotExist: boolean;
27
25
  static from(input: {
28
26
  attributes?: string[];
29
- reference: string;
30
27
  criterion: string;
31
28
  wcag: string;
32
29
  id: string;
@@ -37,7 +34,6 @@ export declare class AutoCheckA11yRule implements A11yRule {
37
34
  shouldNotExist?: boolean;
38
35
  }): AutoCheckA11yRule & {
39
36
  attributes?: string[] | undefined;
40
- reference: string;
41
37
  criterion: string;
42
38
  wcag: string;
43
39
  id: string;
@@ -50,7 +46,6 @@ export declare class AutoCheckA11yRule implements A11yRule {
50
46
  }
51
47
  export declare class ManualCheckA11yRule implements A11yRule {
52
48
  attributes: string[];
53
- reference: string;
54
49
  check: RuleCheckEnum;
55
50
  criterion: string;
56
51
  wcag: string;
@@ -62,7 +57,6 @@ export declare class ManualCheckA11yRule implements A11yRule {
62
57
  shouldNotExist: boolean;
63
58
  static from(input: {
64
59
  attributes?: string[];
65
- reference: string;
66
60
  criterion: string;
67
61
  wcag: string;
68
62
  id: string;
@@ -73,7 +67,6 @@ export declare class ManualCheckA11yRule implements A11yRule {
73
67
  shouldNotExist?: boolean;
74
68
  }): ManualCheckA11yRule & {
75
69
  attributes?: string[] | undefined;
76
- reference: string;
77
70
  criterion: string;
78
71
  wcag: string;
79
72
  id: string;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RuleTypeEnum = exports.CustomFilter = exports.RuleCheckEnum = exports.ManualCheckA11yRule = exports.AutoCheckA11yRule = void 0;
4
4
  class AutoCheckA11yRule {
5
5
  attributes;
6
- reference;
7
6
  check = RuleCheckEnum.AUTO;
8
7
  criterion;
9
8
  wcag;
@@ -20,7 +19,6 @@ class AutoCheckA11yRule {
20
19
  exports.AutoCheckA11yRule = AutoCheckA11yRule;
21
20
  class ManualCheckA11yRule {
22
21
  attributes = [];
23
- reference;
24
22
  check = RuleCheckEnum.MANUAL;
25
23
  criterion;
26
24
  wcag;
@@ -1,4 +1,9 @@
1
1
  export interface Query {
2
- execute(): HTMLElement[];
2
+ execute(): QueryResult[];
3
3
  getSelector(): string;
4
4
  }
5
+ export declare class QueryResult {
6
+ readonly domNode: HTMLElement;
7
+ readonly linkedNodes: HTMLElement[];
8
+ constructor(domNode: HTMLElement, linkedNodes?: HTMLElement[]);
9
+ }
@@ -1,2 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueryResult = void 0;
4
+ class QueryResult {
5
+ domNode;
6
+ linkedNodes;
7
+ constructor(domNode, linkedNodes = []) {
8
+ this.domNode = domNode;
9
+ this.linkedNodes = linkedNodes;
10
+ }
11
+ }
12
+ exports.QueryResult = QueryResult;
@@ -1,8 +1,10 @@
1
- import { Query } from "./00-query";
1
+ import { Query, QueryResult } from "./00-query";
2
2
  export declare class AccessibleNameQuery implements Query {
3
3
  readonly subQuery: Query;
4
4
  readonly shouldBeEmpty: boolean;
5
5
  constructor(subQuery: Query, shouldBeEmpty: boolean);
6
- execute(): HTMLElement[];
6
+ execute(): QueryResult[];
7
+ private isNullOrEmpty;
8
+ private isNotNullAndNotEmpty;
7
9
  getSelector(): string;
8
10
  }
@@ -1,11 +1,8 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.AccessibleNameQuery = void 0;
7
4
  const dom_accessibility_api_1 = require("dom-accessibility-api");
8
- const lodash_1 = __importDefault(require("lodash"));
5
+ const lodash_1 = require("lodash");
9
6
  class AccessibleNameQuery {
10
7
  subQuery;
11
8
  shouldBeEmpty;
@@ -15,11 +12,11 @@ class AccessibleNameQuery {
15
12
  }
16
13
  execute() {
17
14
  return this.subQuery.execute().filter(element => {
18
- const accessibleName = (0, dom_accessibility_api_1.computeAccessibleName)(element);
19
- if (this.shouldBeEmpty && lodash_1.default.isEmpty(accessibleName)) {
15
+ const accessibleName = (0, dom_accessibility_api_1.computeAccessibleName)(element.domNode);
16
+ if (this.shouldBeEmpty && this.isNullOrEmpty(accessibleName)) {
20
17
  return true;
21
18
  }
22
- else if (!this.shouldBeEmpty && !lodash_1.default.isEmpty(accessibleName)) {
19
+ else if (!this.shouldBeEmpty && this.isNotNullAndNotEmpty(accessibleName)) {
23
20
  return true;
24
21
  }
25
22
  else {
@@ -27,6 +24,12 @@ class AccessibleNameQuery {
27
24
  }
28
25
  });
29
26
  }
27
+ isNullOrEmpty(accessibleName) {
28
+ return (0, lodash_1.isNull)(accessibleName) || (0, lodash_1.isEmpty)(accessibleName);
29
+ }
30
+ isNotNullAndNotEmpty(accessibleName) {
31
+ return !(0, lodash_1.isNull)(accessibleName) && !(0, lodash_1.isEmpty)(accessibleName);
32
+ }
30
33
  getSelector() {
31
34
  return `AccessibleName: ${this.subQuery.getSelector()}`;
32
35
  }
@@ -1,8 +1,9 @@
1
- import { Query } from "./00-query";
1
+ import { Query, QueryResult } from "./00-query";
2
2
  export declare class ByRoleQuery implements Query {
3
3
  readonly role: string;
4
4
  readonly attributes: string[];
5
- constructor(role: string, attributes?: string[]);
6
- execute(): HTMLElement[];
5
+ readonly excludedTags: string[];
6
+ constructor(role: string, attributes?: string[], excludedTags?: string[]);
7
+ execute(): QueryResult[];
7
8
  getSelector(): string;
8
9
  }
@@ -1,27 +1,43 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.ByRoleQuery = void 0;
7
+ const _00_query_1 = require("./00-query");
4
8
  const dom_1 = require("@testing-library/dom");
9
+ const lodash_1 = __importDefault(require("lodash"));
5
10
  class ByRoleQuery {
6
11
  role;
7
12
  attributes;
8
- constructor(role, attributes = []) {
13
+ excludedTags;
14
+ constructor(role, attributes = [], excludedTags = []) {
9
15
  this.role = role;
10
16
  this.attributes = attributes;
17
+ this.excludedTags = excludedTags;
11
18
  }
12
19
  execute() {
13
20
  return (0, dom_1.queryAllByRole)(window.document.documentElement, this.role)
14
21
  ?.filter((element) => {
15
- if (this.attributes.length == 0) {
22
+ if (lodash_1.default.isEmpty(this.attributes) && lodash_1.default.isEmpty(this.excludedTags)) {
16
23
  return true;
17
24
  }
18
- return this.attributes.filter(value => {
25
+ const foundExcludedTags = this.excludedTags.filter(value => {
26
+ return element.tagName.toLowerCase() === value;
27
+ });
28
+ const foundAttributes = this.attributes.filter(value => {
19
29
  return element.getAttribute(value);
20
- }).length > 0;
21
- });
30
+ });
31
+ const hasFoundExcludedTags = !lodash_1.default.isEmpty(this.excludedTags) && !lodash_1.default.isEmpty(foundExcludedTags);
32
+ const hasFoundAttributes = !lodash_1.default.isEmpty(this.attributes) && !lodash_1.default.isEmpty(foundAttributes);
33
+ return (!hasFoundExcludedTags &&
34
+ hasFoundAttributes) ||
35
+ lodash_1.default.isEmpty(this.excludedTags) && hasFoundAttributes ||
36
+ lodash_1.default.isEmpty(this.attributes) && !hasFoundExcludedTags;
37
+ }).map((element) => new _00_query_1.QueryResult(element));
22
38
  }
23
39
  getSelector() {
24
- return `ByRole(${this.role}, ${this.attributes})`;
40
+ return `ByRole(${this.role}, ${this.excludedTags}, ${this.attributes})`;
25
41
  }
26
42
  }
27
43
  exports.ByRoleQuery = ByRoleQuery;
@@ -0,0 +1,12 @@
1
+ import { Query, QueryResult } from "./00-query";
2
+ export declare class BySiblingQuery implements Query {
3
+ readonly subQuery: Query;
4
+ readonly shouldBeFound: boolean;
5
+ readonly siblingTags: string[];
6
+ constructor(subQuery: Query, shouldBeFound: boolean, siblingTags: string[]);
7
+ execute(): QueryResult[];
8
+ private computeResult;
9
+ private foundSiblingElement;
10
+ getSelector(): string;
11
+ private addGhostInputNode;
12
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BySiblingQuery = void 0;
7
+ const _00_query_1 = require("./00-query");
8
+ const lodash_1 = __importDefault(require("lodash"));
9
+ const emulate_tab_1 = require("emulate-tab");
10
+ const DATA_TESTID = "data-testid";
11
+ const BODY = "BODY";
12
+ class BySiblingQuery {
13
+ subQuery;
14
+ shouldBeFound;
15
+ siblingTags;
16
+ constructor(subQuery, shouldBeFound, siblingTags) {
17
+ this.subQuery = subQuery;
18
+ this.shouldBeFound = shouldBeFound;
19
+ this.siblingTags = siblingTags;
20
+ }
21
+ execute() {
22
+ const result = [];
23
+ this.subQuery.execute().forEach((currentElement) => {
24
+ const element = currentElement.domNode;
25
+ element.focus();
26
+ if (document.activeElement?.tagName === BODY) {
27
+ const ghost = this.addGhostInputNode(element);
28
+ ghost.focus();
29
+ this.computeResult(element, result, ghost);
30
+ ghost.remove();
31
+ }
32
+ else {
33
+ this.computeResult(element, result);
34
+ }
35
+ });
36
+ return result;
37
+ }
38
+ computeResult(element, result, ghost = undefined) {
39
+ const elementFocused = ghost ?? element;
40
+ const siblingElements = [];
41
+ emulate_tab_1.emulateTab.findSelectableElements().forEach((value, index, collection) => {
42
+ if (value.getAttribute(DATA_TESTID) === elementFocused.getAttribute(DATA_TESTID)) {
43
+ const previousExist = index - 1 >= 0;
44
+ const nextExist = index + 1 <= collection.length - 1;
45
+ if (this.shouldBeFound) {
46
+ if (previousExist && this.foundSiblingElement(collection[index - 1])) {
47
+ siblingElements.push(collection[index - 1]);
48
+ }
49
+ if (nextExist && this.foundSiblingElement(collection[index + 1])) {
50
+ siblingElements.push(collection[index + 1]);
51
+ }
52
+ if (!lodash_1.default.isEmpty(siblingElements)) {
53
+ result.push(new _00_query_1.QueryResult(element, siblingElements));
54
+ }
55
+ }
56
+ else {
57
+ if ((previousExist &&
58
+ !this.foundSiblingElement(collection[index - 1]) &&
59
+ nextExist &&
60
+ !this.foundSiblingElement(collection[index + 1]))) {
61
+ siblingElements.push(collection[index - 1]);
62
+ siblingElements.push(collection[index + 1]);
63
+ }
64
+ if ((previousExist &&
65
+ !this.foundSiblingElement(collection[index - 1]) &&
66
+ !nextExist)) {
67
+ siblingElements.push(collection[index - 1]);
68
+ result.push(new _00_query_1.QueryResult(element, siblingElements));
69
+ }
70
+ if ((!previousExist &&
71
+ nextExist &&
72
+ !this.foundSiblingElement(collection[index + 1]))) {
73
+ siblingElements.push(collection[index + 1]);
74
+ }
75
+ if (!lodash_1.default.isEmpty(siblingElements)) {
76
+ result.push(new _00_query_1.QueryResult(element, siblingElements));
77
+ }
78
+ }
79
+ }
80
+ });
81
+ }
82
+ foundSiblingElement(element) {
83
+ return this.siblingTags.includes(element.tagName.toLowerCase());
84
+ }
85
+ getSelector() {
86
+ return `${this.subQuery.getSelector()}`;
87
+ }
88
+ addGhostInputNode(element) {
89
+ const input = document.createElement("input");
90
+ input.setAttribute(DATA_TESTID, "to-delete-" + String(Math.floor(Math.random() * Date.now())));
91
+ if (element.parentNode) {
92
+ element.parentNode.insertBefore(input, element.nextSibling);
93
+ }
94
+ else {
95
+ element.insertBefore(input, element.nextSibling);
96
+ }
97
+ return input;
98
+ }
99
+ }
100
+ exports.BySiblingQuery = BySiblingQuery;
@@ -1,7 +1,7 @@
1
- import { Query } from "./00-query";
1
+ import { Query, QueryResult } from "./00-query";
2
2
  export declare class ByTagQuery implements Query {
3
3
  readonly selectors: string[];
4
4
  constructor(selectors: string[]);
5
- execute(): HTMLElement[];
5
+ execute(): QueryResult[];
6
6
  getSelector(): string;
7
7
  }
@@ -1,17 +1,16 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.ByTagQuery = void 0;
7
- const jquery_1 = __importDefault(require("jquery"));
4
+ const _00_query_1 = require("./00-query");
5
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
6
+ const $ = require("jquery/dist/jquery.min");
8
7
  class ByTagQuery {
9
8
  selectors;
10
9
  constructor(selectors) {
11
10
  this.selectors = selectors;
12
11
  }
13
12
  execute() {
14
- return (0, jquery_1.default)(this.selectors.join(",")).toArray();
13
+ return $(this.selectors.join(",")).toArray().map((element) => new _00_query_1.QueryResult(element));
15
14
  }
16
15
  getSelector() {
17
16
  return `${this.selectors}`;
@@ -0,0 +1,34 @@
1
+ export interface IAttributeSpecification {
2
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
3
+ }
4
+ export declare class EmptyAttributeSpecification implements IAttributeSpecification {
5
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
6
+ }
7
+ export declare class NotEmptyAttributeSpecification implements IAttributeSpecification {
8
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
9
+ }
10
+ export declare class EmptyElementWithIdSpecification implements IAttributeSpecification {
11
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
12
+ }
13
+ export declare class NotUniqueIdAttributeSpecification implements IAttributeSpecification {
14
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
15
+ }
16
+ export declare class NotEqualsAttributeSpecification implements IAttributeSpecification {
17
+ private expectedValueList;
18
+ constructor(expectedValueList: string[]);
19
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
20
+ }
21
+ export declare class EqualsAttributeSpecification implements IAttributeSpecification {
22
+ private expectedValueList;
23
+ constructor(expectedValueList: string[]);
24
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
25
+ }
26
+ export declare class AccessibleNameNotContainsVisibleTextSpecification implements IAttributeSpecification {
27
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
28
+ }
29
+ export declare class EmptyInnerTextSpecification implements IAttributeSpecification {
30
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
31
+ }
32
+ export declare class NotEmptyInnerTextSpecification implements IAttributeSpecification {
33
+ isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
34
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NotEmptyInnerTextSpecification = exports.EmptyInnerTextSpecification = exports.AccessibleNameNotContainsVisibleTextSpecification = exports.EqualsAttributeSpecification = exports.NotEqualsAttributeSpecification = exports.NotUniqueIdAttributeSpecification = exports.EmptyElementWithIdSpecification = exports.NotEmptyAttributeSpecification = exports.EmptyAttributeSpecification = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
9
+ const $ = require("jquery/dist/jquery.min");
10
+ const dom_accessibility_api_1 = require("dom-accessibility-api");
11
+ class EmptyAttributeSpecification {
12
+ isSatisfiedBy(element, attributeName) {
13
+ const attributeValue = element.getAttribute(attributeName);
14
+ return lodash_1.default.isEmpty(attributeValue);
15
+ }
16
+ }
17
+ exports.EmptyAttributeSpecification = EmptyAttributeSpecification;
18
+ class NotEmptyAttributeSpecification {
19
+ isSatisfiedBy(element, attributeName) {
20
+ const attributeValue = element.getAttribute(attributeName);
21
+ return !lodash_1.default.isEmpty(attributeValue);
22
+ }
23
+ }
24
+ exports.NotEmptyAttributeSpecification = NotEmptyAttributeSpecification;
25
+ class EmptyElementWithIdSpecification {
26
+ isSatisfiedBy(element, attributeName) {
27
+ const attributeValue = element.getAttribute(attributeName);
28
+ if (lodash_1.default.isEmpty(attributeValue) || lodash_1.default.isNull(attributeValue)) {
29
+ return true;
30
+ }
31
+ const bindingNodeId = $(`#${attributeValue.replaceAll(".", "\\.")}`).text();
32
+ return lodash_1.default.isEmpty(bindingNodeId);
33
+ }
34
+ }
35
+ exports.EmptyElementWithIdSpecification = EmptyElementWithIdSpecification;
36
+ class NotUniqueIdAttributeSpecification {
37
+ isSatisfiedBy(element, attributeName) {
38
+ if (lodash_1.default.isNull(element.id) || lodash_1.default.isEmpty(element.id)) {
39
+ return true;
40
+ }
41
+ return $(`[id=${element.id}]`).length > 1;
42
+ }
43
+ }
44
+ exports.NotUniqueIdAttributeSpecification = NotUniqueIdAttributeSpecification;
45
+ class NotEqualsAttributeSpecification {
46
+ expectedValueList;
47
+ constructor(expectedValueList) {
48
+ this.expectedValueList = expectedValueList;
49
+ }
50
+ isSatisfiedBy(element, attributeName) {
51
+ const attributeValue = element.getAttribute(attributeName);
52
+ if (lodash_1.default.isNull(attributeValue)) {
53
+ return true;
54
+ }
55
+ return !this.expectedValueList.includes(attributeValue);
56
+ }
57
+ }
58
+ exports.NotEqualsAttributeSpecification = NotEqualsAttributeSpecification;
59
+ class EqualsAttributeSpecification {
60
+ expectedValueList;
61
+ constructor(expectedValueList) {
62
+ this.expectedValueList = expectedValueList;
63
+ }
64
+ isSatisfiedBy(element, attributeName) {
65
+ const attributeValue = element.getAttribute(attributeName);
66
+ if (lodash_1.default.isNull(attributeValue)) {
67
+ return false;
68
+ }
69
+ return this.expectedValueList.includes(attributeValue);
70
+ }
71
+ }
72
+ exports.EqualsAttributeSpecification = EqualsAttributeSpecification;
73
+ class AccessibleNameNotContainsVisibleTextSpecification {
74
+ isSatisfiedBy(element, attributeName) {
75
+ const visibleText = element.textContent;
76
+ if (lodash_1.default.isNull(visibleText) || lodash_1.default.isEmpty(visibleText)) {
77
+ return false;
78
+ }
79
+ const accessibleName = (0, dom_accessibility_api_1.computeAccessibleName)(element);
80
+ console.debug("visibleText", visibleText, "accessibleName", accessibleName);
81
+ return accessibleName?.toLowerCase().indexOf(visibleText.toLowerCase()) === -1;
82
+ }
83
+ }
84
+ exports.AccessibleNameNotContainsVisibleTextSpecification = AccessibleNameNotContainsVisibleTextSpecification;
85
+ class EmptyInnerTextSpecification {
86
+ isSatisfiedBy(element, attributeName) {
87
+ return lodash_1.default.isEmpty(element.textContent);
88
+ }
89
+ }
90
+ exports.EmptyInnerTextSpecification = EmptyInnerTextSpecification;
91
+ class NotEmptyInnerTextSpecification {
92
+ isSatisfiedBy(element, attributeName) {
93
+ return !lodash_1.default.isEmpty(element.textContent);
94
+ }
95
+ }
96
+ exports.NotEmptyInnerTextSpecification = NotEmptyInnerTextSpecification;
@@ -0,0 +1,47 @@
1
+ import { IAttributeSpecification } from "./attribut-specification";
2
+ export declare class CompliantSpecification {
3
+ readonly attribute: string;
4
+ specification: IAttributeSpecification;
5
+ constructor(attribute: string, specification: IAttributeSpecification);
6
+ }
7
+ export declare class AttributeChecker {
8
+ /**
9
+ * Check if the value of the attributeName is empty
10
+ * @param attributeName : HTMLElement attributeName
11
+ */
12
+ static emptyAttribute(attributeName: string): CompliantSpecification;
13
+ /**
14
+ * Check if the value of the attributeName is not empty
15
+ * @param attributeName : HTMLElement attributeName
16
+ */
17
+ static notEmptyAttribute(attributeName: string): CompliantSpecification;
18
+ /**
19
+ * Check that the text of the HTMLElement whose id matches the value of the attribute named attributeName another HTMLElement is empty
20
+ * @param attributeName : HTMLElement attribute name
21
+ */
22
+ static emptyHtmlNodeTargetedByTheAttribute(attributeName: string): CompliantSpecification;
23
+ /**
24
+ * Check that id attribute is not unique in current page
25
+ */
26
+ static notUniqueId(): CompliantSpecification;
27
+ /**
28
+ * Check that html element does not have the expected value
29
+ */
30
+ static notEquals(attributeName: string, expectedValueList: string[]): CompliantSpecification;
31
+ /**
32
+ * Check that html element have the expected value
33
+ */
34
+ static equals(attributeName: string, expectedValueList: string[]): CompliantSpecification;
35
+ /**
36
+ * Check that html element accessible name contains visible text ignoring case
37
+ */
38
+ static accessibleNameNotContainsVisibleText(): CompliantSpecification;
39
+ /**
40
+ * Check that html element have empty text
41
+ */
42
+ static emptyText(): CompliantSpecification;
43
+ /**
44
+ * Check that html element have not empty text
45
+ */
46
+ static notEmptyText(): CompliantSpecification;
47
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AttributeChecker = exports.CompliantSpecification = void 0;
4
+ const attribut_specification_1 = require("./attribut-specification");
5
+ class CompliantSpecification {
6
+ attribute;
7
+ specification;
8
+ constructor(attribute, specification) {
9
+ this.attribute = attribute;
10
+ this.specification = specification;
11
+ }
12
+ }
13
+ exports.CompliantSpecification = CompliantSpecification;
14
+ class AttributeChecker {
15
+ /**
16
+ * Check if the value of the attributeName is empty
17
+ * @param attributeName : HTMLElement attributeName
18
+ */
19
+ static emptyAttribute(attributeName) {
20
+ return new CompliantSpecification(attributeName, new attribut_specification_1.EmptyAttributeSpecification());
21
+ }
22
+ /**
23
+ * Check if the value of the attributeName is not empty
24
+ * @param attributeName : HTMLElement attributeName
25
+ */
26
+ static notEmptyAttribute(attributeName) {
27
+ return new CompliantSpecification(attributeName, new attribut_specification_1.NotEmptyAttributeSpecification());
28
+ }
29
+ /**
30
+ * Check that the text of the HTMLElement whose id matches the value of the attribute named attributeName another HTMLElement is empty
31
+ * @param attributeName : HTMLElement attribute name
32
+ */
33
+ static emptyHtmlNodeTargetedByTheAttribute(attributeName) {
34
+ return new CompliantSpecification(attributeName, new attribut_specification_1.EmptyElementWithIdSpecification());
35
+ }
36
+ /**
37
+ * Check that id attribute is not unique in current page
38
+ */
39
+ static notUniqueId() {
40
+ return new CompliantSpecification("id", new attribut_specification_1.NotUniqueIdAttributeSpecification());
41
+ }
42
+ /**
43
+ * Check that html element does not have the expected value
44
+ */
45
+ static notEquals(attributeName, expectedValueList) {
46
+ return new CompliantSpecification(attributeName, new attribut_specification_1.NotEqualsAttributeSpecification(expectedValueList));
47
+ }
48
+ /**
49
+ * Check that html element have the expected value
50
+ */
51
+ static equals(attributeName, expectedValueList) {
52
+ return new CompliantSpecification(attributeName, new attribut_specification_1.EqualsAttributeSpecification(expectedValueList));
53
+ }
54
+ /**
55
+ * Check that html element accessible name contains visible text ignoring case
56
+ */
57
+ static accessibleNameNotContainsVisibleText() {
58
+ return new CompliantSpecification("accessibleName", new attribut_specification_1.AccessibleNameNotContainsVisibleTextSpecification());
59
+ }
60
+ /**
61
+ * Check that html element have empty text
62
+ */
63
+ static emptyText() {
64
+ return new CompliantSpecification("text", new attribut_specification_1.EmptyInnerTextSpecification());
65
+ }
66
+ /**
67
+ * Check that html element have not empty text
68
+ */
69
+ static notEmptyText() {
70
+ return new CompliantSpecification("text", new attribut_specification_1.NotEmptyInnerTextSpecification());
71
+ }
72
+ }
73
+ exports.AttributeChecker = AttributeChecker;
@@ -0,0 +1,9 @@
1
+ import { Query, QueryResult } from "../00-query";
2
+ import { CompliantSpecification } from "./attribute-checker";
3
+ export declare class CompliantAttributesQuery implements Query {
4
+ readonly subQuery: Query;
5
+ readonly attributeSpecifications: CompliantSpecification[];
6
+ constructor(subQuery: Query, attributeSpecifications: CompliantSpecification[]);
7
+ execute(): QueryResult[];
8
+ getSelector(): string;
9
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompliantAttributesQuery = void 0;
4
+ class CompliantAttributesQuery {
5
+ subQuery;
6
+ attributeSpecifications;
7
+ constructor(subQuery, attributeSpecifications) {
8
+ this.subQuery = subQuery;
9
+ this.attributeSpecifications = attributeSpecifications;
10
+ }
11
+ execute() {
12
+ return this.subQuery.execute().filter((element) => {
13
+ let result = true;
14
+ this.attributeSpecifications.forEach(attributeSpecification => {
15
+ result = result && attributeSpecification.specification.isSatisfiedBy(element.domNode, attributeSpecification.attribute);
16
+ });
17
+ return result;
18
+ });
19
+ }
20
+ getSelector() {
21
+ return `CompliantAttributes: ${this.subQuery.getSelector()}`;
22
+ }
23
+ }
24
+ exports.CompliantAttributesQuery = CompliantAttributesQuery;
@@ -1,5 +1,5 @@
1
- import { Query } from "./00-query";
1
+ import { Query, QueryResult } from "./00-query";
2
2
  export declare class DoctypeQuery implements Query {
3
- execute(): HTMLElement[];
3
+ execute(): QueryResult[];
4
4
  getSelector(): string;
5
5
  }