@@ -44,13 +44,73 @@ expect.extend({
44
44
// @ts -ignore `axe` is a global variable defined by page.evaluate() above
45
45
const axe = window . axe
46
46
47
+ const interactiveElements = [ 'a[href]' , 'button' , 'summary' , 'select' , 'input:not([type=hidden])' , 'textarea' ]
48
+ const focusableElements = interactiveElements . concat ( [ '[tabindex]' ] )
49
+
47
50
axe . configure ( {
48
51
rules : [
52
+ {
53
+ id : 'menuitem-should-be-interactive' ,
54
+ excludeHidden : true ,
55
+ selector :
56
+ 'div[role="menuitem"], span[role="menuitem"], div[role="menuitemradio"], span[role="menuitemradio"], div[role="menuitemcheckbox"], span[role="menuitemcheckbox"]' ,
57
+ all : [ 'menuitem-should-be-interactive_0' ] ,
58
+ any : [ ] ,
59
+ metadata : {
60
+ help : 'Menu items must be focusable. Use <button>, <a>, or <label tabindex="0">' ,
61
+ helpUrl : '' ,
62
+ } ,
63
+ tags : [ 'custom-github-rule' ] ,
64
+ } ,
65
+ {
66
+ id : 'empty-summary' ,
67
+ excludeHidden : true ,
68
+ selector : 'summary' ,
69
+ all : [ ] ,
70
+ any : [
71
+ 'has-visible-text' ,
72
+ 'aria-label' ,
73
+ 'aria-labelledby' ,
74
+ 'role-presentation' ,
75
+ 'role-none' ,
76
+ 'non-empty-title' ,
77
+ ] ,
78
+ metadata : {
79
+ help : 'Details summary element must have visible text' ,
80
+ helpUrl : '' ,
81
+ } ,
82
+ tags : [ 'custom-github-rule' ] ,
83
+ } ,
84
+ {
85
+ id : 'submit-reset-button-must-be-in-form' ,
86
+ excludeHidden : true ,
87
+ selector : 'button[type="submit"], button[type="reset"], input[type="submit"], input[type="reset"]' ,
88
+ all : [ 'submit-reset-button-must-be-in-form_0' ] ,
89
+ any : [ ] ,
90
+ metadata : {
91
+ help : 'Submit and reset buttons must be in a form' ,
92
+ helpUrl : '' ,
93
+ } ,
94
+ tags : [ 'custom-github-rule' ] ,
95
+ } ,
96
+ {
97
+ id : 'nested-forms' ,
98
+ excludeHidden : true ,
99
+ selector : 'form' ,
100
+ all : [ 'nested-forms_0' ] ,
101
+ any : [ ] ,
102
+ metadata : {
103
+ help : 'Nested form is invalid HTML and should be avoided' ,
104
+ helpUrl :
105
+ 'https://html.spec.whatwg.org/multipage/forms.html#the-form-element:concept-element-content-model' ,
106
+ } ,
107
+ tags : [ 'custom-github-rule' ] ,
108
+ } ,
49
109
{
50
110
id : 'avoid-both-disabled-and-aria-disabled' ,
51
111
excludeHidden : true ,
52
112
selector : 'button, fieldset, input, optgroup, option, select, textarea' ,
53
- all : [ 'check- avoid-both-disabled-and-aria-disabled ' ] ,
113
+ all : [ 'avoid-both-disabled-and-aria-disabled_0 ' ] ,
54
114
any : [ ] ,
55
115
metadata : {
56
116
help : '[aria-disabled] may be used in place of native HTML [disabled] to allow tab-focus on an otherwise ignored element. Setting both attributes is contradictory.' ,
@@ -61,7 +121,31 @@ expect.extend({
61
121
] ,
62
122
checks : [
63
123
{
64
- id : 'check-avoid-both-disabled-and-aria-disabled' ,
124
+ id : 'menuitem-should-be-interactive_0' ,
125
+ evaluate : ( el : Element ) => focusableElements . filter ( s => el . matches ( s ) ) . length > 0 ,
126
+ metadata : {
127
+ impact : 'critical' ,
128
+ } ,
129
+ } ,
130
+ {
131
+ id : 'submit-reset-button-must-be-in-form_0' ,
132
+ evaluate : ( el : Element ) => {
133
+ const formId = el . getAttribute ( 'form' )
134
+ return ! ! el . closest ( 'form' ) || ! ! ( formId && document . getElementById ( formId ) )
135
+ } ,
136
+ metadata : {
137
+ impact : 'critical' ,
138
+ } ,
139
+ } ,
140
+ {
141
+ id : 'nested-forms_0' ,
142
+ evaluate : ( el : Element ) => ! ( el . parentElement && el . parentElement . closest ( 'form' ) ) ,
143
+ metadata : {
144
+ impact : 'critical' ,
145
+ } ,
146
+ } ,
147
+ {
148
+ id : 'avoid-both-disabled-and-aria-disabled_0' ,
65
149
/**
66
150
* Check an element with native `disabled` support doesn't have both `disabled` and `aria-disabled` set.
67
151
*/
0 commit comments