@@ -237,134 +237,142 @@ describe('InteractivityChecker', () => {
237237 } ) ;
238238 } ) ;
239239
240- it ( 'should return true for div and span with tabindex == 0' , ( ) => {
241- let elements = createElements ( 'div' , 'span' ) ;
242-
243- elements . forEach ( el => el . setAttribute ( 'tabindex' , '0' ) ) ;
244- appendElements ( elements ) ;
245240
246- elements . forEach ( el => {
247- expect ( checker . isFocusable ( el ) )
248- . toBe ( true , `Expected <${ el . nodeName } tabindex="0"> to be focusable` ) ;
249- } ) ;
250- } ) ;
251241 } ) ;
252242
253243 describe ( 'isTabbable' , ( ) => {
254- it ( 'should return true for native form controls and anchor without tabindex attribute' , ( ) => {
255- let elements = createElements ( 'input' , 'textarea' , 'select' , 'button' , 'a' ) ;
256- appendElements ( elements ) ;
257244
258- elements . forEach ( el => {
259- expect ( checker . isTabbable ( el ) ) . toBe ( true , `Expected <${ el . nodeName } > to be tabbable` ) ;
260- } ) ;
261- } ) ;
262245
263- it ( 'should return false for native form controls and anchor with tabindex == -1' , ( ) => {
264- let elements = createElements ( 'input' , 'textarea' , 'select' , 'button' , 'a' ) ;
265246
266- elements . forEach ( el => el . setAttribute ( 'tabindex' , '-1' ) ) ;
267- appendElements ( elements ) ;
247+ it ( 'should respect the tabindex for video elements with controls' ,
248+ // Do not run for Blink and Firefox, because those treat video elements
249+ // with controls different.
250+ runIf ( ! platform . BLINK && ! platform . FIREFOX , ( ) => {
268251
269- elements . forEach ( el => {
270- expect ( checker . isTabbable ( el ) )
271- . toBe ( false , `Expected <${ el . nodeName } tabindex="-1"> not to be tabbable` ) ;
272- } ) ;
273- } ) ;
252+ let video = createFromTemplate ( '<video controls>' , true ) ;
274253
275- it ( 'should return true for div and span with tabindex == 0' , ( ) => {
276- let elements = createElements ( 'div' , 'span' ) ;
254+ expect ( checker . isTabbable ( video ) ) . toBe ( true ) ;
277255
278- elements . forEach ( el => el . setAttribute ( 'tabindex' , '0' ) ) ;
279- appendElements ( elements ) ;
256+ video . tabIndex = - 1 ;
280257
281- elements . forEach ( el => {
282- expect ( checker . isTabbable ( el ) )
283- . toBe ( true , `Expected <${ el . nodeName } tabindex="0"> to be tabbable` ) ;
284- } ) ;
285- } ) ;
258+ expect ( checker . isTabbable ( video ) ) . toBe ( false ) ;
259+ } )
260+ ) ;
286261
287- it ( 'should respect the inherited tabindex inside of frame elements' , ( ) => {
288- let iframe = createFromTemplate ( '<iframe>' , true ) as HTMLFrameElement ;
289- let button = createFromTemplate ( '<button tabindex="0">Not Tabbable</button>' ) ;
262+ it ( 'should always mark video elements with controls as tabbable (BLINK & FIREFOX)' ,
263+ // Only run this spec for Blink and Firefox, because those always treat video
264+ // elements with controls as tabbable.
265+ runIf ( platform . BLINK || platform . FIREFOX , ( ) => {
290266
291- appendElements ( [ iframe ] ) ;
267+ let video = createFromTemplate ( '<video controls>' , true ) ;
292268
293- iframe . tabIndex = - 1 ;
294- iframe . contentDocument . body . appendChild ( button ) ;
269+ expect ( checker . isTabbable ( video ) ) . toBe ( true ) ;
295270
296- expect ( checker . isTabbable ( iframe ) ) . toBe ( false ) ;
297- expect ( checker . isTabbable ( button ) ) . toBe ( false ) ;
271+ video . tabIndex = - 1 ;
298272
299- iframe . tabIndex = null ;
273+ expect ( checker . isTabbable ( video ) ) . toBe ( true ) ;
274+ } )
275+ ) ;
300276
301- expect ( checker . isTabbable ( iframe ) ) . toBe ( false ) ;
302- expect ( checker . isTabbable ( button ) ) . toBe ( true ) ;
303- } ) ;
277+ // Some tests should not run inside of iOS browsers, because those only allow specific
278+ // elements to be tabbable and cause the tests to always fail.
279+ describe ( 'for non-iOS browsers' , runIf ( ! platform . IOS , ( ) => {
304280
281+ it ( 'should mark form controls and anchors without tabindex attribute as tabbable' , ( ) => {
282+ let elements = createElements ( 'input' , 'textarea' , 'select' , 'button' , 'a' ) ;
283+ appendElements ( elements ) ;
305284
306- it ( 'should mark elements which are contentEditable as tabbable' , async ( ( ) => {
307- let editableEl = createFromTemplate ( '<div contenteditable="true">' , true ) ;
285+ elements . forEach ( el => {
286+ expect ( checker . isTabbable ( el ) ) . toBe ( true , `Expected <${ el . nodeName } > to be tabbable` ) ;
287+ } ) ;
288+ } ) ;
308289
309- // Wait one tick, because the browser takes some time to update the tabIndex
310- // according to the contentEditable attribute.
311- setTimeout ( ( ) => {
290+ it ( 'should return true for div and span with tabindex == 0' , ( ) => {
291+ let elements = createElements ( 'div' , 'span' ) ;
312292
313- expect ( checker . isTabbable ( editableEl ) ) . toBe ( true ) ;
293+ elements . forEach ( el => el . setAttribute ( 'tabindex' , '0' ) ) ;
294+ appendElements ( elements ) ;
314295
315- editableEl . tabIndex = - 1 ;
296+ elements . forEach ( el => {
297+ expect ( checker . isFocusable ( el ) )
298+ . toBe ( true , `Expected <${ el . nodeName } tabindex="0"> to be focusable` ) ;
299+ } ) ;
300+ } ) ;
316301
317- expect ( checker . isTabbable ( editableEl ) ) . toBe ( false ) ;
302+ it ( 'should return false for native form controls and anchor with tabindex == -1' , ( ) => {
303+ let elements = createElements ( 'input' , 'textarea' , 'select' , 'button' , 'a' ) ;
318304
319- } , 1 ) ;
305+ elements . forEach ( el => el . setAttribute ( 'tabindex' , '-1' ) ) ;
306+ appendElements ( elements ) ;
320307
321- } ) ) ;
308+ elements . forEach ( el => {
309+ expect ( checker . isTabbable ( el ) )
310+ . toBe ( false , `Expected <${ el . nodeName } tabindex="-1"> not to be tabbable` ) ;
311+ } ) ;
312+ } ) ;
322313
323- it ( 'should never mark iframe elements as tabbable ' , ( ) => {
324- let iframe = createFromTemplate ( '<iframe> ', true ) ;
314+ it ( 'should return true for div and span with tabindex == 0 ' , ( ) => {
315+ let elements = createElements ( 'div ', 'span' ) ;
325316
326- // iFrame elements will be never marked as tabbable, because it depends on the content
327- // which is mostly not detectable due to CORS and also the checks will be not reliable.
328- expect ( checker . isTabbable ( iframe ) ) . toBe ( false ) ;
329- } ) ;
317+ elements . forEach ( el => el . setAttribute ( 'tabindex' , '0' ) ) ;
318+ appendElements ( elements ) ;
330319
320+ elements . forEach ( el => {
321+ expect ( checker . isTabbable ( el ) )
322+ . toBe ( true , `Expected <${ el . nodeName } tabindex="0"> to be tabbable` ) ;
323+ } ) ;
324+ } ) ;
331325
326+ it ( 'should respect the inherited tabindex inside of frame elements' , ( ) => {
327+ let iframe = createFromTemplate ( '<iframe>' , true ) as HTMLFrameElement ;
328+ let button = createFromTemplate ( '<button tabindex="0">Not Tabbable</button>' ) ;
332329
333- it ( 'should always mark audio elements without controls as not tabbable' , ( ) => {
334- let audio = createFromTemplate ( '<audio>' , true ) ;
330+ appendElements ( [ iframe ] ) ;
335331
336- expect ( checker . isTabbable ( audio ) ) . toBe ( false ) ;
337- } ) ;
332+ iframe . tabIndex = - 1 ;
333+ iframe . contentDocument . body . appendChild ( button ) ;
338334
339- it ( 'should respect the tabindex for video elements with controls' ,
340- // Do not run for Blink and Firefox, because those treat video elements
341- // with controls different.
342- runIf ( ! platform . BLINK && ! platform . FIREFOX , ( ) => {
335+ expect ( checker . isTabbable ( iframe ) ) . toBe ( false ) ;
336+ expect ( checker . isTabbable ( button ) ) . toBe ( false ) ;
343337
344- let video = createFromTemplate ( '<video controls>' , true ) ;
338+ iframe . tabIndex = null ;
345339
346- expect ( checker . isTabbable ( video ) ) . toBe ( true ) ;
340+ expect ( checker . isTabbable ( iframe ) ) . toBe ( false ) ;
341+ expect ( checker . isTabbable ( button ) ) . toBe ( true ) ;
342+ } ) ;
347343
348- video . tabIndex = - 1 ;
344+ it ( 'should mark elements which are contentEditable as tabbable' , async ( ( ) => {
345+ let editableEl = createFromTemplate ( '<div contenteditable="true">' , true ) ;
349346
350- expect ( checker . isTabbable ( video ) ) . toBe ( false ) ;
351- } )
352- ) ;
347+ // Wait one tick, because the browser takes some time to update the tabIndex
348+ // according to the contentEditable attribute.
349+ setTimeout ( ( ) => {
353350
354- it ( 'should always mark video elements with controls as tabbable (BLINK & FIREFOX)' ,
355- // Only run this spec for Blink and Firefox, because those always treat video
356- // elements with controls as tabbable.
357- runIf ( platform . BLINK || platform . FIREFOX , ( ) => {
351+ expect ( checker . isTabbable ( editableEl ) ) . toBe ( true ) ;
358352
359- let video = createFromTemplate ( '<video controls>' , true ) ;
353+ editableEl . tabIndex = - 1 ;
360354
361- expect ( checker . isTabbable ( video ) ) . toBe ( true ) ;
355+ expect ( checker . isTabbable ( editableEl ) ) . toBe ( false ) ;
362356
363- video . tabIndex = - 1 ;
357+ } , 1 ) ;
364358
365- expect ( checker . isTabbable ( video ) ) . toBe ( true ) ;
366- } )
367- ) ;
359+ } ) ) ;
360+
361+ it ( 'should never mark iframe elements as tabbable' , ( ) => {
362+ let iframe = createFromTemplate ( '<iframe>' , true ) ;
363+
364+ // iFrame elements will be never marked as tabbable, because it depends on the content
365+ // which is mostly not detectable due to CORS and also the checks will be not reliable.
366+ expect ( checker . isTabbable ( iframe ) ) . toBe ( false ) ;
367+ } ) ;
368+
369+ it ( 'should always mark audio elements without controls as not tabbable' , ( ) => {
370+ let audio = createFromTemplate ( '<audio>' , true ) ;
371+
372+ expect ( checker . isTabbable ( audio ) ) . toBe ( false ) ;
373+ } ) ;
374+
375+ } ) ) ;
368376
369377 describe ( 'for Blink and Webkit browsers' , runIf ( platform . BLINK || platform . WEBKIT , ( ) => {
370378
0 commit comments