From 0d273c4b604f3f29d33ce07146083c41c35d5b0a Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:47:47 -0500 Subject: [PATCH 01/14] fix(input): use darker color for helper text --- core/src/components/input/input.md.solid.scss | 4 ++++ core/src/components/input/input.scss | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/components/input/input.md.solid.scss b/core/src/components/input/input.md.solid.scss index 98cde92880a..05bcc00ea55 100644 --- a/core/src/components/input/input.md.solid.scss +++ b/core/src/components/input/input.md.solid.scss @@ -32,6 +32,10 @@ --border-color: var(--highlight-color); } +/** + * The bottom content should never have + * a border with the solid style. + */ :host(.input-fill-solid) .input-bottom { border-top: none; } diff --git a/core/src/components/input/input.scss b/core/src/components/input/input.scss index 80ebc9896ae..9a52f2ac519 100644 --- a/core/src/components/input/input.scss +++ b/core/src/components/input/input.scss @@ -306,6 +306,8 @@ border-top: var(--border-width) var(--border-style) var(--border-color); font-size: dynamic-font(12px); + + white-space: normal; } /** @@ -340,7 +342,7 @@ .input-bottom .helper-text { display: block; - color: #{$text-color-step-450}; + color: $text-color-step-300; } :host(.ion-touched.ion-invalid) .input-bottom .error-text { From 940fb84a1cbc480dbc08496ce4d15e40461f92a8 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:57:08 -0500 Subject: [PATCH 02/14] test(input): update e2e test to improve examples --- .../input/test/bottom-content/index.html | 101 +++-- .../input/test/bottom-content/input.e2e.ts | 354 ++++++++++-------- 2 files changed, 272 insertions(+), 183 deletions(-) diff --git a/core/src/components/input/test/bottom-content/index.html b/core/src/components/input/test/bottom-content/index.html index d08d111c0eb..cc61c09265f 100644 --- a/core/src/components/input/test/bottom-content/index.html +++ b/core/src/components/input/test/bottom-content/index.html @@ -15,10 +15,11 @@ - - `, - config - ); + await expect(input).toHaveAttribute('aria-invalid'); + }); + test('input should not have aria-invalid attribute when input is valid', async ({ page }) => { + await page.setContent( + ``, + config + ); - const errorText = page.locator('ion-input .error-text'); - await expect(errorText).toHaveScreenshot(screenshot(`input-error-custom-color`)); - }); - test('input should have an aria-describedby attribute when error text is present', async ({ page }) => { - await page.setContent( - ``, - config - ); + const input = page.locator('ion-input input'); - const input = page.locator('ion-input input'); - const errorText = page.locator('ion-input .error-text'); - const errorTextId = await errorText.getAttribute('id'); - const ariaDescribedBy = await input.getAttribute('aria-describedby'); + await expect(input).not.toHaveAttribute('aria-invalid'); + }); + test('input should not have aria-describedby attribute when no hint or error text is present', async ({ + page, + }) => { + await page.setContent(``, config); - expect(ariaDescribedBy).toBe(errorTextId); - }); - test('input should have aria-invalid attribute when input is invalid', async ({ page }) => { - await page.setContent( - ``, - config - ); + const input = page.locator('ion-input input'); - const input = page.locator('ion-input input'); + await expect(input).not.toHaveAttribute('aria-describedby'); + }); + }); +}); - await expect(input).toHaveAttribute('aria-invalid'); - }); - test('input should not have aria-invalid attribute when input is valid', async ({ page }) => { - await page.setContent( - ``, - config - ); +/** + * Rendering is different across modes + */ +configs({ modes: ['ios', 'md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('input: helper text rendering'), () => { + test('should not have visual regressions when rendering helper text', async ({ page }) => { + await page.setContent(``, config); - const input = page.locator('ion-input input'); + const bottomEl = page.locator('ion-input'); + await expect(bottomEl).toHaveScreenshot(screenshot(`input-helper-text`)); + }); + test('should not have visual regressions when rendering helper text with wrapping text', async ({ page }) => { + await page.setContent( + ``, + config + ); - await expect(input).not.toHaveAttribute('aria-invalid'); - }); - test('input should not have aria-describedby attribute when no hint or error text is present', async ({ - page, - }) => { - await page.setContent(``, config); + const bottomEl = page.locator('ion-input'); + await expect(bottomEl).toHaveScreenshot(screenshot(`input-helper-text-wrapping`)); + }); + test('should not have visual regressions when rendering helper text with a stacked label', async ({ page }) => { + await page.setContent( + ``, + config + ); - const input = page.locator('ion-input input'); + const bottomEl = page.locator('ion-input'); + await expect(bottomEl).toHaveScreenshot(screenshot(`input-helper-text-stacked-label`)); + }); + }); - await expect(input).not.toHaveAttribute('aria-describedby'); - }); + test.describe(title('input: error text rendering'), () => { + test('should not have visual regressions when rendering error text', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const bottomEl = page.locator('ion-input'); + await expect(bottomEl).toHaveScreenshot(screenshot(`input-error-text`)); }); - test.describe('input: hint text rendering', () => { - test.describe('regular inputs', () => { - test('should not have visual regressions when rendering helper text', async ({ page }) => { - await page.setContent(``, config); - - const bottomEl = page.locator('ion-input .input-bottom'); - await expect(bottomEl).toHaveScreenshot(screenshot(`input-bottom-content-helper`)); - }); - test('should not have visual regressions when rendering error text', async ({ page }) => { - await page.setContent( - ``, - config - ); - - const bottomEl = page.locator('ion-input .input-bottom'); - await expect(bottomEl).toHaveScreenshot(screenshot(`input-bottom-content-error`)); - }); - }); + test('should not have visual regressions when rendering error text with a stacked label', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const bottomEl = page.locator('ion-input'); + await expect(bottomEl).toHaveScreenshot(screenshot(`input-error-text-stacked-label`)); }); }); }); /** - * Rendering is the same across modes + * Customizing supporting text is the same across modes and directions */ +configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('input: supporting text customization'), () => { + test('should not have visual regressions when rendering helper text with a custom color via css', async ({ + page, + }) => { + await page.setContent( + ` + + + `, + config + ); + + const helperText = page.locator('ion-input'); + await expect(helperText).toHaveScreenshot(screenshot(`input-helper-text-custom-color`)); + }); + test('should not have visual regressions when rendering error text with a custom color via css', async ({ + page, + }) => { + await page.setContent( + ` + + + `, + config + ); + + const errorText = page.locator('ion-input'); + await expect(errorText).toHaveScreenshot(screenshot(`input-error-text-custom-color`)); + }); + test('should not have visual regressions when rendering error text with a custom color via css var', async ({ + page, + }) => { + await page.setContent( + ` + + + `, + config + ); + + const errorText = page.locator('ion-input'); + await expect(errorText).toHaveScreenshot(screenshot(`input-error-text-custom-color-var`)); + }); + }); +}); + configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { test.describe(title('input: counter'), () => { test.describe('input: counter functionality', () => { test('should not activate if maxlength is not specified even if bottom content is visible', async ({ page }) => { await page.setContent( ` - + `, config ); @@ -193,7 +226,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co test('default formatter should be used', async ({ page }) => { await page.setContent( ` - + `, config ); @@ -203,8 +236,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co test('custom formatter should be used when provided', async ({ page }) => { await page.setContent( ` - - +