@@ -623,6 +623,196 @@ test.describe('Keyboard Behavior', () => {
623
623
} ) ;
624
624
} ) ;
625
625
626
+ test . describe ( 'looping' , ( ) => {
627
+ test . describe ( 'loop disabled' , ( ) => {
628
+ test ( `GIVEN an open basic select
629
+ AND the last option is data-highlighted
630
+ WHEN the down key is pressed
631
+ THEN data-highlighted should stay on the last option` , async ( { page } ) => {
632
+ const { getTrigger, getOptions, openListbox } = await setup (
633
+ page ,
634
+ 'select-hero-test' ,
635
+ ) ;
636
+
637
+ // initially last option is highlighted
638
+ await openListbox ( 'Enter' ) ;
639
+ await getTrigger ( ) . focus ( ) ;
640
+ await getTrigger ( ) . press ( 'End' ) ;
641
+ const options = await getOptions ( ) ;
642
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
643
+
644
+ await getTrigger ( ) . focus ( ) ;
645
+ await getTrigger ( ) . press ( 'ArrowDown' ) ;
646
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
647
+ } ) ;
648
+
649
+ test ( `GIVEN an open basic select
650
+ AND the first option is data-highlighted
651
+ WHEN the up arrow key is pressed
652
+ THEN data-highlighted should stay on the first option` , async ( { page } ) => {
653
+ const { getTrigger, getOptions, openListbox } = await setup (
654
+ page ,
655
+ 'select-hero-test' ,
656
+ ) ;
657
+
658
+ await openListbox ( 'Enter' ) ;
659
+ const options = await getOptions ( ) ;
660
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
661
+ await getTrigger ( ) . focus ( ) ;
662
+ await getTrigger ( ) . press ( 'ArrowUp' ) ;
663
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
664
+ } ) ;
665
+
666
+ test ( `GIVEN a closed basic select
667
+ AND the last option is selected
668
+ WHEN the right arrow key is pressed
669
+ THEN it should stay on the last option` , async ( { page } ) => {
670
+ const { getTrigger, getOptions, getListbox, openListbox } = await setup (
671
+ page ,
672
+ 'select-hero-test' ,
673
+ ) ;
674
+
675
+ // initially last option is highlighted & listbox closed
676
+ await openListbox ( 'Enter' ) ;
677
+ await getTrigger ( ) . focus ( ) ;
678
+ await getTrigger ( ) . press ( 'End' ) ;
679
+ const options = await getOptions ( ) ;
680
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
681
+ await getTrigger ( ) . press ( 'Enter' ) ;
682
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute (
683
+ 'aria-selected' ,
684
+ 'true' ,
685
+ ) ;
686
+ await expect ( getListbox ( ) ) . toBeHidden ( ) ;
687
+
688
+ await getTrigger ( ) . focus ( ) ;
689
+ await getTrigger ( ) . press ( 'ArrowRight' ) ;
690
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
691
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute (
692
+ 'aria-selected' ,
693
+ 'true' ,
694
+ ) ;
695
+ } ) ;
696
+
697
+ test ( `GIVEN a closed basic select
698
+ AND the first option is selected
699
+ WHEN the left arrow key is pressed
700
+ THEN it should stay on the first option` , async ( { page } ) => {
701
+ const { getTrigger, getOptions, getListbox, openListbox } = await setup (
702
+ page ,
703
+ 'select-hero-test' ,
704
+ ) ;
705
+
706
+ // initially first option is highlighted & listbox closed
707
+ await openListbox ( 'Enter' ) ;
708
+ await getTrigger ( ) . focus ( ) ;
709
+ await getTrigger ( ) . press ( 'Enter' ) ;
710
+ const options = await getOptions ( ) ;
711
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
712
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'aria-selected' , 'true' ) ;
713
+ await expect ( getListbox ( ) ) . toBeHidden ( ) ;
714
+
715
+ await getTrigger ( ) . focus ( ) ;
716
+ await getTrigger ( ) . press ( 'ArrowLeft' ) ;
717
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
718
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'aria-selected' , 'true' ) ;
719
+ } ) ;
720
+ } ) ;
721
+
722
+ test . describe ( 'loop enabled' , ( ) => {
723
+ test ( `GIVEN an open select with loop enabled
724
+ AND the last option is data-highlighted
725
+ WHEN the down arrow key is pressed
726
+ THEN the first option should have data-highlighted` , async ( { page } ) => {
727
+ const { getTrigger, getOptions, openListbox } = await setup (
728
+ page ,
729
+ 'select-loop-test' ,
730
+ ) ;
731
+
732
+ // initially last option is highlighted
733
+ await openListbox ( 'Enter' ) ;
734
+ await getTrigger ( ) . focus ( ) ;
735
+ await getTrigger ( ) . press ( 'End' ) ;
736
+ const options = await getOptions ( ) ;
737
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
738
+
739
+ await getTrigger ( ) . focus ( ) ;
740
+ await getTrigger ( ) . press ( 'ArrowDown' ) ;
741
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
742
+ } ) ;
743
+
744
+ test ( `GIVEN an open select with loop enabled
745
+ AND the first option is data-highlighted
746
+ WHEN the up arrow key is pressed
747
+ THEN the last option should have data-highlighted` , async ( { page } ) => {
748
+ const { getTrigger, getOptions, openListbox } = await setup (
749
+ page ,
750
+ 'select-loop-test' ,
751
+ ) ;
752
+
753
+ // initially last option is highlighted
754
+ await openListbox ( 'Enter' ) ;
755
+ const options = await getOptions ( ) ;
756
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
757
+
758
+ await getTrigger ( ) . focus ( ) ;
759
+ await getTrigger ( ) . press ( 'ArrowUp' ) ;
760
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
761
+ } ) ;
762
+
763
+ test ( `GIVEN a closed select with loop enabled
764
+ AND the last option is selected
765
+ WHEN the right arrow key is pressed
766
+ THEN it should loop to the first option` , async ( { page } ) => {
767
+ const { getTrigger, getOptions, openListbox } = await setup (
768
+ page ,
769
+ 'select-loop-test' ,
770
+ ) ;
771
+
772
+ // initially last option is highlighted
773
+ await openListbox ( 'Enter' ) ;
774
+ await getTrigger ( ) . focus ( ) ;
775
+ await getTrigger ( ) . press ( 'End' ) ;
776
+ await getTrigger ( ) . press ( 'Enter' ) ;
777
+ const options = await getOptions ( ) ;
778
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute (
779
+ 'aria-selected' ,
780
+ 'true' ,
781
+ ) ;
782
+
783
+ await getTrigger ( ) . focus ( ) ;
784
+ await getTrigger ( ) . press ( 'ArrowRight' ) ;
785
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
786
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'aria-selected' , 'true' ) ;
787
+ } ) ;
788
+
789
+ test ( `GIVEN a closed select with loop enabled
790
+ AND the first option is selected
791
+ WHEN the right arrow key is pressed
792
+ THEN it should loop to the first option` , async ( { page } ) => {
793
+ const { getTrigger, getOptions, openListbox } = await setup (
794
+ page ,
795
+ 'select-loop-test' ,
796
+ ) ;
797
+
798
+ // initially select first option
799
+ await openListbox ( 'Enter' ) ;
800
+ await getTrigger ( ) . focus ( ) ;
801
+ await getTrigger ( ) . press ( 'Enter' ) ;
802
+ const options = await getOptions ( ) ;
803
+ await expect ( options [ 0 ] ) . toHaveAttribute ( 'aria-selected' , 'true' ) ;
804
+
805
+ await getTrigger ( ) . focus ( ) ;
806
+ await getTrigger ( ) . press ( 'ArrowLeft' ) ;
807
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute ( 'data-highlighted' ) ;
808
+ await expect ( options [ options . length - 1 ] ) . toHaveAttribute (
809
+ 'aria-selected' ,
810
+ 'true' ,
811
+ ) ;
812
+ } ) ;
813
+ } ) ;
814
+ } ) ;
815
+
626
816
test ( `GIVEN an open select with multiple groups and a scrollable listbox
627
817
AND the last option is not visible
628
818
WHEN the end key is pressed
0 commit comments