From d147f89f177403a09e8a91cc473d1e1149980864 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:53:52 -0500 Subject: [PATCH] test(select): add e2e test for bottom content --- .../select/test/bottom-content/index.html | 132 ++++++++++++ .../select/test/bottom-content/select.e2e.ts | 195 ++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 core/src/components/select/test/bottom-content/index.html create mode 100644 core/src/components/select/test/bottom-content/select.e2e.ts diff --git a/core/src/components/select/test/bottom-content/index.html b/core/src/components/select/test/bottom-content/index.html new file mode 100644 index 00000000000..b27b6134ad5 --- /dev/null +++ b/core/src/components/select/test/bottom-content/index.html @@ -0,0 +1,132 @@ + + + + + Select - Bottom Content + + + + + + + + + + + + + + Select - Bottom Content + + + + +
+
+

No Hint

+ + Option + +
+ +
+

No Hint: Stacked

+ + Option + +
+ +
+

Helper Text

+ + Option + +
+ +
+

Helper Text: Stacked

+ Label + Option + +
+ +
+

Error Text

+ + Option +
+ +
+

Error Text: Stacked

+ + Option +
+ +
+

Error Text: Custom Color

+ + Option +
+ +
+

Helper Text: Wrapping

+ + Option + +
+
+ + +
+
+ + + + diff --git a/core/src/components/select/test/bottom-content/select.e2e.ts b/core/src/components/select/test/bottom-content/select.e2e.ts new file mode 100644 index 00000000000..ead4a72ca8f --- /dev/null +++ b/core/src/components/select/test/bottom-content/select.e2e.ts @@ -0,0 +1,195 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * Functionality is the same across modes & directions + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('select: bottom content functionality'), () => { + test('should not render bottom content if no hint is enabled', async ({ page }) => { + await page.setContent(``, config); + + const bottomEl = page.locator('ion-select .select-bottom'); + await expect(bottomEl).toHaveCount(0); + }); + test('helper text should be visible initially', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const helperText = page.locator('ion-select .helper-text'); + const errorText = page.locator('ion-select .error-text'); + await expect(helperText).toBeVisible(); + await expect(helperText).toHaveText('Helper text'); + await expect(errorText).toBeHidden(); + }); + test('input should have an aria-describedby attribute when helper text is present', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const input = page.locator('ion-select button'); + const helperText = page.locator('ion-select .helper-text'); + const helperTextId = await helperText.getAttribute('id'); + const ariaDescribedBy = await input.getAttribute('aria-describedby'); + + expect(ariaDescribedBy).toBe(helperTextId); + }); + test('error text should be visible when select is invalid', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const helperText = page.locator('ion-select .helper-text'); + const errorText = page.locator('ion-select .error-text'); + await expect(helperText).toBeHidden(); + await expect(errorText).toBeVisible(); + await expect(errorText).toHaveText('Error text'); + }); + + test('input should have an aria-describedby attribute when error text is present', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const input = page.locator('ion-select button'); + const errorText = page.locator('ion-select .error-text'); + const errorTextId = await errorText.getAttribute('id'); + const ariaDescribedBy = await input.getAttribute('aria-describedby'); + + 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-select button'); + + 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 input = page.locator('ion-select button'); + + 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 input = page.locator('ion-select button'); + + await expect(input).not.toHaveAttribute('aria-describedby'); + }); + }); +}); + +/** + * Rendering is different across modes + */ +configs({ modes: ['ios', 'md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('select: helper text rendering'), () => { + test('should not have visual regressions when rendering helper text', async ({ page }) => { + await page.setContent(``, config); + + const bottomEl = page.locator('ion-select'); + await expect(bottomEl).toHaveScreenshot(screenshot(`select-helper-text`)); + }); + test('should not have visual regressions when rendering helper text with wrapping text', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const bottomEl = page.locator('ion-select'); + await expect(bottomEl).toHaveScreenshot(screenshot(`select-helper-text-wrapping`)); + }); + test('should not have visual regressions when rendering helper text with a stacked label', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const bottomEl = page.locator('ion-select'); + await expect(bottomEl).toHaveScreenshot(screenshot(`select-helper-text-stacked-label`)); + }); + }); + + test.describe(title('select: error text rendering'), () => { + test('should not have visual regressions when rendering error text', async ({ page }) => { + await page.setContent( + ``, + config + ); + + const bottomEl = page.locator('ion-select'); + await expect(bottomEl).toHaveScreenshot(screenshot(`select-error-text`)); + }); + 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-select'); + await expect(bottomEl).toHaveScreenshot(screenshot(`select-error-text-stacked-label`)); + }); + }); +}); + +/** + * Customizing supporting text is the same across modes and directions + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('select: supporting text customization'), () => { + test('should not have visual regressions when rendering helper text with a custom color', async ({ page }) => { + await page.setContent( + ` + + + `, + config + ); + + const errorText = page.locator('ion-select'); + await expect(errorText).toHaveScreenshot(screenshot(`select-helper-text-custom`)); + }); + test('should not have visual regressions when rendering error text with a custom color', async ({ page }) => { + await page.setContent( + ` + + + `, + config + ); + + const errorText = page.locator('ion-select'); + await expect(errorText).toHaveScreenshot(screenshot(`select-error-text-custom`)); + }); + }); +});