@arcaauth/eslint-plugin-jsx-a11y 6.10.2
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/.babelrc +17 -0
- package/.eslintrc +44 -0
- package/CHANGELOG.md +774 -0
- package/LICENSE.md +8 -0
- package/README.md +423 -0
- package/__mocks__/IdentifierMock.js +15 -0
- package/__mocks__/JSXAttributeMock.js +39 -0
- package/__mocks__/JSXElementMock.js +37 -0
- package/__mocks__/JSXExpressionContainerMock.js +15 -0
- package/__mocks__/JSXSpreadAttributeMock.js +18 -0
- package/__mocks__/JSXTextMock.js +17 -0
- package/__mocks__/LiteralMock.js +17 -0
- package/__mocks__/genInteractives.js +218 -0
- package/__tests__/__util__/axeMapping.js +6 -0
- package/__tests__/__util__/helpers/getESLintCoreRule.js +9 -0
- package/__tests__/__util__/helpers/parsers.js +186 -0
- package/__tests__/__util__/parserOptionsMapper.js +53 -0
- package/__tests__/__util__/ruleOptionsMapperFactory.js +33 -0
- package/__tests__/index-test.js +40 -0
- package/__tests__/src/rules/accessible-emoji-test.js +66 -0
- package/__tests__/src/rules/alt-text-test.js +291 -0
- package/__tests__/src/rules/anchor-ambiguous-text-test.js +117 -0
- package/__tests__/src/rules/anchor-has-content-test.js +54 -0
- package/__tests__/src/rules/anchor-is-valid-test.js +532 -0
- package/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js +95 -0
- package/__tests__/src/rules/aria-props-test.js +69 -0
- package/__tests__/src/rules/aria-proptypes-test.js +311 -0
- package/__tests__/src/rules/aria-role-test.js +118 -0
- package/__tests__/src/rules/aria-unsupported-elements-test.js +75 -0
- package/__tests__/src/rules/autocomplete-valid-test.js +77 -0
- package/__tests__/src/rules/click-events-have-key-events-test.js +77 -0
- package/__tests__/src/rules/control-has-associated-label-test.js +327 -0
- package/__tests__/src/rules/heading-has-content-test.js +85 -0
- package/__tests__/src/rules/html-has-lang-test.js +42 -0
- package/__tests__/src/rules/iframe-has-title-test.js +55 -0
- package/__tests__/src/rules/img-redundant-alt-test.js +137 -0
- package/__tests__/src/rules/interactive-supports-focus-test.js +267 -0
- package/__tests__/src/rules/label-has-associated-control-test.js +243 -0
- package/__tests__/src/rules/label-has-for-test.js +235 -0
- package/__tests__/src/rules/lang-test.js +59 -0
- package/__tests__/src/rules/media-has-caption-test.js +220 -0
- package/__tests__/src/rules/mouse-events-have-key-events-test.js +154 -0
- package/__tests__/src/rules/no-access-key-test.js +48 -0
- package/__tests__/src/rules/no-aria-hidden-on-focusable-test.js +44 -0
- package/__tests__/src/rules/no-autofocus-test.js +68 -0
- package/__tests__/src/rules/no-distracting-elements-test.js +51 -0
- package/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js +405 -0
- package/__tests__/src/rules/no-noninteractive-element-interactions-test.js +502 -0
- package/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js +500 -0
- package/__tests__/src/rules/no-noninteractive-tabindex-test.js +123 -0
- package/__tests__/src/rules/no-onchange-test.js +57 -0
- package/__tests__/src/rules/no-redundant-roles-test.js +98 -0
- package/__tests__/src/rules/no-static-element-interactions-test.js +501 -0
- package/__tests__/src/rules/prefer-tag-over-role-test.js +63 -0
- package/__tests__/src/rules/role-has-required-aria-props-test.js +134 -0
- package/__tests__/src/rules/role-supports-aria-props-test.js +570 -0
- package/__tests__/src/rules/scope-test.js +50 -0
- package/__tests__/src/rules/tabindex-no-positive-test.js +55 -0
- package/__tests__/src/util/attributesComparator-test.js +91 -0
- package/__tests__/src/util/getAccessibleChildText-test.js +174 -0
- package/__tests__/src/util/getComputedRole-test.js +71 -0
- package/__tests__/src/util/getElementType-test.js +154 -0
- package/__tests__/src/util/getExplicitRole-test.js +35 -0
- package/__tests__/src/util/getImplicitRole-test.js +25 -0
- package/__tests__/src/util/getSuggestion-test.js +33 -0
- package/__tests__/src/util/getTabIndex-test.js +85 -0
- package/__tests__/src/util/hasAccessibleChild-test.js +157 -0
- package/__tests__/src/util/implicitRoles/input-test.js +87 -0
- package/__tests__/src/util/implicitRoles/menu-test.js +20 -0
- package/__tests__/src/util/implicitRoles/menuitem-test.js +38 -0
- package/__tests__/src/util/isAbstractRole-test.js +51 -0
- package/__tests__/src/util/isContentEditable-test.js +52 -0
- package/__tests__/src/util/isDOMElement-test.js +30 -0
- package/__tests__/src/util/isDisabledElement-test.js +88 -0
- package/__tests__/src/util/isFocusable-test.js +111 -0
- package/__tests__/src/util/isInteractiveElement-test.js +104 -0
- package/__tests__/src/util/isInteractiveRole-test.js +59 -0
- package/__tests__/src/util/isNonInteractiveElement-test.js +97 -0
- package/__tests__/src/util/isNonInteractiveRole-test.js +59 -0
- package/__tests__/src/util/isNonLiteralProperty-test.js +52 -0
- package/__tests__/src/util/isSemanticRoleElement-test.js +72 -0
- package/__tests__/src/util/mayContainChildComponent-test.js +219 -0
- package/__tests__/src/util/mayHaveAccessibleLabel-test.js +256 -0
- package/__tests__/src/util/parserOptionsMapper-test.js +93 -0
- package/__tests__/src/util/schemas-test.js +35 -0
- package/docs/rules/accessible-emoji.md +30 -0
- package/docs/rules/alt-text.md +168 -0
- package/docs/rules/anchor-ambiguous-text.md +91 -0
- package/docs/rules/anchor-has-content.md +64 -0
- package/docs/rules/anchor-is-valid.md +270 -0
- package/docs/rules/aria-activedescendant-has-tabindex.md +52 -0
- package/docs/rules/aria-props.md +29 -0
- package/docs/rules/aria-proptypes.md +30 -0
- package/docs/rules/aria-role.md +51 -0
- package/docs/rules/aria-unsupported-elements.md +30 -0
- package/docs/rules/autocomplete-valid.md +49 -0
- package/docs/rules/click-events-have-key-events.md +28 -0
- package/docs/rules/control-has-associated-label.md +113 -0
- package/docs/rules/heading-has-content.md +67 -0
- package/docs/rules/html-has-lang.md +31 -0
- package/docs/rules/iframe-has-title.md +37 -0
- package/docs/rules/img-redundant-alt.md +48 -0
- package/docs/rules/interactive-supports-focus.md +156 -0
- package/docs/rules/label-has-associated-control.md +152 -0
- package/docs/rules/label-has-for.md +130 -0
- package/docs/rules/lang.md +31 -0
- package/docs/rules/media-has-caption.md +48 -0
- package/docs/rules/mouse-events-have-key-events.md +58 -0
- package/docs/rules/no-access-key.md +30 -0
- package/docs/rules/no-aria-hidden-on-focusable.md +37 -0
- package/docs/rules/no-autofocus.md +43 -0
- package/docs/rules/no-distracting-elements.md +41 -0
- package/docs/rules/no-interactive-element-to-noninteractive-role.md +73 -0
- package/docs/rules/no-noninteractive-element-interactions.md +145 -0
- package/docs/rules/no-noninteractive-element-to-interactive-role.md +76 -0
- package/docs/rules/no-noninteractive-tabindex.md +115 -0
- package/docs/rules/no-onchange.md +36 -0
- package/docs/rules/no-redundant-roles.md +46 -0
- package/docs/rules/no-static-element-interactions.md +114 -0
- package/docs/rules/prefer-tag-over-role.md +32 -0
- package/docs/rules/role-has-required-aria-props.md +31 -0
- package/docs/rules/role-supports-aria-props.md +39 -0
- package/docs/rules/scope.md +30 -0
- package/docs/rules/tabindex-no-positive.md +32 -0
- package/lib/configs/flat-config-base.js +11 -0
- package/lib/configs/legacy-config-base.js +9 -0
- package/lib/index.js +209 -0
- package/lib/rules/accessible-emoji.js +63 -0
- package/lib/rules/alt-text.js +218 -0
- package/lib/rules/anchor-ambiguous-text.js +64 -0
- package/lib/rules/anchor-has-content.js +60 -0
- package/lib/rules/anchor-is-valid.js +122 -0
- package/lib/rules/aria-activedescendant-has-tabindex.js +66 -0
- package/lib/rules/aria-props.js +59 -0
- package/lib/rules/aria-proptypes.js +114 -0
- package/lib/rules/aria-role.js +89 -0
- package/lib/rules/aria-unsupported-elements.js +64 -0
- package/lib/rules/autocomplete-valid.js +67 -0
- package/lib/rules/click-events-have-key-events.js +68 -0
- package/lib/rules/control-has-associated-label.js +103 -0
- package/lib/rules/heading-has-content.js +61 -0
- package/lib/rules/html-has-lang.js +50 -0
- package/lib/rules/iframe-has-title.js +50 -0
- package/lib/rules/img-redundant-alt.js +88 -0
- package/lib/rules/interactive-supports-focus.js +87 -0
- package/lib/rules/label-has-associated-control.js +127 -0
- package/lib/rules/label-has-for.js +150 -0
- package/lib/rules/lang.js +68 -0
- package/lib/rules/media-has-caption.js +96 -0
- package/lib/rules/mouse-events-have-key-events.js +94 -0
- package/lib/rules/no-access-key.js +43 -0
- package/lib/rules/no-aria-hidden-on-focusable.js +47 -0
- package/lib/rules/no-autofocus.js +62 -0
- package/lib/rules/no-distracting-elements.js +54 -0
- package/lib/rules/no-interactive-element-to-noninteractive-role.js +81 -0
- package/lib/rules/no-noninteractive-element-interactions.js +95 -0
- package/lib/rules/no-noninteractive-element-to-interactive-role.js +80 -0
- package/lib/rules/no-noninteractive-tabindex.js +109 -0
- package/lib/rules/no-onchange.js +52 -0
- package/lib/rules/no-redundant-roles.js +86 -0
- package/lib/rules/no-static-element-interactions.js +102 -0
- package/lib/rules/prefer-tag-over-role.js +75 -0
- package/lib/rules/role-has-required-aria-props.js +88 -0
- package/lib/rules/role-supports-aria-props.js +78 -0
- package/lib/rules/scope.js +58 -0
- package/lib/rules/tabindex-no-positive.js +53 -0
- package/lib/util/attributesComparator.js +34 -0
- package/lib/util/getAccessibleChildText.js +55 -0
- package/lib/util/getComputedRole.js +19 -0
- package/lib/util/getElementType.js +30 -0
- package/lib/util/getExplicitRole.js +27 -0
- package/lib/util/getImplicitRole.js +24 -0
- package/lib/util/getSuggestion.js +32 -0
- package/lib/util/getTabIndex.js +34 -0
- package/lib/util/hasAccessibleChild.js +30 -0
- package/lib/util/implicitRoles/a.js +17 -0
- package/lib/util/implicitRoles/area.js +17 -0
- package/lib/util/implicitRoles/article.js +13 -0
- package/lib/util/implicitRoles/aside.js +13 -0
- package/lib/util/implicitRoles/body.js +13 -0
- package/lib/util/implicitRoles/button.js +13 -0
- package/lib/util/implicitRoles/datalist.js +13 -0
- package/lib/util/implicitRoles/details.js +13 -0
- package/lib/util/implicitRoles/dialog.js +13 -0
- package/lib/util/implicitRoles/form.js +13 -0
- package/lib/util/implicitRoles/h1.js +13 -0
- package/lib/util/implicitRoles/h2.js +13 -0
- package/lib/util/implicitRoles/h3.js +13 -0
- package/lib/util/implicitRoles/h4.js +13 -0
- package/lib/util/implicitRoles/h5.js +13 -0
- package/lib/util/implicitRoles/h6.js +13 -0
- package/lib/util/implicitRoles/hr.js +13 -0
- package/lib/util/implicitRoles/img.js +31 -0
- package/lib/util/implicitRoles/index.js +82 -0
- package/lib/util/implicitRoles/input.js +38 -0
- package/lib/util/implicitRoles/li.js +13 -0
- package/lib/util/implicitRoles/link.js +17 -0
- package/lib/util/implicitRoles/menu.js +19 -0
- package/lib/util/implicitRoles/menuitem.js +28 -0
- package/lib/util/implicitRoles/meter.js +13 -0
- package/lib/util/implicitRoles/nav.js +13 -0
- package/lib/util/implicitRoles/ol.js +13 -0
- package/lib/util/implicitRoles/option.js +13 -0
- package/lib/util/implicitRoles/output.js +13 -0
- package/lib/util/implicitRoles/progress.js +13 -0
- package/lib/util/implicitRoles/section.js +13 -0
- package/lib/util/implicitRoles/select.js +13 -0
- package/lib/util/implicitRoles/tbody.js +13 -0
- package/lib/util/implicitRoles/textarea.js +13 -0
- package/lib/util/implicitRoles/tfoot.js +13 -0
- package/lib/util/implicitRoles/thead.js +13 -0
- package/lib/util/implicitRoles/ul.js +13 -0
- package/lib/util/isAbstractRole.js +23 -0
- package/lib/util/isContentEditable.js +13 -0
- package/lib/util/isDOMElement.js +15 -0
- package/lib/util/isDisabledElement.js +23 -0
- package/lib/util/isFocusable.js +23 -0
- package/lib/util/isHiddenFromScreenReader.js +26 -0
- package/lib/util/isInteractiveElement.js +116 -0
- package/lib/util/isInteractiveRole.js +54 -0
- package/lib/util/isNonInteractiveElement.js +131 -0
- package/lib/util/isNonInteractiveRole.js +55 -0
- package/lib/util/isNonLiteralProperty.js +29 -0
- package/lib/util/isPresentationRole.js +13 -0
- package/lib/util/isSemanticRoleElement.js +54 -0
- package/lib/util/mayContainChildComponent.js +50 -0
- package/lib/util/mayHaveAccessibleLabel.js +95 -0
- package/lib/util/schemas.js +52 -0
- package/package.json +120 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
|
|
3
|
+
import getTabIndex from '../../../src/util/getTabIndex';
|
|
4
|
+
import IdentifierMock from '../../../__mocks__/IdentifierMock';
|
|
5
|
+
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
|
6
|
+
|
|
7
|
+
test('getTabIndex', (t) => {
|
|
8
|
+
t.equal(
|
|
9
|
+
getTabIndex(JSXAttributeMock('tabIndex', 0)),
|
|
10
|
+
0,
|
|
11
|
+
'tabIndex is defined as zero -> zero',
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
t.equal(
|
|
15
|
+
getTabIndex(JSXAttributeMock('tabIndex', 1)),
|
|
16
|
+
1,
|
|
17
|
+
'tabIndex is defined as a positive integer -> returns it',
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
t.equal(
|
|
21
|
+
getTabIndex(JSXAttributeMock('tabIndex', -1)),
|
|
22
|
+
-1,
|
|
23
|
+
'tabIndex is defined as a negative integer -> returns it',
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
t.equal(
|
|
27
|
+
getTabIndex(JSXAttributeMock('tabIndex', '')),
|
|
28
|
+
undefined,
|
|
29
|
+
'tabIndex is defined as an empty string -> undefined',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
t.equal(
|
|
33
|
+
getTabIndex(JSXAttributeMock('tabIndex', 9.1)),
|
|
34
|
+
undefined,
|
|
35
|
+
'tabIndex is defined as a float -> undefined',
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
t.equal(
|
|
39
|
+
getTabIndex(JSXAttributeMock('tabIndex', '0')),
|
|
40
|
+
0,
|
|
41
|
+
'tabIndex is defined as a string which converts to a number -> returns the integer',
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
t.equal(
|
|
45
|
+
getTabIndex(JSXAttributeMock('tabIndex', '0a')),
|
|
46
|
+
undefined,
|
|
47
|
+
'tabIndex is defined as a string which is NaN -> returns undefined',
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
t.equal(
|
|
51
|
+
getTabIndex(JSXAttributeMock('tabIndex', true)),
|
|
52
|
+
undefined,
|
|
53
|
+
'tabIndex is defined as true -> returns undefined',
|
|
54
|
+
);
|
|
55
|
+
t.equal(
|
|
56
|
+
getTabIndex(JSXAttributeMock('tabIndex', false)),
|
|
57
|
+
undefined,
|
|
58
|
+
'tabIndex is defined as false -> returns undefined',
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
t.equal(
|
|
62
|
+
typeof getTabIndex(JSXAttributeMock('tabIndex', () => 0)),
|
|
63
|
+
'function',
|
|
64
|
+
'tabIndex is defined as a function expression -> returns the correct type',
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const name = 'identName';
|
|
68
|
+
t.equal(
|
|
69
|
+
getTabIndex(JSXAttributeMock(
|
|
70
|
+
'tabIndex',
|
|
71
|
+
IdentifierMock(name),
|
|
72
|
+
true,
|
|
73
|
+
)),
|
|
74
|
+
name,
|
|
75
|
+
'tabIndex is defined as a variable expression -> returns the Identifier name',
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
t.equal(
|
|
79
|
+
getTabIndex(JSXAttributeMock('tabIndex', undefined)),
|
|
80
|
+
undefined,
|
|
81
|
+
'tabIndex is not defined -> returns undefined',
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
t.end();
|
|
85
|
+
});
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import { elementType } from 'jsx-ast-utils';
|
|
3
|
+
|
|
4
|
+
import hasAccessibleChild from '../../../src/util/hasAccessibleChild';
|
|
5
|
+
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
|
6
|
+
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
|
7
|
+
import JSXExpressionContainerMock from '../../../__mocks__/JSXExpressionContainerMock';
|
|
8
|
+
|
|
9
|
+
test('hasAccessibleChild', (t) => {
|
|
10
|
+
t.equal(
|
|
11
|
+
hasAccessibleChild(JSXElementMock('div', []), elementType),
|
|
12
|
+
false,
|
|
13
|
+
'has no children and does not set dangerouslySetInnerHTML -> false',
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
t.equal(
|
|
17
|
+
hasAccessibleChild(
|
|
18
|
+
JSXElementMock('div', [JSXAttributeMock('dangerouslySetInnerHTML', true)], []),
|
|
19
|
+
elementType,
|
|
20
|
+
),
|
|
21
|
+
true,
|
|
22
|
+
'has no children and sets dangerouslySetInnerHTML -> true',
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
t.equal(
|
|
26
|
+
hasAccessibleChild(
|
|
27
|
+
JSXElementMock(
|
|
28
|
+
'div',
|
|
29
|
+
[],
|
|
30
|
+
[{
|
|
31
|
+
type: 'Literal',
|
|
32
|
+
value: 'foo',
|
|
33
|
+
}],
|
|
34
|
+
),
|
|
35
|
+
elementType,
|
|
36
|
+
),
|
|
37
|
+
true,
|
|
38
|
+
'has children + Literal child -> true',
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
t.equal(
|
|
42
|
+
hasAccessibleChild(
|
|
43
|
+
JSXElementMock('div', [], [JSXElementMock('div', [])]),
|
|
44
|
+
elementType,
|
|
45
|
+
),
|
|
46
|
+
true,
|
|
47
|
+
'has children + visible JSXElement child -> true',
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
t.equal(
|
|
51
|
+
hasAccessibleChild(
|
|
52
|
+
JSXElementMock('div', [], [{
|
|
53
|
+
type: 'JSXText',
|
|
54
|
+
value: 'foo',
|
|
55
|
+
}]),
|
|
56
|
+
elementType,
|
|
57
|
+
),
|
|
58
|
+
true,
|
|
59
|
+
'has children + JSText element -> true',
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
t.equal(
|
|
63
|
+
hasAccessibleChild(
|
|
64
|
+
JSXElementMock('div', [], [
|
|
65
|
+
JSXElementMock('div', [
|
|
66
|
+
JSXAttributeMock('aria-hidden', true),
|
|
67
|
+
]),
|
|
68
|
+
]),
|
|
69
|
+
elementType,
|
|
70
|
+
),
|
|
71
|
+
false,
|
|
72
|
+
'has children + hidden child JSXElement -> false',
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
t.equal(
|
|
76
|
+
hasAccessibleChild(
|
|
77
|
+
JSXElementMock('div', [], [
|
|
78
|
+
JSXExpressionContainerMock({
|
|
79
|
+
type: 'Identifier',
|
|
80
|
+
name: 'foo',
|
|
81
|
+
}),
|
|
82
|
+
]),
|
|
83
|
+
elementType,
|
|
84
|
+
),
|
|
85
|
+
true,
|
|
86
|
+
'defined JSXExpressionContainer -> true',
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
t.equal(
|
|
90
|
+
hasAccessibleChild(
|
|
91
|
+
JSXElementMock('div', [], [
|
|
92
|
+
JSXExpressionContainerMock({
|
|
93
|
+
type: 'Identifier',
|
|
94
|
+
name: 'undefined',
|
|
95
|
+
}),
|
|
96
|
+
]),
|
|
97
|
+
elementType,
|
|
98
|
+
),
|
|
99
|
+
false,
|
|
100
|
+
'has children + undefined JSXExpressionContainer -> false',
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
t.equal(
|
|
104
|
+
hasAccessibleChild(
|
|
105
|
+
JSXElementMock('div', [], [{
|
|
106
|
+
type: 'Unknown',
|
|
107
|
+
}]),
|
|
108
|
+
elementType,
|
|
109
|
+
),
|
|
110
|
+
false,
|
|
111
|
+
'unknown child type -> false',
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
t.equal(
|
|
115
|
+
hasAccessibleChild(
|
|
116
|
+
JSXElementMock('div', [JSXAttributeMock('children', true)], []),
|
|
117
|
+
elementType,
|
|
118
|
+
),
|
|
119
|
+
true,
|
|
120
|
+
'children passed as a prop -> true',
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
t.equal(
|
|
124
|
+
hasAccessibleChild(
|
|
125
|
+
JSXElementMock('div', [], [
|
|
126
|
+
JSXElementMock('input', [JSXAttributeMock('type', 'hidden')]),
|
|
127
|
+
]),
|
|
128
|
+
elementType,
|
|
129
|
+
),
|
|
130
|
+
false,
|
|
131
|
+
'has chidren -> hidden child input JSXElement -> false',
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
t.equal(
|
|
135
|
+
hasAccessibleChild(
|
|
136
|
+
JSXElementMock('div', [], [
|
|
137
|
+
JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]),
|
|
138
|
+
]),
|
|
139
|
+
elementType,
|
|
140
|
+
),
|
|
141
|
+
true,
|
|
142
|
+
'has children + custom JSXElement of type hidden -> true',
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
t.equal(
|
|
146
|
+
hasAccessibleChild(
|
|
147
|
+
JSXElementMock('div', [], [
|
|
148
|
+
JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]),
|
|
149
|
+
]),
|
|
150
|
+
() => 'input',
|
|
151
|
+
),
|
|
152
|
+
false,
|
|
153
|
+
'custom JSXElement mapped to input if type is hidden -> false',
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
t.end();
|
|
157
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
|
|
3
|
+
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock';
|
|
4
|
+
import getImplicitRoleForInput from '../../../../src/util/implicitRoles/input';
|
|
5
|
+
|
|
6
|
+
test('isAbstractRole', (t) => {
|
|
7
|
+
t.test('works for buttons', (st) => {
|
|
8
|
+
st.equal(
|
|
9
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'button')]),
|
|
10
|
+
'button',
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
st.equal(
|
|
14
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'image')]),
|
|
15
|
+
'button',
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
st.equal(
|
|
19
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'reset')]),
|
|
20
|
+
'button',
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
st.equal(
|
|
24
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'submit')]),
|
|
25
|
+
'button',
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
st.end();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
t.equal(
|
|
32
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'checkbox')]),
|
|
33
|
+
'checkbox',
|
|
34
|
+
'works for checkboxes',
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
t.equal(
|
|
38
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'radio')]),
|
|
39
|
+
'radio',
|
|
40
|
+
'works for radios',
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
t.equal(
|
|
44
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'range')]),
|
|
45
|
+
'slider',
|
|
46
|
+
'works for ranges',
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
t.test('works for textboxes', (st) => {
|
|
50
|
+
st.equal(
|
|
51
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'email')]),
|
|
52
|
+
'textbox',
|
|
53
|
+
);
|
|
54
|
+
st.equal(
|
|
55
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'password')]),
|
|
56
|
+
'textbox',
|
|
57
|
+
);
|
|
58
|
+
st.equal(
|
|
59
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'search')]),
|
|
60
|
+
'textbox',
|
|
61
|
+
);
|
|
62
|
+
st.equal(
|
|
63
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'tel')]),
|
|
64
|
+
'textbox',
|
|
65
|
+
);
|
|
66
|
+
st.equal(
|
|
67
|
+
getImplicitRoleForInput([JSXAttributeMock('type', 'url')]),
|
|
68
|
+
'textbox',
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
st.end();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
t.equal(
|
|
75
|
+
getImplicitRoleForInput([JSXAttributeMock('type', '')]),
|
|
76
|
+
'textbox',
|
|
77
|
+
'works for the default case',
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
t.equal(
|
|
81
|
+
getImplicitRoleForInput([JSXAttributeMock('type', true)]),
|
|
82
|
+
'textbox',
|
|
83
|
+
'works for the true case',
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
t.end();
|
|
87
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
|
|
3
|
+
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock';
|
|
4
|
+
import getImplicitRoleForMenu from '../../../../src/util/implicitRoles/menu';
|
|
5
|
+
|
|
6
|
+
test('isAbstractRole', (t) => {
|
|
7
|
+
t.equal(
|
|
8
|
+
getImplicitRoleForMenu([JSXAttributeMock('type', 'toolbar')]),
|
|
9
|
+
'toolbar',
|
|
10
|
+
'works for toolbars',
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
t.equal(
|
|
14
|
+
getImplicitRoleForMenu([JSXAttributeMock('type', '')]),
|
|
15
|
+
'',
|
|
16
|
+
'works for non-toolbars',
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
t.end();
|
|
20
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
|
|
3
|
+
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock';
|
|
4
|
+
import getImplicitRoleForMenuitem from '../../../../src/util/implicitRoles/menuitem';
|
|
5
|
+
|
|
6
|
+
test('isAbstractRole', (t) => {
|
|
7
|
+
t.equal(
|
|
8
|
+
getImplicitRoleForMenuitem([JSXAttributeMock('type', 'command')]),
|
|
9
|
+
'menuitem',
|
|
10
|
+
'works for menu items',
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
t.equal(
|
|
14
|
+
getImplicitRoleForMenuitem([JSXAttributeMock('type', 'checkbox')]),
|
|
15
|
+
'menuitemcheckbox',
|
|
16
|
+
'works for menu item checkboxes',
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
t.equal(
|
|
20
|
+
getImplicitRoleForMenuitem([JSXAttributeMock('type', 'radio')]),
|
|
21
|
+
'menuitemradio',
|
|
22
|
+
'works for menu item radios',
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
t.equal(
|
|
26
|
+
getImplicitRoleForMenuitem([JSXAttributeMock('type', '')]),
|
|
27
|
+
'',
|
|
28
|
+
'works for non-toolbars',
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
t.equal(
|
|
32
|
+
getImplicitRoleForMenuitem([JSXAttributeMock('type', true)]),
|
|
33
|
+
'',
|
|
34
|
+
'works for the true case',
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
t.end();
|
|
38
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import { elementType } from 'jsx-ast-utils';
|
|
3
|
+
|
|
4
|
+
import isAbstractRole from '../../../src/util/isAbstractRole';
|
|
5
|
+
import {
|
|
6
|
+
genElementSymbol,
|
|
7
|
+
genAbstractRoleElements,
|
|
8
|
+
genNonAbstractRoleElements,
|
|
9
|
+
} from '../../../__mocks__/genInteractives';
|
|
10
|
+
|
|
11
|
+
test('isAbstractRole', (t) => {
|
|
12
|
+
t.equal(
|
|
13
|
+
isAbstractRole(undefined, []),
|
|
14
|
+
false,
|
|
15
|
+
'does NOT identify JSX Components (no tagName) as abstract role elements',
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
t.test('elements with an abstract role', (st) => {
|
|
19
|
+
genAbstractRoleElements().forEach(({ openingElement }) => {
|
|
20
|
+
const { attributes } = openingElement;
|
|
21
|
+
st.equal(
|
|
22
|
+
isAbstractRole(
|
|
23
|
+
elementType(openingElement),
|
|
24
|
+
attributes,
|
|
25
|
+
),
|
|
26
|
+
true,
|
|
27
|
+
`identifies \`${genElementSymbol(openingElement)}\` as an abstract role element`,
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
st.end();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
t.test('elements with a non-abstract role', (st) => {
|
|
35
|
+
genNonAbstractRoleElements().forEach(({ openingElement }) => {
|
|
36
|
+
const { attributes } = openingElement;
|
|
37
|
+
st.equal(
|
|
38
|
+
isAbstractRole(
|
|
39
|
+
elementType(openingElement),
|
|
40
|
+
attributes,
|
|
41
|
+
),
|
|
42
|
+
false,
|
|
43
|
+
`does NOT identify \`${genElementSymbol(openingElement)}\` as an abstract role element`,
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
st.end();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
t.end();
|
|
51
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
|
|
3
|
+
import isContentEditable from '../../../src/util/isContentEditable';
|
|
4
|
+
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
|
5
|
+
|
|
6
|
+
test('isContentEditable - HTML5', (t) => {
|
|
7
|
+
t.equal(
|
|
8
|
+
isContentEditable('some tag', [
|
|
9
|
+
JSXAttributeMock('contentEditable', 'true'),
|
|
10
|
+
]),
|
|
11
|
+
true,
|
|
12
|
+
'identifies HTML5 contentEditable elements',
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
t.test('not content editable', (st) => {
|
|
16
|
+
st.equal(
|
|
17
|
+
isContentEditable('some tag', [
|
|
18
|
+
JSXAttributeMock('contentEditable', null),
|
|
19
|
+
]),
|
|
20
|
+
false,
|
|
21
|
+
'does not identify HTML5 content editable elements with null as the value',
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
st.equal(
|
|
25
|
+
isContentEditable('some tag', [
|
|
26
|
+
JSXAttributeMock('contentEditable', undefined),
|
|
27
|
+
]),
|
|
28
|
+
false,
|
|
29
|
+
'does not identify HTML5 content editable elements with undefined as the value',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
st.equal(
|
|
33
|
+
isContentEditable('some tag', [
|
|
34
|
+
JSXAttributeMock('contentEditable', true),
|
|
35
|
+
]),
|
|
36
|
+
false,
|
|
37
|
+
'does not identify HTML5 content editable elements with true as the value',
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
st.equal(
|
|
41
|
+
isContentEditable('some tag', [
|
|
42
|
+
JSXAttributeMock('contentEditable', 'false'),
|
|
43
|
+
]),
|
|
44
|
+
false,
|
|
45
|
+
'does not identify HTML5 content editable elements with "false" as the value',
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
st.end();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
t.end();
|
|
52
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import { dom } from 'aria-query';
|
|
3
|
+
import { elementType } from 'jsx-ast-utils';
|
|
4
|
+
|
|
5
|
+
import isDOMElement from '../../../src/util/isDOMElement';
|
|
6
|
+
import JSXElementMock from '../../../__mocks__/JSXElementMock';
|
|
7
|
+
|
|
8
|
+
test('isDOMElement', (t) => {
|
|
9
|
+
t.test('DOM elements', (st) => {
|
|
10
|
+
dom.forEach((_, el) => {
|
|
11
|
+
const element = JSXElementMock(el);
|
|
12
|
+
|
|
13
|
+
st.equal(
|
|
14
|
+
isDOMElement(elementType(element.openingElement)),
|
|
15
|
+
true,
|
|
16
|
+
`identifies ${el} as a DOM element`,
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
st.end();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
t.equal(
|
|
24
|
+
isDOMElement(JSXElementMock('CustomElement')),
|
|
25
|
+
false,
|
|
26
|
+
'does not identify a custom element',
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
t.end();
|
|
30
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
|
|
3
|
+
import isDisabledElement from '../../../src/util/isDisabledElement';
|
|
4
|
+
import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock';
|
|
5
|
+
|
|
6
|
+
test('isDisabledElement', (t) => {
|
|
7
|
+
t.test('HTML5', (st) => {
|
|
8
|
+
st.equal(
|
|
9
|
+
isDisabledElement([
|
|
10
|
+
JSXAttributeMock('disabled', 'disabled'),
|
|
11
|
+
]),
|
|
12
|
+
true,
|
|
13
|
+
'identifies HTML5 disabled elements',
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
st.equal(
|
|
17
|
+
isDisabledElement([
|
|
18
|
+
JSXAttributeMock('disabled', null),
|
|
19
|
+
]),
|
|
20
|
+
true,
|
|
21
|
+
'identifies HTML5 disabled elements with null as the value',
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
st.equal(
|
|
25
|
+
isDisabledElement([
|
|
26
|
+
JSXAttributeMock('disabled', undefined),
|
|
27
|
+
]),
|
|
28
|
+
false,
|
|
29
|
+
'does not identify HTML5 disabled elements with undefined as the value',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
st.end();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
t.test('ARIA', (st) => {
|
|
36
|
+
st.equal(
|
|
37
|
+
isDisabledElement([
|
|
38
|
+
JSXAttributeMock('aria-disabled', 'true'),
|
|
39
|
+
]),
|
|
40
|
+
true,
|
|
41
|
+
'does not identify ARIA disabled elements',
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
st.equal(
|
|
45
|
+
isDisabledElement([
|
|
46
|
+
JSXAttributeMock('aria-disabled', true),
|
|
47
|
+
]),
|
|
48
|
+
true,
|
|
49
|
+
'does not identify ARIA disabled elements',
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
st.equal(
|
|
53
|
+
isDisabledElement([
|
|
54
|
+
JSXAttributeMock('aria-disabled', 'false'),
|
|
55
|
+
]),
|
|
56
|
+
false,
|
|
57
|
+
'does not identify ARIA disabled elements',
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
st.equal(
|
|
61
|
+
isDisabledElement([
|
|
62
|
+
JSXAttributeMock('aria-disabled', false),
|
|
63
|
+
]),
|
|
64
|
+
false,
|
|
65
|
+
'does not identify ARIA disabled elements',
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
st.equal(
|
|
69
|
+
isDisabledElement([
|
|
70
|
+
JSXAttributeMock('aria-disabled', null),
|
|
71
|
+
]),
|
|
72
|
+
false,
|
|
73
|
+
'does not identify ARIA disabled elements with null as the value',
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
st.equal(
|
|
77
|
+
isDisabledElement([
|
|
78
|
+
JSXAttributeMock('aria-disabled', undefined),
|
|
79
|
+
]),
|
|
80
|
+
false,
|
|
81
|
+
'does not identify ARIA disabled elements with undefined as the value',
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
st.end();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
t.end();
|
|
88
|
+
});
|