Skip to content

Commit 5a7ac87

Browse files
committed
test(input): add functionality checks
1 parent dc55ac6 commit 5a7ac87

File tree

2 files changed

+110
-26
lines changed

2 files changed

+110
-26
lines changed

core/src/components/input/test/bottom-content/index.html

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,40 +49,67 @@
4949
</ion-header>
5050

5151
<ion-content id="content" class="ion-padding">
52-
<ion-input
53-
type="email"
54-
fill="solid"
55-
label="Email"
56-
label-placement="floating"
57-
helper-text="Enter a valid email"
58-
error-text="Invalid email"
59-
></ion-input>
52+
<div class="grid">
53+
<div class="grid-item">
54+
<h2>No Hint</h2>
55+
<ion-input label="Email"></ion-input>
56+
</div>
6057

61-
<script>
62-
const input = document.querySelector('ion-input');
58+
<div class="grid-item">
59+
<h2>Helper Hint</h2>
60+
<ion-input label="Email" helper-text="Enter your email"></ion-input>
61+
</div>
6362

64-
input.addEventListener('ionInput', (ev) => validate(ev));
65-
input.addEventListener('ionBlur', () => markTouched());
63+
<div class="grid-item">
64+
<h2>Error Hint</h2>
65+
<ion-input
66+
class="ion-touched ion-invalid"
67+
label="Email"
68+
error-text="Please enter a valid email"
69+
></ion-input>
70+
</div>
6671

67-
const validateEmail = (email) => {
68-
return email.match(
69-
/^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
70-
);
71-
};
72+
<div class="grid-item">
73+
<h2>Custom Error Color</h2>
74+
<ion-input
75+
class="ion-touched ion-invalid custom-error-color"
76+
label="Email"
77+
error-text="Please enter a valid email"
78+
></ion-input>
79+
</div>
7280

73-
const validate = (ev) => {
74-
const value = ev.target.value;
81+
<div class="grid-item">
82+
<h2>Counter</h2>
83+
<ion-input label="Email" counter="true" maxlength="100"></ion-input>
84+
</div>
7585

76-
input.classList.remove('ion-valid');
77-
input.classList.remove('ion-invalid');
86+
<div class="grid-item">
87+
<h2>Custom Counter</h2>
88+
<ion-input id="custom-counter" label="Email" counter="true" maxlength="100"></ion-input>
89+
</div>
7890

79-
if (value === '') return;
91+
<div class="grid-item">
92+
<h2>Counter with Helper</h2>
93+
<ion-input label="Email" counter="true" maxlength="100" helper-text="Enter an email"></ion-input>
94+
</div>
8095

81-
validateEmail(value) ? input.classList.add('ion-valid') : input.classList.add('ion-invalid');
82-
};
96+
<div class="grid-item">
97+
<h2>Counter with Error</h2>
98+
<ion-input
99+
class="ion-touched ion-invalid"
100+
label="Email"
101+
counter="true"
102+
maxlength="100"
103+
error-text="Please enter a valid email"
104+
></ion-input>
105+
</div>
106+
</div>
83107

84-
const markTouched = () => {
85-
input.classList.add('ion-touched');
108+
<script>
109+
const customCounterInput = document.querySelector('ion-input#custom-counter');
110+
customCounterInput.counterFormatter = (inputLength, maxLength) => {
111+
const length = maxLength - inputLength;
112+
return `${maxLength - inputLength} characters left`;
86113
};
87114
</script>
88115
</ion-content>

core/src/components/input/test/bottom-content/input.e2e.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)