@uuv/a11y 1.0.0-beta.4 → 1.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/CONTRIBUTING.md +1 -1
- package/bundle/uuv-a11y.bundle.js +2 -2
- package/dist/CHANGELOG.md +16 -0
- package/dist/CONTRIBUTING.md +1 -1
- package/dist/lib/engine/engine.js +15 -13
- package/dist/lib/model/result.d.ts +2 -1
- package/dist/lib/model/rule.d.ts +0 -7
- package/dist/lib/model/rule.js +0 -2
- package/dist/lib/query/00-query.d.ts +6 -1
- package/dist/lib/query/00-query.js +10 -0
- package/dist/lib/query/accessible-name.query.d.ts +2 -2
- package/dist/lib/query/accessible-name.query.js +1 -1
- package/dist/lib/query/by-role.query.d.ts +4 -3
- package/dist/lib/query/by-role.query.js +22 -6
- package/dist/lib/query/by-sibling.query.d.ts +12 -0
- package/dist/lib/query/by-sibling.query.js +100 -0
- package/dist/lib/query/by-tag.query.d.ts +2 -2
- package/dist/lib/query/by-tag.query.js +2 -1
- package/dist/lib/query/compliant-attributes/attribut-specification.d.ts +9 -0
- package/dist/lib/query/compliant-attributes/attribut-specification.js +27 -0
- package/dist/lib/query/compliant-attributes/attribute-checker.d.ts +18 -0
- package/dist/lib/query/compliant-attributes/attribute-checker.js +30 -0
- package/dist/lib/query/compliant-attributes/compliant-attributes.query.d.ts +9 -0
- package/dist/lib/query/compliant-attributes/compliant-attributes.query.js +24 -0
- package/dist/lib/query/doctype.query.d.ts +2 -2
- package/dist/lib/query/doctype.query.js +2 -1
- package/dist/lib/query/form.query.d.ts +2 -2
- package/dist/lib/query/index.d.ts +7 -0
- package/dist/lib/query/index.js +7 -0
- package/dist/lib/query/operators/and-query.d.ts +8 -0
- package/dist/lib/query/operators/and-query.js +25 -0
- package/dist/lib/query/operators/operator-query.d.ts +8 -0
- package/dist/lib/query/operators/operator-query.js +14 -0
- package/dist/lib/query/operators/or-query.d.ts +8 -0
- package/dist/lib/query/operators/or-query.js +24 -0
- package/dist/lib/reference/rgaa/coverage/coverage-statement.json +16 -16
- package/dist/lib/reference/rgaa/rules/1-image.d.ts +0 -1
- package/dist/lib/reference/rgaa/rules/1-image.js +51 -77
- package/dist/lib/reference/rgaa/rules/11-form.d.ts +0 -1
- package/dist/lib/reference/rgaa/rules/11-form.js +0 -1
- package/dist/lib/reference/rgaa/rules/2-frame.d.ts +0 -1
- package/dist/lib/reference/rgaa/rules/2-frame.js +0 -2
- package/dist/lib/reference/rgaa/rules/3-color.d.ts +0 -1
- package/dist/lib/reference/rgaa/rules/3-color.js +0 -3
- package/dist/lib/reference/rgaa/rules/8-required-element.d.ts +0 -1
- package/dist/lib/reference/rgaa/rules/8-required-element.js +0 -6
- package/dist/lib/reference/rgaa/selector-helper.d.ts +4 -1
- package/dist/lib/reference/rgaa/selector-helper.js +10 -10
- package/dist/package.json +2 -1
- package/package.json +2 -1
package/dist/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## [1.0.0-beta.5](https://github.com/Orange-OpenSource/uuv/compare/a11y-v1.0.0-beta.4...a11y-v1.0.0-beta.5) (2024-01-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **a11y:** update dependency @testing-library/dom to v9.3.4 ([368b6b4](https://github.com/Orange-OpenSource/uuv/commit/368b6b4210f83d2da7695a0bfedd8ac593df171a))
|
|
7
|
+
* **assistant:** fix assistant and enable uuv test for assistant, [#437](https://github.com/Orange-OpenSource/uuv/issues/437) ([da82e1b](https://github.com/Orange-OpenSource/uuv/commit/da82e1b588a391eb24573ac8c3f2db18cfdbf5a5))
|
|
8
|
+
* **deps:** update dependency @easyops-cn/docusaurus-search-local to v0.40.1 ([d5ed3d7](https://github.com/Orange-OpenSource/uuv/commit/d5ed3d75f44e2b83af81fcd7227521dea00371e6))
|
|
9
|
+
|
|
10
|
+
## [1.0.0-beta.4](https://github.com/Orange-OpenSource/uuv/compare/a11y-v1.0.0-beta.3...a11y-v1.0.0-beta.4) (2024-01-11)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **a11y:** add a contains sentence for a11y rgaa, [#424](https://github.com/Orange-OpenSource/uuv/issues/424) ([297cc33](https://github.com/Orange-OpenSource/uuv/commit/297cc3378798d1eb9c973a2038423ae6f874f70f))
|
|
16
|
+
|
|
1
17
|
## [1.0.0-beta.3](https://github.com/Orange-OpenSource/uuv/compare/a11y-v1.0.0-beta.2...a11y-v1.0.0-beta.3) (2024-01-08)
|
|
2
18
|
|
|
3
19
|
|
package/dist/CONTRIBUTING.md
CHANGED
|
@@ -40,7 +40,7 @@ For example :
|
|
|
40
40
|
help: "adapt these attributes to be relevant"
|
|
41
41
|
})
|
|
42
42
|
```
|
|
43
|
-
**Adding a new rule may require you to create a new query, in which case remember to write the corresponding automated tests in the `a11y/test/query/**` directory.**
|
|
43
|
+
**Adding a new rule may require you to create a new query, in which case remember to write the corresponding automated tests in the `a11y/test/query/**` directory and export it `index.ts` of same directory.**
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
4. Create or enhance the automated topic test file in the directory `a11y/test/checker/**`.
|
|
@@ -18,13 +18,14 @@ class Engine {
|
|
|
18
18
|
observer.complete();
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
getRuleResult(rule,
|
|
21
|
+
getRuleResult(rule, queryResults) {
|
|
22
22
|
if (rule.check === model_1.RuleCheckEnum.MANUAL) {
|
|
23
|
-
return this.buildResultForManualCheck(rule,
|
|
23
|
+
return this.buildResultForManualCheck(rule, queryResults);
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
// Then we are considering rule as RuleCheckEnum.AUTO
|
|
27
|
-
|
|
27
|
+
const domNodes = queryResults.map((element) => element.domNode);
|
|
28
|
+
return this.buildResultForAutoCheck(rule, domNodes);
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
buildResultForAutoCheck(rule, $el) {
|
|
@@ -62,30 +63,31 @@ class Engine {
|
|
|
62
63
|
}
|
|
63
64
|
return a11YRuleresult;
|
|
64
65
|
}
|
|
65
|
-
buildResultForManualCheck(rule,
|
|
66
|
-
const
|
|
67
|
-
const validation =
|
|
66
|
+
buildResultForManualCheck(rule, queryResults) {
|
|
67
|
+
const a11YRuleResult = new model_1.A11yRuleResult(this.targetUrl, rule);
|
|
68
|
+
const validation = a11YRuleResult.getOrAddValidation(rule.criterion);
|
|
68
69
|
validation.status = model_1.A11yResultStatus.SUCCESS;
|
|
69
|
-
for (let i = 0; i <
|
|
70
|
-
const
|
|
70
|
+
for (let i = 0; i < queryResults.length; i++) {
|
|
71
|
+
const domNode = queryResults[i].domNode;
|
|
72
|
+
const selector = this.getSelector(domNode);
|
|
71
73
|
const attributesToCheck = [];
|
|
72
74
|
rule.attributes.forEach((attribute) => {
|
|
73
|
-
const attributeFilledWithInformation =
|
|
75
|
+
const attributeFilledWithInformation = domNode.getAttribute(attribute);
|
|
74
76
|
if (attributeFilledWithInformation) {
|
|
75
77
|
attributesToCheck.push(` ${attribute}=${attributeFilledWithInformation}`);
|
|
76
78
|
}
|
|
77
79
|
});
|
|
78
|
-
const manualValidation =
|
|
80
|
+
const manualValidation = a11YRuleResult.getOrAddValidation(rule.criterion);
|
|
79
81
|
manualValidation.status = model_1.A11yResultStatus.MANUAL;
|
|
80
82
|
manualValidation.nodesToCheckManually.push({
|
|
81
|
-
node:
|
|
83
|
+
node: queryResults[i],
|
|
82
84
|
selector: selector,
|
|
83
85
|
attributes: attributesToCheck.toString(),
|
|
84
|
-
html:
|
|
86
|
+
html: domNode.outerHTML,
|
|
85
87
|
help: rule.id ? `${this.reference.getRuleUrl(rule.id)}` : ""
|
|
86
88
|
});
|
|
87
89
|
}
|
|
88
|
-
return
|
|
90
|
+
return a11YRuleResult;
|
|
89
91
|
}
|
|
90
92
|
getSelector(element) {
|
|
91
93
|
const path = [];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { A11yRule } from "./rule";
|
|
2
2
|
import { A11yReference } from "./reference";
|
|
3
|
+
import { QueryResult } from "../query";
|
|
3
4
|
export declare enum A11yResultStatus {
|
|
4
5
|
UNKNOWN = "unknown",
|
|
5
6
|
SUCCESS = "success",
|
|
@@ -12,7 +13,7 @@ export interface NonCompliantNode {
|
|
|
12
13
|
html?: string;
|
|
13
14
|
}
|
|
14
15
|
export interface NodeToCheckManually {
|
|
15
|
-
node:
|
|
16
|
+
node: QueryResult;
|
|
16
17
|
selector: string;
|
|
17
18
|
attributes: string;
|
|
18
19
|
html: string;
|
package/dist/lib/model/rule.d.ts
CHANGED
|
@@ -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;
|
package/dist/lib/model/rule.js
CHANGED
|
@@ -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():
|
|
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,8 @@
|
|
|
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():
|
|
6
|
+
execute(): QueryResult[];
|
|
7
7
|
getSelector(): string;
|
|
8
8
|
}
|
|
@@ -12,7 +12,7 @@ class AccessibleNameQuery {
|
|
|
12
12
|
}
|
|
13
13
|
execute() {
|
|
14
14
|
return this.subQuery.execute().filter(element => {
|
|
15
|
-
const accessibleName = (0, dom_accessibility_api_1.computeAccessibleName)(element);
|
|
15
|
+
const accessibleName = (0, dom_accessibility_api_1.computeAccessibleName)(element.domNode);
|
|
16
16
|
if (this.shouldBeEmpty && (0, lodash_1.isEmpty)(accessibleName)) {
|
|
17
17
|
return true;
|
|
18
18
|
}
|
|
@@ -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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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
|
|
22
|
+
if (lodash_1.default.isEmpty(this.attributes) && lodash_1.default.isEmpty(this.excludedTags)) {
|
|
16
23
|
return true;
|
|
17
24
|
}
|
|
18
|
-
|
|
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
|
-
})
|
|
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():
|
|
5
|
+
execute(): QueryResult[];
|
|
6
6
|
getSelector(): string;
|
|
7
7
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ByTagQuery = void 0;
|
|
4
|
+
const _00_query_1 = require("./00-query");
|
|
4
5
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
5
6
|
const $ = require("jquery/dist/jquery.min");
|
|
6
7
|
class ByTagQuery {
|
|
@@ -9,7 +10,7 @@ class ByTagQuery {
|
|
|
9
10
|
this.selectors = selectors;
|
|
10
11
|
}
|
|
11
12
|
execute() {
|
|
12
|
-
return $(this.selectors.join(",")).toArray();
|
|
13
|
+
return $(this.selectors.join(",")).toArray().map((element) => new _00_query_1.QueryResult(element));
|
|
13
14
|
}
|
|
14
15
|
getSelector() {
|
|
15
16
|
return `${this.selectors}`;
|
|
@@ -0,0 +1,9 @@
|
|
|
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 EmptyElementWithIdSpecification implements IAttributeSpecification {
|
|
8
|
+
isSatisfiedBy(element: HTMLElement, attributeName: string): boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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.EmptyElementWithIdSpecification = 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
|
+
class EmptyAttributeSpecification {
|
|
11
|
+
isSatisfiedBy(element, attributeName) {
|
|
12
|
+
const attributeValue = element.getAttribute(attributeName);
|
|
13
|
+
return lodash_1.default.isEmpty(attributeValue);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.EmptyAttributeSpecification = EmptyAttributeSpecification;
|
|
17
|
+
class EmptyElementWithIdSpecification {
|
|
18
|
+
isSatisfiedBy(element, attributeName) {
|
|
19
|
+
const attributeValue = element.getAttribute(attributeName);
|
|
20
|
+
if (lodash_1.default.isEmpty(attributeValue) || lodash_1.default.isNull(attributeValue)) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const bindingNodeId = $(`#${attributeValue.replaceAll(".", "\\.")}`).text();
|
|
24
|
+
return lodash_1.default.isEmpty(bindingNodeId);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.EmptyElementWithIdSpecification = EmptyElementWithIdSpecification;
|
|
@@ -0,0 +1,18 @@
|
|
|
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 that the text of the HTMLElement whose id matches the value of the attribute named attributeName another HTMLElement is empty
|
|
15
|
+
* @param attributeName : HTMLElement attribute name
|
|
16
|
+
*/
|
|
17
|
+
static emptyHtmlNodeTargetedByTheAttribute(attributeName: string): CompliantSpecification;
|
|
18
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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 that the text of the HTMLElement whose id matches the value of the attribute named attributeName another HTMLElement is empty
|
|
24
|
+
* @param attributeName : HTMLElement attribute name
|
|
25
|
+
*/
|
|
26
|
+
static emptyHtmlNodeTargetedByTheAttribute(attributeName) {
|
|
27
|
+
return new CompliantSpecification(attributeName, new attribut_specification_1.EmptyElementWithIdSpecification());
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
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,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DoctypeQuery = void 0;
|
|
4
|
+
const _00_query_1 = require("./00-query");
|
|
4
5
|
class DoctypeQuery {
|
|
5
6
|
execute() {
|
|
6
7
|
if (document?.doctype?.name !== "html") {
|
|
7
|
-
return [document.documentElement];
|
|
8
|
+
return [new _00_query_1.QueryResult(document.documentElement)];
|
|
8
9
|
}
|
|
9
10
|
return [];
|
|
10
11
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Query } from "./00-query";
|
|
1
|
+
import { Query, QueryResult } from "./00-query";
|
|
2
2
|
export declare class FormQuery implements Query {
|
|
3
3
|
LABEL_ATTRIBUTE: string;
|
|
4
4
|
FORMFIELD_SELECTORS: string[];
|
|
5
5
|
FORMFIELD_LABEL_ATTRIBUTES: string[];
|
|
6
|
-
execute():
|
|
6
|
+
execute(): QueryResult[];
|
|
7
7
|
getSelector(): string;
|
|
8
8
|
}
|
|
@@ -3,4 +3,11 @@ export * from "./by-tag.query";
|
|
|
3
3
|
export * from "./doctype.query";
|
|
4
4
|
export * from "./form.query";
|
|
5
5
|
export * from "./by-role.query";
|
|
6
|
+
export * from "./by-sibling.query";
|
|
7
|
+
export * from "./operators/operator-query";
|
|
8
|
+
export * from "./operators/or-query";
|
|
9
|
+
export * from "./operators/and-query";
|
|
6
10
|
export * from "./accessible-name.query";
|
|
11
|
+
export * from "./compliant-attributes/compliant-attributes.query";
|
|
12
|
+
export * from "./compliant-attributes/attribute-checker";
|
|
13
|
+
export * from "./compliant-attributes/attribut-specification";
|
package/dist/lib/query/index.js
CHANGED
|
@@ -19,4 +19,11 @@ __exportStar(require("./by-tag.query"), exports);
|
|
|
19
19
|
__exportStar(require("./doctype.query"), exports);
|
|
20
20
|
__exportStar(require("./form.query"), exports);
|
|
21
21
|
__exportStar(require("./by-role.query"), exports);
|
|
22
|
+
__exportStar(require("./by-sibling.query"), exports);
|
|
23
|
+
__exportStar(require("./operators/operator-query"), exports);
|
|
24
|
+
__exportStar(require("./operators/or-query"), exports);
|
|
25
|
+
__exportStar(require("./operators/and-query"), exports);
|
|
22
26
|
__exportStar(require("./accessible-name.query"), exports);
|
|
27
|
+
__exportStar(require("./compliant-attributes/compliant-attributes.query"), exports);
|
|
28
|
+
__exportStar(require("./compliant-attributes/attribute-checker"), exports);
|
|
29
|
+
__exportStar(require("./compliant-attributes/attribut-specification"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IOperatorQuery } from "./operator-query";
|
|
2
|
+
import { Query, QueryResult } from "../00-query";
|
|
3
|
+
export declare class AndQuery implements IOperatorQuery, Query {
|
|
4
|
+
readonly queries: Query[];
|
|
5
|
+
constructor(queries: Query[]);
|
|
6
|
+
execute(): QueryResult[];
|
|
7
|
+
getSelector(): string;
|
|
8
|
+
}
|