@@ -464,4 +464,202 @@ describe('Card', () => {
464
464
} ) ;
465
465
} ) ;
466
466
} ) ;
467
+
468
+ describe ( 'disabled' , ( ) => {
469
+ it ( 'should have aria-disabled attribute when disabled' , ( ) => {
470
+ mountFluent ( < CardSample disabled /> ) ;
471
+
472
+ cy . get ( '#card' ) . should ( 'have.attr' , 'aria-disabled' , 'true' ) ;
473
+ } ) ;
474
+
475
+ it ( 'should not be focusable when disabled' , ( ) => {
476
+ mountFluent ( < CardSample disabled focusMode = "no-tab" /> ) ;
477
+
478
+ cy . get ( '#before' ) . focus ( ) ;
479
+ cy . realPress ( 'Tab' ) ;
480
+
481
+ cy . get ( '#card' ) . should ( 'not.be.focused' ) ;
482
+ cy . get ( '#open-button' ) . should ( 'be.focused' ) ;
483
+ } ) ;
484
+
485
+ it ( 'should not respond to click events when disabled' , ( ) => {
486
+ const onClickSpy = cy . spy ( ) . as ( 'onClickSpy' ) ;
487
+
488
+ mountFluent ( < CardSample disabled onClick = { onClickSpy } /> ) ;
489
+
490
+ cy . get ( '#card' ) . realClick ( ) ;
491
+
492
+ cy . get ( '@onClickSpy' ) . should ( 'not.have.been.called' ) ;
493
+ } ) ;
494
+
495
+ it ( 'should not respond to keyboard events when disabled' , ( ) => {
496
+ const onClickSpy = cy . spy ( ) . as ( 'onClickSpy' ) ;
497
+
498
+ mountFluent ( < CardSample disabled onClick = { onClickSpy } focusMode = "no-tab" /> ) ;
499
+
500
+ // Since the card is disabled and not focusable, we can't send keyboard events to it
501
+ // This test verifies that the card doesn't receive focus and therefore can't respond to keyboard events
502
+ cy . get ( '#card' ) . should ( 'have.attr' , 'aria-disabled' , 'true' ) ;
503
+
504
+ // Try to focus the card - it should not be focusable
505
+ cy . get ( '#before' ) . focus ( ) ;
506
+ cy . realPress ( 'Tab' ) ;
507
+ cy . get ( '#card' ) . should ( 'not.be.focused' ) ;
508
+
509
+ cy . get ( '@onClickSpy' ) . should ( 'not.have.been.called' ) ;
510
+ } ) ;
511
+
512
+ describe ( 'selectable disabled' , ( ) => {
513
+ it ( 'should not be selectable when disabled' , ( ) => {
514
+ mountFluent ( < CardSample disabled selected /> ) ;
515
+
516
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'be.disabled' ) ;
517
+ } ) ;
518
+
519
+ it ( 'should not change selection state when clicked and disabled' , ( ) => {
520
+ mountFluent ( < CardSample disabled defaultSelected = { false } /> ) ;
521
+
522
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'not.be.checked' ) ;
523
+ cy . get ( '#card' ) . realClick ( ) ;
524
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'not.be.checked' ) ;
525
+ } ) ;
526
+
527
+ it ( 'should not change selection state with keyboard when disabled' , ( ) => {
528
+ mountFluent ( < CardSample disabled defaultSelected = { false } /> ) ;
529
+
530
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'not.be.checked' ) ;
531
+ // Disabled checkbox should not respond to keyboard events
532
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'be.disabled' ) ;
533
+ // The checkbox is disabled, so trying to type on it should not work
534
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'not.be.checked' ) ;
535
+ } ) ;
536
+
537
+ it ( 'should maintain selected state when disabled' , ( ) => {
538
+ mountFluent ( < CardSample disabled defaultSelected /> ) ;
539
+
540
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'be.checked' ) ;
541
+ cy . get ( '#card' ) . realClick ( ) ;
542
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'be.checked' ) ;
543
+ } ) ;
544
+
545
+ it ( 'should have disabled checkbox when card is disabled and selectable' , ( ) => {
546
+ mountFluent ( < CardSample disabled selected /> ) ;
547
+
548
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'be.disabled' ) ;
549
+ // HTML inputs use the 'disabled' attribute, not 'aria-disabled'
550
+ cy . get ( `.${ cardClassNames . checkbox } ` ) . should ( 'have.attr' , 'disabled' ) ;
551
+ } ) ;
552
+
553
+ it ( 'should not trigger onSelectionChange when disabled' , ( ) => {
554
+ const onSelectionChangeSpy = cy . spy ( ) . as ( 'onSelectionChangeSpy' ) ;
555
+
556
+ const DisabledSelectableCard = ( ) => (
557
+ < CardSample disabled defaultSelected = { false } onSelectionChange = { onSelectionChangeSpy } />
558
+ ) ;
559
+
560
+ mountFluent ( < DisabledSelectableCard /> ) ;
561
+
562
+ cy . get ( '#card' ) . realClick ( ) ;
563
+ cy . get ( '@onSelectionChangeSpy' ) . should ( 'not.have.been.called' ) ;
564
+ } ) ;
565
+ } ) ;
566
+
567
+ describe ( 'focus modes when disabled' , ( ) => {
568
+ it ( 'should not be focusable with focusMode="no-tab" when disabled' , ( ) => {
569
+ mountFluent ( < CardSample disabled focusMode = "no-tab" /> ) ;
570
+
571
+ cy . get ( '#before' ) . focus ( ) ;
572
+ cy . realPress ( 'Tab' ) ;
573
+
574
+ cy . get ( '#card' ) . should ( 'not.be.focused' ) ;
575
+ cy . get ( '#open-button' ) . should ( 'be.focused' ) ;
576
+ } ) ;
577
+
578
+ it ( 'should not be focusable with focusMode="tab-exit" when disabled' , ( ) => {
579
+ mountFluent ( < CardSample disabled focusMode = "tab-exit" /> ) ;
580
+
581
+ cy . get ( '#before' ) . focus ( ) ;
582
+ cy . realPress ( 'Tab' ) ;
583
+
584
+ cy . get ( '#card' ) . should ( 'not.be.focused' ) ;
585
+ cy . get ( '#open-button' ) . should ( 'be.focused' ) ;
586
+ } ) ;
587
+
588
+ it ( 'should not be focusable with focusMode="tab-only" when disabled' , ( ) => {
589
+ mountFluent ( < CardSample disabled focusMode = "tab-only" /> ) ;
590
+
591
+ cy . get ( '#before' ) . focus ( ) ;
592
+ cy . realPress ( 'Tab' ) ;
593
+
594
+ cy . get ( '#card' ) . should ( 'not.be.focused' ) ;
595
+ cy . get ( '#open-button' ) . should ( 'be.focused' ) ;
596
+ } ) ;
597
+
598
+ it ( 'should not receive programmatic focus when disabled' , ( ) => {
599
+ mountFluent ( < CardSample disabled focusMode = "no-tab" /> ) ;
600
+
601
+ // Disabled cards should not be focusable, so we verify the focus doesn't change
602
+ cy . get ( '#before' ) . focus ( ) ;
603
+ cy . get ( '#before' ) . should ( 'be.focused' ) ;
604
+
605
+ // This should not change the focus since the card is disabled
606
+ cy . get ( '#card' ) . should ( 'have.attr' , 'aria-disabled' , 'true' ) ;
607
+ cy . get ( '#before' ) . should ( 'be.focused' ) ; // Focus should remain on #before
608
+ } ) ;
609
+ } ) ;
610
+
611
+ describe ( 'interactive behaviors when disabled' , ( ) => {
612
+ it ( 'should not be interactive when disabled even with click handlers' , ( ) => {
613
+ const onClickSpy = cy . spy ( ) . as ( 'onClickSpy' ) ;
614
+
615
+ mountFluent ( < CardSample disabled onClick = { onClickSpy } /> ) ;
616
+
617
+ cy . get ( '#card' ) . realClick ( ) ;
618
+
619
+ // The onClick handler should not be called when disabled
620
+ cy . get ( '@onClickSpy' ) . should ( 'not.have.been.called' ) ;
621
+ } ) ;
622
+
623
+ it ( 'should not respond to mouse events when disabled' , ( ) => {
624
+ // When a card is disabled, the onClick handler is removed
625
+ // but other mouse events may still bubble up from child elements
626
+ // This test verifies that the main onClick interaction is disabled
627
+ mountFluent ( < CardSample disabled /> ) ;
628
+
629
+ cy . get ( '#card' ) . should ( 'have.attr' , 'aria-disabled' , 'true' ) ;
630
+
631
+ // The card should be visually disabled
632
+ cy . get ( '#card' ) . realClick ( ) ;
633
+
634
+ // Since we didn't provide an onClick handler, we just verify the disabled state
635
+ cy . get ( '#card' ) . should ( 'have.attr' , 'aria-disabled' , 'true' ) ;
636
+ } ) ;
637
+ } ) ;
638
+
639
+ describe ( 'child element interaction when card is disabled' , ( ) => {
640
+ it ( 'should allow child elements to be interacted with when card is disabled' , ( ) => {
641
+ mountFluent ( < CardSample disabled /> ) ;
642
+
643
+ // Child buttons should still be clickable unless explicitly disabled
644
+ cy . get ( '#open-button' ) . should ( 'not.be.disabled' ) ;
645
+ cy . get ( '#close-button' ) . should ( 'not.be.disabled' ) ;
646
+
647
+ cy . get ( '#open-button' ) . realClick ( ) ;
648
+ cy . get ( '#close-button' ) . realClick ( ) ;
649
+ } ) ;
650
+
651
+ it ( 'should focus child elements normally when card is disabled' , ( ) => {
652
+ mountFluent ( < CardSample disabled /> ) ;
653
+
654
+ cy . get ( '#before' ) . focus ( ) ;
655
+ cy . realPress ( 'Tab' ) ;
656
+
657
+ cy . get ( '#open-button' ) . should ( 'be.focused' ) ;
658
+
659
+ cy . realPress ( 'Tab' ) ;
660
+
661
+ cy . get ( '#close-button' ) . should ( 'be.focused' ) ;
662
+ } ) ;
663
+ } ) ;
664
+ } ) ;
467
665
} ) ;
0 commit comments