@@ -144,44 +144,49 @@ describe('input: error text accessibility', () => {
144144
145145 const errorTextEl = page . body . querySelector ( 'ion-input .error-text' ) ;
146146 expect ( errorTextEl ) . not . toBe ( null ) ;
147-
148- // Error text element should always exist and have aria-atomic
149- expect ( errorTextEl ! . getAttribute ( 'aria-atomic' ) ) . toBe ( 'true' ) ;
150147 expect ( errorTextEl ! . getAttribute ( 'id' ) ) . toContain ( 'error-text' ) ;
148+ expect ( errorTextEl ! . textContent ) . toBe ( 'This field is required' ) ;
151149 } ) ;
152150
153- it ( 'should maintain error text structure when error text changes dynamically ' , async ( ) => {
151+ it ( 'should set aria-invalid when input is invalid ' , async ( ) => {
154152 const page = await newSpecPage ( {
155153 components : [ Input ] ,
156- html : `<ion-input label="Input"></ion-input>` ,
154+ html : `<ion-input label="Input" error-text="Required field" class="ion-touched ion-invalid" ></ion-input>` ,
157155 } ) ;
158156
159- const input = page . body . querySelector ( 'ion-input' ) ! ;
160-
161- // Add error text dynamically
162- input . setAttribute ( 'error-text' , 'Invalid email format' ) ;
163- await page . waitForChanges ( ) ;
157+ const nativeInput = page . body . querySelector ( 'ion-input input' ) ! ;
164158
165- const errorTextEl = page . body . querySelector ( 'ion-input .error-text' ) ;
166- expect ( errorTextEl ) . not . toBe ( null ) ;
167- expect ( errorTextEl ! . getAttribute ( 'aria-atomic' ) ) . toBe ( 'true' ) ;
168- expect ( errorTextEl ! . getAttribute ( 'id' ) ) . toContain ( 'error-text' ) ;
159+ // Should be invalid because of the classes
160+ expect ( nativeInput . getAttribute ( 'aria-invalid' ) ) . toBe ( 'true' ) ;
169161 } ) ;
170162
171- it ( 'should have proper aria-describedby reference structure ' , async ( ) => {
163+ it ( 'should set aria-describedby to error text when invalid ' , async ( ) => {
172164 const page = await newSpecPage ( {
173165 components : [ Input ] ,
174- html : `<ion-input label="Input" error-text="Required field"></ion-input>` ,
166+ html : `<ion-input label="Input" error-text="Required field" class="ion-touched ion-invalid" ></ion-input>` ,
175167 } ) ;
176168
169+ const nativeInput = page . body . querySelector ( 'ion-input input' ) ! ;
177170 const errorTextEl = page . body . querySelector ( 'ion-input .error-text' ) ! ;
178171
179- // Verify the error text element has an ID
172+ // Verify aria-describedby points to error text
180173 const errorId = errorTextEl . getAttribute ( 'id' ) ;
181- expect ( errorId ) . toContain ( 'error-text' ) ;
174+ expect ( nativeInput . getAttribute ( 'aria-describedby' ) ) . toBe ( errorId ) ;
175+ } ) ;
176+
177+ it ( 'should set aria-describedby to helper text when valid' , async ( ) => {
178+ const page = await newSpecPage ( {
179+ components : [ Input ] ,
180+ html : `<ion-input label="Input" helper-text="Enter a value" error-text="Required field"></ion-input>` ,
181+ } ) ;
182+
183+ const nativeInput = page . body . querySelector ( 'ion-input input' ) ! ;
184+ const helperTextEl = page . body . querySelector ( 'ion-input .helper-text' ) ! ;
182185
183- // Note: aria-describedby is dynamically set based on validation state
184- // The actual connection happens when the input becomes invalid
186+ // When not invalid, should point to helper text
187+ const helperId = helperTextEl . getAttribute ( 'id' ) ;
188+ expect ( nativeInput . getAttribute ( 'aria-describedby' ) ) . toBe ( helperId ) ;
189+ expect ( nativeInput . getAttribute ( 'aria-invalid' ) ) . toBe ( 'false' ) ;
185190 } ) ;
186191
187192 it ( 'should have helper text element with proper structure' , async ( ) => {
@@ -195,4 +200,22 @@ describe('input: error text accessibility', () => {
195200 expect ( helperTextEl ! . getAttribute ( 'id' ) ) . toContain ( 'helper-text' ) ;
196201 expect ( helperTextEl ! . textContent ) . toBe ( 'Enter a valid value' ) ;
197202 } ) ;
203+
204+ it ( 'should maintain error text content when error text changes dynamically' , async ( ) => {
205+ const page = await newSpecPage ( {
206+ components : [ Input ] ,
207+ html : `<ion-input label="Input"></ion-input>` ,
208+ } ) ;
209+
210+ const input = page . body . querySelector ( 'ion-input' ) ! ;
211+
212+ // Add error text dynamically
213+ input . setAttribute ( 'error-text' , 'Invalid email format' ) ;
214+ await page . waitForChanges ( ) ;
215+
216+ const errorTextEl = page . body . querySelector ( 'ion-input .error-text' ) ;
217+ expect ( errorTextEl ) . not . toBe ( null ) ;
218+ expect ( errorTextEl ! . getAttribute ( 'id' ) ) . toContain ( 'error-text' ) ;
219+ expect ( errorTextEl ! . textContent ) . toBe ( 'Invalid email format' ) ;
220+ } ) ;
198221} ) ;
0 commit comments