@@ -68,6 +68,19 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
6868 await expect ( helperText ) . toHaveText ( 'my helper' ) ;
6969 await expect ( errorText ) . toBeHidden ( ) ;
7070 } ) ;
71+ test ( 'input should have an aria-describedby attribute when helper text is present' , async ( { page } ) => {
72+ await page . setContent (
73+ `<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>` ,
74+ config
75+ ) ;
76+
77+ const input = page . locator ( 'ion-input input' ) ;
78+ const helperText = page . locator ( 'ion-input .helper-text' ) ;
79+ const helperTextId = await helperText . getAttribute ( 'id' ) ;
80+ const ariaDescribedBy = await input . getAttribute ( 'aria-describedby' ) ;
81+
82+ expect ( ariaDescribedBy ) . toBe ( helperTextId ) ;
83+ } ) ;
7184 test ( 'error text should be visible when input is invalid' , async ( { page } ) => {
7285 await page . setContent (
7386 `<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>` ,
@@ -96,6 +109,50 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
96109 const errorText = page . locator ( 'ion-input .error-text' ) ;
97110 await expect ( errorText ) . toHaveScreenshot ( screenshot ( `input-error-custom-color` ) ) ;
98111 } ) ;
112+ test ( 'input should have an aria-describedby attribute when error text is present' , async ( { page } ) => {
113+ await page . setContent (
114+ `<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>` ,
115+ config
116+ ) ;
117+
118+ const input = page . locator ( 'ion-input input' ) ;
119+ const errorText = page . locator ( 'ion-input .error-text' ) ;
120+ const errorTextId = await errorText . getAttribute ( 'id' ) ;
121+ const ariaDescribedBy = await input . getAttribute ( 'aria-describedby' ) ;
122+
123+ expect ( ariaDescribedBy ) . toBe ( errorTextId ) ;
124+ } ) ;
125+ test ( 'input should have aria-invalid attribute when input is invalid' , async ( { page } ) => {
126+ await page . setContent (
127+ `<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>` ,
128+ config
129+ ) ;
130+
131+ const input = page . locator ( 'ion-input input' ) ;
132+
133+ await expect ( input ) . toHaveAttribute ( 'aria-invalid' , '' ) ;
134+ } ) ;
135+ test ( 'input should not have aria-invalid attribute when input is valid' , async ( { page } ) => {
136+ await page . setContent (
137+ `<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>` ,
138+ config
139+ ) ;
140+
141+ const input = page . locator ( 'ion-input input' ) ;
142+ const ariaInvalid = await input . getAttribute ( 'aria-invalid' ) ;
143+
144+ expect ( ariaInvalid ) . toBe ( null ) ;
145+ } ) ;
146+ test ( 'input should not have aria-describedby attribute when no hint or error text is present' , async ( {
147+ page,
148+ } ) => {
149+ await page . setContent ( `<ion-input label="my input"></ion-input>` , config ) ;
150+
151+ const input = page . locator ( 'ion-input input' ) ;
152+ const ariaDescribedBy = await input . getAttribute ( 'aria-describedby' ) ;
153+
154+ expect ( ariaDescribedBy ) . toBe ( null ) ;
155+ } ) ;
99156 } ) ;
100157 test . describe ( 'input: hint text rendering' , ( ) => {
101158 test . describe ( 'regular inputs' , ( ) => {
0 commit comments