Skip to content

Commit f2d2a36

Browse files
chore: drop aria-query (#139)
1 parent abb4fcb commit f2d2a36

19 files changed

+149
-173
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@guidepup/virtual-screen-reader",
3-
"version": "0.31.2",
3+
"version": "0.32.0",
44
"description": "Virtual Screen Reader driver for unit test automation.",
55
"author": "Craig Morten <[email protected]>",
66
"license": "MIT",
@@ -65,7 +65,6 @@
6565
"dependencies": {
6666
"@testing-library/dom": "^10.4.0",
6767
"@testing-library/user-event": "^14.6.1",
68-
"aria-query": "^5.3.2",
6968
"dom-accessibility-api": "^0.7.0",
7069
"html-aria": "^0.5.1"
7170
},

src/createAccessibilityTree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface AccessibilityNode {
1212
accessibleDescription: string;
1313
accessibleName: string;
1414
accessibleValue: string;
15-
allowedAccessibilityChildRoles: string[][];
15+
allowedAccessibilityChildRoles: string[];
1616
alternateReadingOrderParents: Node[];
1717
childrenPresentational: boolean;
1818
isInert: boolean;
Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,54 @@
1-
import { ARIARoleDefinitionKey, roles } from "aria-query";
2-
import { globalStatesAndProperties, reverseSynonymRolesMap } from "../getRole";
1+
import { ARIAAttribute, ARIARole, roles } from "html-aria";
2+
import { globalStatesAndProperties } from "../getRole";
33

44
const ignoreAttributesWithAccessibleValue = new Set(["aria-placeholder"]);
55

6+
const nonSpecCompliantAttributeMap: Record<
7+
string,
8+
Record<string, boolean | number | string | null>
9+
> = {
10+
listitem: { "aria-level": null },
11+
option: { "aria-selected": false },
12+
};
13+
614
export const getAttributesByRole = ({
715
accessibleValue,
816
role,
917
}: {
1018
accessibleValue: string;
1119
role: string;
1220
}): [string, string | null][] => {
13-
// TODO: temporary solution until aria-query is updated with WAI-ARIA 1.3
14-
// synonym roles, or the html-aria package supports implicit attribute
15-
// values.
16-
const reverseSynonymRole = (reverseSynonymRolesMap[role] ??
17-
role) as ARIARoleDefinitionKey;
18-
19-
// TODO: swap out with the html-aria package if implicit role attributes
20-
// become supported.
2121
const {
22-
props: implicitRoleAttributes = {},
23-
prohibitedProps: prohibitedAttributes = [],
24-
} = (roles.get(reverseSynonymRole) ?? {}) as {
25-
props: Record<string, string | undefined>;
26-
prohibitedProps: string[];
22+
supported: supportedAttributes = [],
23+
defaultAttributeValues = {},
24+
prohibited: prohibitedAttributes = [],
25+
} = roles[role as ARIARole] ?? {};
26+
27+
const implicitRoleAttributes = {
28+
...defaultAttributeValues,
29+
...nonSpecCompliantAttributeMap[role],
2730
};
2831

2932
const uniqueAttributes = Array.from(
3033
new Set([
3134
...Object.keys(implicitRoleAttributes),
35+
...supportedAttributes,
3236
...globalStatesAndProperties,
3337
])
3438
)
35-
.filter((attribute) => !prohibitedAttributes.includes(attribute))
39+
.filter(
40+
(attribute) => !prohibitedAttributes.includes(attribute as ARIAAttribute)
41+
)
3642
.filter(
3743
(attribute) =>
3844
!accessibleValue || !ignoreAttributesWithAccessibleValue.has(attribute)
3945
);
4046

4147
return uniqueAttributes.map((attribute) => [
4248
attribute,
43-
implicitRoleAttributes[attribute] ?? null,
49+
attribute in implicitRoleAttributes &&
50+
implicitRoleAttributes[attribute] !== null
51+
? implicitRoleAttributes[attribute].toString()
52+
: null,
4453
]);
4554
};

src/getNodeAccessibilityData/getRole.ts

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { getRole as getHtmlAriaRole, roles } from "html-aria";
2-
import { roles as backupRoles } from "aria-query";
1+
import { ALL_ROLES, ARIARole, getRole as getHtmlAriaRole } from "html-aria";
32
import { getLocalName } from "../getLocalName";
43
import { isElement } from "../isElement";
54

@@ -11,22 +10,7 @@ export const synonymRolesMap: Record<string, string> = {
1110
directory: "list",
1211
};
1312

14-
export const reverseSynonymRolesMap: Record<string, string> =
15-
Object.fromEntries(
16-
Object.entries(synonymRolesMap).map(([key, value]) => [value, key])
17-
);
18-
19-
const allowedNonAbstractRoles = new Set([
20-
...(Object.entries(roles)
21-
.filter(([, { type }]) => !type.includes("abstract"))
22-
.map(([key]) => key) as string[]),
23-
// TODO: remove once the `html-aria` package supports `dpub-aam` /
24-
// `dpub-aria` specifications.
25-
...(backupRoles
26-
.entries()
27-
.filter(([, { abstract }]) => !abstract)
28-
.map(([key]) => key) as string[]),
29-
]);
13+
const allowedNonAbstractRoles = new Set(ALL_ROLES);
3014

3115
const rolesRequiringName = new Set(["form", "region"]);
3216

@@ -84,7 +68,7 @@ function getExplicitRole({
8468
node,
8569
}: {
8670
accessibleName: string;
87-
allowedAccessibilityRoles: string[][];
71+
allowedAccessibilityRoles: string[];
8872
inheritedImplicitPresentational: boolean;
8973
node: HTMLElement;
9074
}) {
@@ -99,7 +83,7 @@ function getExplicitRole({
9983
*
10084
* REF: https://www.w3.org/TR/wai-aria-1.2/#document-handling_author-errors_roles
10185
*/
102-
.filter((role) => allowedNonAbstractRoles.has(role))
86+
.filter((role) => allowedNonAbstractRoles.has(role as ARIARole))
10387
/**
10488
* Certain landmark roles require names from authors. In situations where
10589
* an author has not specified names for these landmarks, it is
@@ -133,7 +117,7 @@ function getExplicitRole({
133117
*/
134118

135119
const isExplicitAllowedChildElement = allowedAccessibilityRoles.some(
136-
([allowedExplicitRole]) =>
120+
(allowedExplicitRole) =>
137121
authorErrorFilteredRoles?.[0] === allowedExplicitRole
138122
);
139123

@@ -182,7 +166,7 @@ export function getRole({
182166
node,
183167
}: {
184168
accessibleName: string;
185-
allowedAccessibilityRoles: string[][];
169+
allowedAccessibilityRoles: string[];
186170
inheritedImplicitPresentational: boolean;
187171
node: Node;
188172
}): { explicitRole: string; implicitRole: string; role: string } {

src/getNodeAccessibilityData/index.ts

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,17 @@
1-
import { ARIARoleDefinition, ARIARoleDefinitionKey, roles } from "aria-query";
2-
import { getRole, presentationRoles, synonymRolesMap } from "./getRole";
1+
import { ARIARole, roles } from "html-aria";
2+
import { getRole, presentationRoles } from "./getRole";
33
import { getAccessibleDescription } from "./getAccessibleDescription";
44
import { getAccessibleName } from "./getAccessibleName";
55
import { getAccessibleValue } from "./getAccessibleValue";
66
import { getLocalName } from "../getLocalName";
77
import { isDialogRole } from "../isDialogRole";
88
import { isElement } from "../isElement";
99

10-
// TODO: swap out with the html-aria package once it supports `dpub-aam` /
11-
// `dpub-aria` specifications.
12-
const childrenPresentationalRoles = new Set([
13-
...(roles
14-
.entries()
10+
const childrenPresentationalRoles = new Set(
11+
Object.entries(roles)
1512
.filter(([, { childrenPresentational }]) => childrenPresentational)
16-
.map(([key]) => key) as string[]),
17-
// TODO: temporary catering to WAI-ARIA 1.3 synonym roles that aria-query
18-
// doesn't handle.
19-
...(Object.entries(synonymRolesMap)
20-
.map(
21-
([from, to]) =>
22-
[to, roles.get(from as ARIARoleDefinitionKey)] as
23-
| [ARIARoleDefinitionKey, ARIARoleDefinition]
24-
| [ARIARoleDefinitionKey, undefined]
25-
)
26-
.filter(([, role]) => role?.childrenPresentational)
27-
.map(([key]) => key) as string[]),
28-
]);
13+
.map(([key]) => key) as string[]
14+
);
2915

3016
const getSpokenRole = ({
3117
isGeneric,
@@ -108,7 +94,7 @@ export function getNodeAccessibilityData({
10894
inheritedImplicitPresentational,
10995
node,
11096
}: {
111-
allowedAccessibilityRoles: string[][];
97+
allowedAccessibilityRoles: string[];
11298
inheritedImplicitInert: boolean;
11399
inheritedImplicitPresentational: boolean;
114100
node: Node;
@@ -138,16 +124,17 @@ export function getNodeAccessibilityData({
138124
role,
139125
});
140126

141-
const { requiredOwnedElements: allowedAccessibilityChildRoles } = (roles.get(
142-
role as ARIARoleDefinitionKey
143-
) as unknown as {
144-
requiredOwnedElements: string[][];
145-
}) ?? { requiredOwnedElements: [] };
127+
const { allowedChildRoles: allowedAccessibilityChildRoles } = roles[
128+
role as ARIARole
129+
] ?? {
130+
allowedChildRoles: [],
131+
};
146132

147-
const { requiredOwnedElements: implicitAllowedAccessibilityChildRoles } =
148-
(roles.get(implicitRole as ARIARoleDefinitionKey) as unknown as {
149-
requiredOwnedElements: string[][];
150-
}) ?? { requiredOwnedElements: [] };
133+
const { allowedChildRoles: implicitAllowedAccessibilityChildRoles } = roles[
134+
implicitRole as ARIARole
135+
] ?? {
136+
allowedChildRoles: [],
137+
};
151138

152139
/**
153140
* Any descendants of elements that have the characteristic "Children

test/int/accessibleValue.int.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ describe("Placeholder Attribute Property", () => {
111111
await virtual.next();
112112

113113
expect(await virtual.lastSpokenPhrase()).toBe(
114-
"combobox, second, not expanded, has popup listbox"
114+
"combobox, second, has popup listbox, not expanded"
115115
);
116116

117117
await virtual.stop();
@@ -130,7 +130,7 @@ describe("Placeholder Attribute Property", () => {
130130
await virtual.next();
131131

132132
expect(await virtual.lastSpokenPhrase()).toBe(
133-
"listbox, second; third, multi-selectable, orientated vertically"
133+
"listbox, second; third, orientated vertically, multi-selectable"
134134
);
135135

136136
await virtual.stop();
@@ -150,7 +150,7 @@ describe("Placeholder Attribute Property", () => {
150150
await virtual.next();
151151

152152
expect(await virtual.lastSpokenPhrase()).toBe(
153-
"combobox, not expanded, has popup listbox"
153+
"combobox, has popup listbox, not expanded"
154154
);
155155

156156
await virtual.stop();
@@ -167,7 +167,7 @@ describe("Placeholder Attribute Property", () => {
167167
await virtual.next();
168168

169169
expect(await virtual.lastSpokenPhrase()).toBe(
170-
"progressbar, Loading:, 23, max value 100, current value 23%"
170+
"progressbar, Loading:, 23, max value 100, min value 0, current value 23%"
171171
);
172172

173173
await virtual.stop();
@@ -184,7 +184,7 @@ describe("Placeholder Attribute Property", () => {
184184
await virtual.next();
185185

186186
expect(await virtual.lastSpokenPhrase()).toBe(
187-
"progressbar, Loading:, max value 100, current value 23%"
187+
"progressbar, Loading:, max value 100, min value 0, current value 23%"
188188
);
189189

190190
await virtual.stop();
@@ -201,7 +201,7 @@ describe("Placeholder Attribute Property", () => {
201201
await virtual.next();
202202

203203
expect(await virtual.lastSpokenPhrase()).toBe(
204-
"progressbar, Loading:, current value massive, max value 100"
204+
"progressbar, Loading:, max value 100, min value 0, current value massive"
205205
);
206206

207207
await virtual.stop();

test/int/allowedAccessibilityChildRoles.int.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe("Allowed Accessibility Child Roles", () => {
2222
expect(await virtual.spokenPhraseLog()).toEqual([
2323
"document",
2424
"listbox, orientated vertically",
25-
"option, option text, position 1, set size 1, not selected",
25+
"option, option text, not selected, position 1, set size 1",
2626
"end of listbox, orientated vertically",
2727
"end of document",
2828
]);
@@ -48,7 +48,7 @@ describe("Allowed Accessibility Child Roles", () => {
4848
expect(await virtual.spokenPhraseLog()).toEqual([
4949
"document",
5050
"listbox, orientated vertically",
51-
"option, option text, position 1, set size 1, not selected",
51+
"option, option text, not selected, position 1, set size 1",
5252
"end of listbox, orientated vertically",
5353
"end of document",
5454
]);
@@ -71,7 +71,7 @@ describe("Allowed Accessibility Child Roles", () => {
7171
expect(await virtual.spokenPhraseLog()).toEqual([
7272
"document",
7373
"listbox, orientated vertically",
74-
"option, option text, position 1, set size 1, not selected",
74+
"option, option text, not selected, position 1, set size 1",
7575
"end of listbox, orientated vertically",
7676
"end of document",
7777
]);
@@ -98,7 +98,7 @@ describe("Allowed Accessibility Child Roles", () => {
9898
expect(await virtual.spokenPhraseLog()).toEqual([
9999
"document",
100100
"listbox, orientated vertically",
101-
"option, option text, position 1, set size 1, not selected",
101+
"option, option text, not selected, position 1, set size 1",
102102
"end of listbox, orientated vertically",
103103
"end of document",
104104
]);

test/int/ariaActiveDescendant.int.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe("Aria Active Descendant", () => {
2525

2626
expect(await virtual.spokenPhraseLog()).toEqual([
2727
"document",
28-
"combobox, active descendant California, autocomplete in list, read only, not expanded, has popup listbox",
28+
"combobox, has popup listbox, not expanded, active descendant California, autocomplete in list, read only",
2929
]);
3030

3131
await virtual.stop();
@@ -50,7 +50,7 @@ describe("Aria Active Descendant", () => {
5050

5151
expect(await virtual.spokenPhraseLog()).toEqual([
5252
"document",
53-
"combobox, autocomplete in list, read only, not expanded, has popup listbox",
53+
"combobox, has popup listbox, not expanded, autocomplete in list, read only",
5454
]);
5555

5656
await virtual.stop();

test/int/ariaActiveDescendantCombobox.int.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ describe("Aria Active Descendant", () => {
2424
expect(await virtual.spokenPhraseLog()).toEqual([
2525
"document",
2626
"State",
27-
"combobox, State, autocomplete in list, not expanded, has popup listbox, 1 control",
28-
"combobox, State, autocomplete in list, expanded, has popup listbox, 1 control",
29-
"combobox, State, nebr, autocomplete in list, expanded, has popup listbox, 1 control",
30-
"combobox, State, nebr, active descendant Nebraska, autocomplete in list, expanded, has popup listbox, 1 control",
27+
"combobox, State, has popup listbox, not expanded, autocomplete in list, 1 control",
28+
"combobox, State, has popup listbox, expanded, autocomplete in list, 1 control",
29+
"combobox, State, nebr, has popup listbox, expanded, autocomplete in list, 1 control",
30+
"combobox, State, nebr, has popup listbox, expanded, active descendant Nebraska, autocomplete in list, 1 control",
3131
]);
3232
});
3333
});

test/int/ariaActiveDescendantMenuButton1.int.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ describe("Aria Active Descendant Menu Button", () => {
2121

2222
expect(await virtual.spokenPhraseLog()).toEqual([
2323
"document",
24-
"button, Actions, has popup menu, 1 control",
25-
"button, Actions, expanded, has popup menu, 1 control",
24+
"button, Actions, 1 control, has popup menu",
25+
"button, Actions, 1 control, expanded, has popup menu",
2626
"menu, Actions, orientated vertically, active descendant Action 1",
2727
]);
2828

0 commit comments

Comments
 (0)