-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(select): add e2e test for bottom content
- Loading branch information
1 parent
5acf8ab
commit d147f89
Showing
2 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
132 changes: 132 additions & 0 deletions
132
core/src/components/select/test/bottom-content/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" dir="ltr"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<title>Select - Bottom Content</title> | ||
<meta | ||
name="viewport" | ||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" | ||
/> | ||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" /> | ||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" /> | ||
<script src="../../../../../scripts/testing/scripts.js"></script> | ||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script> | ||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script> | ||
<style> | ||
.grid { | ||
display: grid; | ||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | ||
grid-row-gap: 20px; | ||
grid-column-gap: 20px; | ||
} | ||
|
||
h2 { | ||
font-size: 12px; | ||
font-weight: normal; | ||
|
||
color: #6f7378; | ||
|
||
margin-top: 10px; | ||
} | ||
|
||
ion-select.custom-error-color { | ||
--highlight-color-invalid: purple; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<ion-app> | ||
<ion-header> | ||
<ion-toolbar> | ||
<ion-title>Select - Bottom Content</ion-title> | ||
</ion-toolbar> | ||
</ion-header> | ||
|
||
<ion-content id="content" class="ion-padding"> | ||
<div class="grid"> | ||
<div class="grid-item"> | ||
<h2>No Hint</h2> | ||
<ion-select label="Label"> | ||
<ion-select-option>Option</ion-select-option> | ||
</ion-select> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>No Hint: Stacked</h2> | ||
<ion-select label="Label" label-placement="stacked"> | ||
<ion-select-option>Option</ion-select-option> | ||
</ion-select> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>Helper Text</h2> | ||
<ion-select label="Label" helper-text="Helper text"> | ||
<ion-select-option>Option</ion-select-option> | ||
</ion-select> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>Helper Text: Stacked</h2> | ||
<ion-select label="Label" label-placement="stacked" helper-text="Helper text" | ||
>Label | ||
<ion-select-option>Option</ion-select-option> | ||
</ion-select> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>Error Text</h2> | ||
<ion-select class="ion-touched ion-invalid" label="Label" error-text="Error text"> | ||
<ion-select-option>Option</ion-select-option></ion-select | ||
> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>Error Text: Stacked</h2> | ||
<ion-select class="ion-touched ion-invalid" label="Label" label-placement="stacked" error-text="Error text"> | ||
<ion-select-option>Option</ion-select-option></ion-select | ||
> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>Error Text: Custom Color</h2> | ||
<ion-select class="ion-touched ion-invalid custom-error-color" label="Label" error-text="Error text"> | ||
<ion-select-option>Option</ion-select-option></ion-select | ||
> | ||
</div> | ||
|
||
<div class="grid-item"> | ||
<h2>Helper Text: Wrapping</h2> | ||
<ion-select | ||
label="Label" | ||
helper-text="Helper text helper text helper text helper text helper text helper text helper text helper text helper text" | ||
> | ||
<ion-select-option>Option</ion-select-option> | ||
</ion-select> | ||
</div> | ||
</div> | ||
|
||
<button class="expand" onclick="toggleFill()">Toggle Fill</button> | ||
</ion-content> | ||
</ion-app> | ||
|
||
<script> | ||
const selects = document.querySelectorAll('ion-select'); | ||
|
||
function toggleFill() { | ||
selects.forEach((select) => { | ||
switch (select.fill) { | ||
case 'outline': | ||
select.fill = 'solid'; | ||
break; | ||
case 'solid': | ||
select.fill = undefined; | ||
break; | ||
default: | ||
select.fill = 'outline'; | ||
} | ||
}); | ||
} | ||
</script> | ||
</body> | ||
</html> |
195 changes: 195 additions & 0 deletions
195
core/src/components/select/test/bottom-content/select.e2e.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(`<ion-select label="Label"></ion-select>`, 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( | ||
`<ion-select label="Label" helper-text="Helper text" error-text="Error text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" helper-text="Helper text" error-text="Error text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" class="ion-invalid ion-touched" helper-text="Helper text" error-text="Error text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" class="ion-invalid ion-touched" helper-text="Helper text" error-text="Error text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" class="ion-invalid ion-touched" helper-text="Helper text" error-text="Error text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" helper-text="Helper text" error-text="Error text"></ion-select>`, | ||
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(`<ion-select label="Label"></ion-select>`, 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(`<ion-select label="Label" helper-text="Helper text"></ion-select>`, 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( | ||
`<ion-select label="Label" helper-text="Helper text helper text helper text helper text helper text helper text helper text helper text helper text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" label-placement="stacked" helper-text="Helper text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" class="ion-invalid ion-touched" error-text="Error text"></ion-select>`, | ||
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( | ||
`<ion-select label="Label" class="ion-invalid ion-touched" error-text="Error text" label-placement="stacked"></ion-select>`, | ||
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( | ||
` | ||
<style> | ||
ion-select.custom-select::part(supporting-text) { | ||
font-size: 20px; | ||
} | ||
ion-select.custom-select::part(helper-text) { | ||
color: green; | ||
} | ||
</style> | ||
<ion-select label="Label" class="custom-select" helper-text="Helper text"></ion-select> | ||
`, | ||
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( | ||
` | ||
<style> | ||
ion-select.custom-select::part(supporting-text) { | ||
font-size: 20px; | ||
} | ||
ion-select.custom-select::part(error-text) { | ||
color: purple; | ||
} | ||
</style> | ||
<ion-select label="Label" class="ion-invalid ion-touched custom-select" error-text="Error text"></ion-select> | ||
`, | ||
config | ||
); | ||
|
||
const errorText = page.locator('ion-select'); | ||
await expect(errorText).toHaveScreenshot(screenshot(`select-error-text-custom`)); | ||
}); | ||
}); | ||
}); |