@@ -114,6 +114,38 @@ test.describe('Dropdown', () => {
114114 await expect ( listbox ) . toBeVisible ( ) ;
115115 } ) ;
116116
117+ test ( 'should open the dropdown when a character is pressed' , async ( { fastPage } ) => {
118+ const { element } = fastPage ;
119+ const listbox = element . locator ( ListboxTagName ) ;
120+ const button = element . locator ( '[role=combobox]' ) ;
121+
122+ await fastPage . setTemplate ( ) ;
123+
124+ await button . press ( 'a' ) ;
125+
126+ await expect ( listbox ) . toBeVisible ( ) ;
127+ } ) ;
128+
129+ test ( 'should not open the dropdown when a character is pressed with Meta, Alt, or Ctrl' , async ( { fastPage } ) => {
130+ const { element } = fastPage ;
131+ const listbox = element . locator ( ListboxTagName ) ;
132+ const button = element . locator ( '[role=combobox]' ) ;
133+
134+ await fastPage . setTemplate ( ) ;
135+
136+ await button . press ( 'Meta+a' ) ;
137+
138+ await expect ( listbox ) . toBeHidden ( ) ;
139+
140+ await button . press ( 'Alt+a' ) ;
141+
142+ await expect ( listbox ) . toBeHidden ( ) ;
143+
144+ await button . press ( 'Control+a' ) ;
145+
146+ await expect ( listbox ) . toBeHidden ( ) ;
147+ } ) ;
148+
117149 test ( "should set the `name` property on options when it's set on the dropdown" , async ( { fastPage } ) => {
118150 const { element } = fastPage ;
119151 const options = element . locator ( OptionTagName ) ;
@@ -550,4 +582,90 @@ test.describe('Dropdown', () => {
550582
551583 await expect ( listbox ) . toBeHidden ( ) ;
552584 } ) ;
585+
586+ test . describe ( 'search options by printable characters' , ( ) => {
587+ test . use ( {
588+ innerHTML : /* html */ `
589+ <${ ListboxTagName } >
590+ <${ OptionTagName } id="o1">Afoo</${ OptionTagName } >
591+ <${ OptionTagName } id="o2">Bfoo</${ OptionTagName } >
592+ <${ OptionTagName } id="o3">Bbfoo</${ OptionTagName } >
593+ <${ OptionTagName } id="o4">Bcfoo</${ OptionTagName } >
594+ <${ OptionTagName } id="o5">Cfoo</${ OptionTagName } >
595+ </${ ListboxTagName } >
596+ ` ,
597+ } ) ;
598+
599+ test ( 'should set active descendant based on user typing' , async ( { fastPage } ) => {
600+ const { element, page } = fastPage ;
601+ const combobox = element . getByRole ( 'combobox' ) ;
602+
603+ await fastPage . setTemplate ( ) ;
604+
605+ await combobox . focus ( ) ;
606+ await page . keyboard . press ( 'b' , { delay : 500 } ) ;
607+
608+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o2' ) ;
609+
610+ await page . keyboard . press ( 'a' , { delay : 500 } ) ;
611+
612+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o1' ) ;
613+
614+ await page . keyboard . press ( 'c' , { delay : 500 } ) ;
615+
616+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o5' ) ;
617+
618+ await page . keyboard . press ( 'd' ) ;
619+
620+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o5' ) ;
621+ } ) ;
622+
623+ test ( 'should cycle through matching options as active descendant based on user typing' , async ( { fastPage } ) => {
624+ const { element, page } = fastPage ;
625+ const combobox = element . getByRole ( 'combobox' ) ;
626+
627+ await fastPage . setTemplate ( ) ;
628+
629+ await combobox . focus ( ) ;
630+ await page . keyboard . press ( 'b' ) ;
631+
632+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o2' ) ;
633+
634+ await page . keyboard . press ( 'b' ) ;
635+
636+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o3' ) ;
637+
638+ await page . keyboard . press ( 'b' ) ;
639+
640+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o4' ) ;
641+
642+ await page . keyboard . press ( 'b' ) ;
643+
644+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o2' ) ;
645+ } ) ;
646+
647+ test ( 'should set active descendant if its label has repeated character' , async ( { fastPage } ) => {
648+ const { element, page } = fastPage ;
649+ const combobox = element . getByRole ( 'combobox' ) ;
650+
651+ await fastPage . setTemplate ( ) ;
652+
653+ await combobox . focus ( ) ;
654+ await page . keyboard . type ( 'bb' , { delay : 100 } ) ;
655+
656+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o3' ) ;
657+
658+ await page . waitForTimeout ( 500 ) ;
659+
660+ await page . keyboard . type ( 'bb' , { delay : 100 } ) ;
661+
662+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o3' ) ;
663+
664+ await page . waitForTimeout ( 500 ) ;
665+
666+ await page . keyboard . type ( 'bb' , { delay : 600 } ) ;
667+
668+ await expect ( combobox ) . toHaveAttribute ( 'aria-activedescendant' , 'o2' ) ;
669+ } ) ;
670+ } ) ;
553671} ) ;
0 commit comments