@@ -122,6 +122,159 @@ test( "accessibility", function() {
122
122
// TODO: aria-live and aria-busy tests for ajax tabs
123
123
} ) ;
124
124
125
+ asyncTest ( "keyboard support - LEFT, RIGHT, UP, DOWN, HOME, END, SPACE, ENTER" , function ( ) {
126
+ expect ( 90 ) ;
127
+ var element = $ ( "#tabs1" ) . tabs ( {
128
+ active : 0 ,
129
+ collapsible : true
130
+ } ) ,
131
+ tabs = element . find ( ".ui-tabs-nav li" ) ,
132
+ anchors = tabs . find ( ".ui-tabs-anchor" ) ,
133
+ panels = element . find ( ".ui-tabs-panel" ) ,
134
+ keyCode = $ . ui . keyCode ;
135
+
136
+ element . data ( "tabs" ) . delay = 50 ;
137
+
138
+ equal ( tabs . filter ( ".ui-state-focus" ) . length , 0 , "no tabs focused on init" ) ;
139
+ tabs . eq ( 0 ) . simulate ( "focus" ) ;
140
+
141
+ // down, right, down (wrap), up (wrap)
142
+ function step1 ( ) {
143
+ ok ( tabs . eq ( 0 ) . is ( ".ui-state-focus" ) , "first tab has focus" ) ;
144
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "true" , "first tab has aria-selected=true" ) ;
145
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is visible" ) ;
146
+
147
+ tabs . eq ( 0 ) . simulate ( "keydown" , { keyCode : keyCode . DOWN } ) ;
148
+ ok ( tabs . eq ( 1 ) . is ( ".ui-state-focus" ) , "DOWN moves focus to next tab" ) ;
149
+ ok ( ! tabs . eq ( 0 ) . is ( ".ui-state-focus" ) , "first tab is no longer focused" ) ;
150
+ equal ( tabs . eq ( 1 ) . attr ( "aria-selected" ) , "true" , "second tab has aria-selected=true" ) ;
151
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "false" , "first tab has aria-selected=false" ) ;
152
+ ok ( panels . eq ( 1 ) . is ( ":hidden" ) , "second panel is still hidden" ) ;
153
+ equal ( panels . eq ( 1 ) . attr ( "aria-expanded" ) , "false" , "second panel has aria-expanded=false" ) ;
154
+ equal ( panels . eq ( 1 ) . attr ( "aria-hidden" ) , "true" , "second panel has aria-hidden=true" ) ;
155
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is still visible" ) ;
156
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "true" , "first panel has aria-expanded=true" ) ;
157
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "false" , "first panel has aria-hidden=false" ) ;
158
+
159
+ tabs . eq ( 1 ) . simulate ( "keydown" , { keyCode : keyCode . RIGHT } ) ;
160
+ ok ( tabs . eq ( 2 ) . is ( ".ui-state-focus" ) , "RIGHT moves focus to next tab" ) ;
161
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "true" , "third tab has aria-selected=true" ) ;
162
+ equal ( tabs . eq ( 1 ) . attr ( "aria-selected" ) , "false" , "second tab has aria-selected=false" ) ;
163
+ ok ( panels . eq ( 2 ) . is ( ":hidden" ) , "third panel is still hidden" ) ;
164
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "false" , "third panel has aria-expanded=false" ) ;
165
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "true" , "third panel has aria-hidden=true" ) ;
166
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is still visible" ) ;
167
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "true" , "first panel has aria-expanded=true" ) ;
168
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "false" , "first panel has aria-hidden=false" ) ;
169
+
170
+ tabs . eq ( 2 ) . simulate ( "keydown" , { keyCode : keyCode . DOWN } ) ;
171
+ ok ( tabs . eq ( 0 ) . is ( ".ui-state-focus" ) , "DOWN wraps focus to first tab" ) ;
172
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "true" , "first tab has aria-selected=true" ) ;
173
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "false" , "third tab has aria-selected=false" ) ;
174
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is still visible" ) ;
175
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "true" , "first panel has aria-expanded=true" ) ;
176
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "false" , "first panel has aria-hidden=false" ) ;
177
+
178
+ tabs . eq ( 0 ) . simulate ( "keydown" , { keyCode : keyCode . UP } ) ;
179
+ ok ( tabs . eq ( 2 ) . is ( ".ui-state-focus" ) , "UP wraps focus to last tab" ) ;
180
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "true" , "third tab has aria-selected=true" ) ;
181
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "false" , "first tab has aria-selected=false" ) ;
182
+ ok ( panels . eq ( 2 ) . is ( ":hidden" ) , "third panel is still hidden" ) ;
183
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "false" , "third panel has aria-expanded=false" ) ;
184
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "true" , "third panel has aria-hidden=true" ) ;
185
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is still visible" ) ;
186
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "true" , "first panel has aria-expanded=true" ) ;
187
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "false" , "first panel has aria-hidden=false" ) ;
188
+
189
+ setTimeout ( step2 , 100 ) ;
190
+ }
191
+
192
+ // left, home, space
193
+ function step2 ( ) {
194
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "true" , "third tab has aria-selected=true" ) ;
195
+ ok ( panels . eq ( 2 ) . is ( ":visible" ) , "third panel is visible" ) ;
196
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "true" , "third panel has aria-expanded=true" ) ;
197
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "false" , "third panel has aria-hidden=false" ) ;
198
+ ok ( panels . eq ( 0 ) . is ( ":hidden" ) , "first panel is hidden" ) ;
199
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "false" , "first panel has aria-expanded=false" ) ;
200
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "true" , "first panel has aria-hidden=true" ) ;
201
+
202
+ tabs . eq ( 2 ) . simulate ( "keydown" , { keyCode : keyCode . LEFT } ) ;
203
+ ok ( tabs . eq ( 1 ) . is ( ".ui-state-focus" ) , "LEFT moves focus to previous tab" ) ;
204
+ equal ( tabs . eq ( 1 ) . attr ( "aria-selected" ) , "true" , "second tab has aria-selected=true" ) ;
205
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "false" , "third tab has aria-selected=false" ) ;
206
+ ok ( panels . eq ( 1 ) . is ( ":hidden" ) , "second panel is still hidden" ) ;
207
+ equal ( panels . eq ( 1 ) . attr ( "aria-expanded" ) , "false" , "second panel has aria-expanded=false" ) ;
208
+ equal ( panels . eq ( 1 ) . attr ( "aria-hidden" ) , "true" , "second panel has aria-hidden=true" ) ;
209
+ ok ( panels . eq ( 2 ) . is ( ":visible" ) , "third panel is still visible" ) ;
210
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "true" , "third panel has aria-expanded=true" ) ;
211
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "false" , "third panel has aria-hidden=false" ) ;
212
+
213
+ tabs . eq ( 1 ) . simulate ( "keydown" , { keyCode : keyCode . HOME } ) ;
214
+ ok ( tabs . eq ( 0 ) . is ( ".ui-state-focus" ) , "HOME moves focus to first tab" ) ;
215
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "true" , "first tab has aria-selected=true" ) ;
216
+ equal ( tabs . eq ( 1 ) . attr ( "aria-selected" ) , "false" , "second tab has aria-selected=false" ) ;
217
+ ok ( panels . eq ( 0 ) . is ( ":hidden" ) , "first panel is still hidden" ) ;
218
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "false" , "first panel has aria-expanded=false" ) ;
219
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "true" , "first panel has aria-hidden=true" ) ;
220
+ ok ( panels . eq ( 2 ) . is ( ":visible" ) , "third panel is still visible" ) ;
221
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "true" , "third panel has aria-expanded=true" ) ;
222
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "false" , "third panel has aria-hidden=false" ) ;
223
+
224
+ // SPACE activates, cancels delay
225
+ tabs . eq ( 0 ) . simulate ( "keydown" , { keyCode : keyCode . SPACE } ) ;
226
+ setTimeout ( step3 , 1 ) ;
227
+ }
228
+
229
+ // end, enter
230
+ function step3 ( ) {
231
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "true" , "first tab has aria-selected=true" ) ;
232
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is visible" ) ;
233
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "true" , "first panel has aria-expanded=true" ) ;
234
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "false" , "first panel has aria-hidden=false" ) ;
235
+ ok ( panels . eq ( 2 ) . is ( ":hidden" ) , "third panel is hidden" ) ;
236
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "false" , "third panel has aria-expanded=false" ) ;
237
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "true" , "third panel has aria-hidden=true" ) ;
238
+
239
+ tabs . eq ( 0 ) . simulate ( "keydown" , { keyCode : keyCode . END } ) ;
240
+ ok ( tabs . eq ( 2 ) . is ( ".ui-state-focus" ) , "END moves focus to last tab" ) ;
241
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "true" , "third tab has aria-selected=true" ) ;
242
+ equal ( tabs . eq ( 0 ) . attr ( "aria-selected" ) , "false" , "first tab has aria-selected=false" ) ;
243
+ ok ( panels . eq ( 2 ) . is ( ":hidden" ) , "third panel is still hidden" ) ;
244
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "false" , "third panel has aria-expanded=false" ) ;
245
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "true" , "third panel has aria-hidden=true" ) ;
246
+ ok ( panels . eq ( 0 ) . is ( ":visible" ) , "first panel is still visible" ) ;
247
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "true" , "first panel has aria-expanded=true" ) ;
248
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "false" , "first panel has aria-hidden=false" ) ;
249
+
250
+ // ENTER activates, cancels delay
251
+ tabs . eq ( 0 ) . simulate ( "keydown" , { keyCode : keyCode . ENTER } ) ;
252
+ setTimeout ( step4 , 1 ) ;
253
+ }
254
+
255
+ // enter (collapse)
256
+ function step4 ( ) {
257
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "true" , "third tab has aria-selected=true" ) ;
258
+ ok ( panels . eq ( 2 ) . is ( ":visible" ) , "third panel is visible" ) ;
259
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "true" , "third panel has aria-expanded=true" ) ;
260
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "false" , "third panel has aria-hidden=false" ) ;
261
+ ok ( panels . eq ( 0 ) . is ( ":hidden" ) , "first panel is hidden" ) ;
262
+ equal ( panels . eq ( 0 ) . attr ( "aria-expanded" ) , "false" , "first panel has aria-expanded=false" ) ;
263
+ equal ( panels . eq ( 0 ) . attr ( "aria-hidden" ) , "true" , "first panel has aria-hidden=true" ) ;
264
+
265
+ // ENTER collapses if active
266
+ tabs . eq ( 2 ) . simulate ( "keydown" , { keyCode : keyCode . ENTER } ) ;
267
+ equal ( tabs . eq ( 2 ) . attr ( "aria-selected" ) , "false" , "third tab has aria-selected=false" ) ;
268
+ ok ( panels . eq ( 2 ) . is ( ":hidden" ) , "third panel is hidden" ) ;
269
+ equal ( panels . eq ( 2 ) . attr ( "aria-expanded" ) , "false" , "third panel has aria-expanded=false" ) ;
270
+ equal ( panels . eq ( 2 ) . attr ( "aria-hidden" ) , "true" , "third panel has aria-hidden=true" ) ;
271
+
272
+ start ( ) ;
273
+ }
274
+
275
+ setTimeout ( step1 , 1 ) ;
276
+ } ) ;
277
+
125
278
test ( "#3627 - Ajax tab with url containing a fragment identifier fails to load" , function ( ) {
126
279
expect ( 1 ) ;
127
280
0 commit comments