Skip to content

Commit 9d14d67

Browse files
committed
test(textarea): add on to form test for submit and reset
1 parent ab96071 commit 9d14d67

File tree

2 files changed

+124
-12
lines changed

2 files changed

+124
-12
lines changed

core/src/components/textarea/test/form/index.html

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,28 @@
1414
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
1515

1616
<style>
17+
.grid {
18+
display: grid;
19+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
20+
gap: 6px;
21+
}
22+
1723
.required-label {
1824
display: none;
1925
}
2026

2127
.textarea-required .required-label {
2228
display: inline;
23-
color: red;
29+
color: #b80000;
30+
}
31+
32+
ion-textarea {
33+
margin-bottom: 16px;
34+
}
35+
36+
ion-content button.reset-button {
37+
background: #960101;
38+
border-color: #650000;
2439
}
2540
</style>
2641
</head>
@@ -37,41 +52,78 @@
3752
<form onsubmit="return onSubmit(event)">
3853
<ion-textarea
3954
fill="outline"
55+
label="Textarea 1"
4056
label-placement="stacked"
41-
placeholder="Placeholder"
57+
placeholder="Textarea 1"
4258
helper-text="Helper message"
4359
counter="true"
4460
maxlength="999"
61+
name="textarea1"
4562
>
46-
<div slot="label">Label <span class="required-label">(Required) *</span></div>
4763
<ion-icon slot="end" name="square-outline"></ion-icon>
4864
</ion-textarea>
4965

66+
<ion-textarea
67+
fill="outline"
68+
label-placement="stacked"
69+
placeholder="Textarea 2"
70+
helper-text="Helper message"
71+
counter="true"
72+
maxlength="999"
73+
name="textarea2"
74+
>
75+
<div slot="label">Textarea 2 <span class="required-label">(Required) *</span></div>
76+
<ion-icon slot="end" name="square-outline"></ion-icon>
77+
</ion-textarea>
78+
79+
<div class="grid">
80+
<button type="button" onClick="toggleRequired()">Toggle Required (Textarea 2)</button>
81+
</div>
82+
5083
<p>
51-
Click the first button below to toggle the required prop and then click the submit button to attempt to
52-
submit the form. It should show a popup warning to fill out the field when textarea is required and empty.
53-
When the textarea is not required, or the field is filled, the form should submit by sending a console log.
84+
Click the button above to toggle the required prop on the
85+
2nd textarea and then click the submit button to attempt to submit
86+
the form. It should show a popup warning on the 2nd textarea to
87+
fill out the field when the textarea is required and empty. When
88+
the textarea is not required, or the field is filled, the form
89+
should submit by sending a console log. Click the reset button to
90+
reset the form and clear the textareas.
5491
</p>
55-
<button type="button" onClick="toggleRequired()">Toggle Required</button>
56-
<button type="submit">Submit</button>
92+
93+
<div class="grid">
94+
<button type="submit">Submit</button>
95+
<button type="reset" class="reset-button">Reset</button>
96+
</div>
5797
</form>
5898
</ion-content>
5999
</ion-app>
60100

61101
<script>
102+
const form = document.querySelector('form');
103+
62104
function onSubmit(event) {
63105
event.preventDefault();
64-
const textarea = document.querySelector('ion-textarea');
65-
console.log('Form submitted with value:', textarea.value);
106+
console.log('Form submitted with values:', getFormData(form));
66107
return true;
67108
}
68109

69110
function toggleRequired() {
70-
const textarea = document.querySelector('ion-textarea');
111+
const textarea = document.querySelector('[name="textarea2"]');
71112
textarea.required = textarea.required ? false : true;
72113
textarea.classList.toggle('textarea-required', textarea.required);
73114
console.log('Textarea required set to:', textarea.required);
74115
}
116+
117+
// Helper function to get the form data as a plain object
118+
function getFormData(form) {
119+
const formData = new FormData(form);
120+
// Convert FormData to a plain object for easier inspection
121+
const formDataEntries = {};
122+
for (const [key, value] of formData.entries()) {
123+
formDataEntries[key] = value;
124+
}
125+
return formDataEntries;
126+
}
75127
</script>
76128
</body>
77129
</html>

core/src/components/textarea/test/form/textarea.e2e.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
9595
const textarea = page.locator('ion-textarea');
9696
const submitButton = page.locator('button[type="submit"]');
9797

98-
// Type into the native textarea in the shadow DOM
98+
// Type into the native textarea
9999
await textarea.evaluate((el: HTMLIonTextareaElement) => {
100100
const nativeTextarea = el.shadowRoot?.querySelector('textarea') as HTMLTextAreaElement | null;
101101
if (nativeTextarea) {
@@ -135,5 +135,65 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
135135
});
136136
expect(isValidAfterSubmit).toBe(true);
137137
});
138+
139+
test('should set formData when submitted', async ({ page }) => {
140+
await page.setContent(
141+
`
142+
<form onsubmit="return onSubmit(event)">
143+
<ion-textarea label="textarea" name="textarea" required></ion-textarea>
144+
<button type="submit">Submit</button>
145+
</form>
146+
<script>
147+
function onSubmit(event) {
148+
window.formSubmitted = true;
149+
event.preventDefault();
150+
return false;
151+
}
152+
</script>
153+
`,
154+
config
155+
);
156+
157+
const textarea = page.locator('ion-textarea');
158+
const submitButton = page.locator('button[type="submit"]');
159+
160+
// Type into the native textarea
161+
await textarea.evaluate((el: HTMLIonTextareaElement) => {
162+
const nativeTextarea = el.shadowRoot?.querySelector('textarea') as HTMLTextAreaElement | null;
163+
if (nativeTextarea) {
164+
nativeTextarea.value = 'Test value';
165+
nativeTextarea.dispatchEvent(new Event('input', { bubbles: true }));
166+
}
167+
});
168+
169+
// Click submit button - form should submit since validation passes
170+
await submitButton.click();
171+
172+
// Wait for any async operations to complete
173+
await page.waitForChanges();
174+
175+
// Verify that the form's validation passed
176+
const formValidity = await page.evaluate(() => {
177+
const form = document.querySelector('form');
178+
return form ? form.checkValidity() : null;
179+
});
180+
expect(formValidity).toBe(true);
181+
182+
// Verify that the formData is set
183+
const formData = await page.evaluate(() => {
184+
const form = document.querySelector('form');
185+
if (!form) {
186+
return null;
187+
}
188+
const formData = new FormData(form);
189+
const entries: Record<string, string> = {};
190+
for (const [key, value] of formData.entries()) {
191+
entries[key] = value.toString();
192+
}
193+
return entries;
194+
});
195+
expect(formData).toBeDefined();
196+
expect(formData?.['textarea']).toBe('Test value');
197+
});
138198
});
139199
});

0 commit comments

Comments
 (0)