@@ -144,44 +144,49 @@ describe('input: error text accessibility', () => {
144
144
145
145
const errorTextEl = page . body . querySelector ( 'ion-input .error-text' ) ;
146
146
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' ) ;
150
147
expect ( errorTextEl ! . getAttribute ( 'id' ) ) . toContain ( 'error-text' ) ;
148
+ expect ( errorTextEl ! . textContent ) . toBe ( 'This field is required' ) ;
151
149
} ) ;
152
150
153
- it ( 'should maintain error text structure when error text changes dynamically ' , async ( ) => {
151
+ it ( 'should set aria-invalid when input is invalid ' , async ( ) => {
154
152
const page = await newSpecPage ( {
155
153
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>` ,
157
155
} ) ;
158
156
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' ) ! ;
164
158
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' ) ;
169
161
} ) ;
170
162
171
- it ( 'should have proper aria-describedby reference structure ' , async ( ) => {
163
+ it ( 'should set aria-describedby to error text when invalid ' , async ( ) => {
172
164
const page = await newSpecPage ( {
173
165
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>` ,
175
167
} ) ;
176
168
169
+ const nativeInput = page . body . querySelector ( 'ion-input input' ) ! ;
177
170
const errorTextEl = page . body . querySelector ( 'ion-input .error-text' ) ! ;
178
171
179
- // Verify the error text element has an ID
172
+ // Verify aria-describedby points to error text
180
173
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' ) ! ;
182
185
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' ) ;
185
190
} ) ;
186
191
187
192
it ( 'should have helper text element with proper structure' , async ( ) => {
@@ -195,4 +200,22 @@ describe('input: error text accessibility', () => {
195
200
expect ( helperTextEl ! . getAttribute ( 'id' ) ) . toContain ( 'helper-text' ) ;
196
201
expect ( helperTextEl ! . textContent ) . toBe ( 'Enter a valid value' ) ;
197
202
} ) ;
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
+ } ) ;
198
221
} ) ;
0 commit comments