mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
test(radio-group): add e2e test for supporting text
This commit is contained in:
174
core/src/components/radio-group/test/supporting-text/index.html
Normal file
174
core/src/components/radio-group/test/supporting-text/index.html
Normal file
@@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Radio Group - Supporting Text</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(3, minmax(200px, 1fr));
|
||||
grid-row-gap: 20px;
|
||||
grid-column-gap: 20px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
|
||||
color: #6f7378;
|
||||
|
||||
margin-top: 10px;
|
||||
}
|
||||
ion-radio {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Radio Group - Supporting Text</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content id="content" class="ion-padding">
|
||||
<div class="grid">
|
||||
<div class="grid-item">
|
||||
<h2>No Supporting Text</h2>
|
||||
<ion-radio-group value="1">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
<ion-radio value="4">Label</ion-radio>
|
||||
<ion-radio value="5">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Helper Text</h2>
|
||||
<ion-radio-group value="1" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
<ion-radio value="4">Label</ion-radio>
|
||||
<ion-radio value="5">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Error Text</h2>
|
||||
<ion-radio-group
|
||||
value="1"
|
||||
helper-text="Helper text"
|
||||
error-text="Error text"
|
||||
class="ion-invalid ion-touched"
|
||||
>
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
<ion-radio value="4">Label</ion-radio>
|
||||
<ion-radio value="5">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<ion-list>
|
||||
<ion-list-header>List</ion-list-header>
|
||||
<ion-radio-group value="1">
|
||||
<ion-item>
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="4">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="5">Label</ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<ion-list>
|
||||
<ion-list-header>Supporting Text: List</ion-list-header>
|
||||
<ion-radio-group value="1" helper-text="Helper text" error-text="Error text">
|
||||
<ion-item>
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="4">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="5">Label</ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<ion-list>
|
||||
<ion-list-header>Error Text: List</ion-list-header>
|
||||
<ion-radio-group
|
||||
value="1"
|
||||
helper-text="Helper text"
|
||||
error-text="Error text"
|
||||
class="ion-invalid ion-touched"
|
||||
>
|
||||
<ion-item>
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="4">Label</ion-radio>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-radio value="5">Label</ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button onclick="toggleValid()" class="expand">Toggle error</button>
|
||||
|
||||
<script>
|
||||
const radioGroups = document.querySelectorAll('ion-radio-group[helper-text]');
|
||||
|
||||
function toggleValid() {
|
||||
radioGroups.forEach((radioGroup) => {
|
||||
radioGroup.classList.toggle('ion-invalid');
|
||||
radioGroup.classList.toggle('ion-touched');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,247 @@
|
||||
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('radio group: supporting text functionality'), () => {
|
||||
test('should not render bottom content if no hint is enabled', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const bottomEl = page.locator('ion-radio-group .radio-bottom');
|
||||
await expect(bottomEl).toHaveCount(0);
|
||||
});
|
||||
test('helper text should be visible initially', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const helperText = page.locator('ion-radio-group .helper-text');
|
||||
const errorText = page.locator('ion-radio-group .error-text');
|
||||
await expect(helperText).toBeVisible();
|
||||
await expect(helperText).toHaveText('Helper text');
|
||||
await expect(errorText).toBeHidden();
|
||||
});
|
||||
test('radio group should have an aria-describedby attribute when helper text is present', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
const helperText = page.locator('ion-radio-group .helper-text');
|
||||
const helperTextId = await helperText.getAttribute('id');
|
||||
const ariaDescribedBy = await radioGroup.getAttribute('aria-describedby');
|
||||
|
||||
expect(ariaDescribedBy).toBe(helperTextId);
|
||||
});
|
||||
test('error text should be visible when radio group is invalid', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" class="ion-invalid ion-touched" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const helperText = page.locator('ion-radio-group .helper-text');
|
||||
const errorText = page.locator('ion-radio-group .error-text');
|
||||
await expect(helperText).toBeHidden();
|
||||
await expect(errorText).toBeVisible();
|
||||
await expect(errorText).toHaveText('Error text');
|
||||
});
|
||||
|
||||
test('radio group should have an aria-describedby attribute when error text is present', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" class="ion-invalid ion-touched" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
const errorText = page.locator('ion-radio-group .error-text');
|
||||
const errorTextId = await errorText.getAttribute('id');
|
||||
const ariaDescribedBy = await radioGroup.getAttribute('aria-describedby');
|
||||
|
||||
expect(ariaDescribedBy).toBe(errorTextId);
|
||||
});
|
||||
test('radio group should have aria-invalid attribute when radio group is invalid', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" class="ion-invalid ion-touched" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
|
||||
await expect(radioGroup).toHaveAttribute('aria-invalid');
|
||||
});
|
||||
test('radio group should not have aria-invalid attribute when radio group is valid', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" helper-text="Helper text" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
|
||||
await expect(radioGroup).not.toHaveAttribute('aria-invalid');
|
||||
});
|
||||
test('radio group should not have aria-describedby attribute when no hint or error text is present', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
|
||||
await expect(radioGroup).not.toHaveAttribute('aria-describedby');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Rendering is different across modes
|
||||
*/
|
||||
configs({ modes: ['ios', 'md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('radio-group: supporting text rendering'), () => {
|
||||
test('should not have visual regressions when rendering helper text', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" helper-text="Helper text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
await expect(radioGroup).toHaveScreenshot(screenshot(`radio-group-helper-text`));
|
||||
});
|
||||
|
||||
test('should not have visual regressions when rendering error text', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-radio-group value="1" class="ion-invalid ion-touched" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
await expect(radioGroup).toHaveScreenshot(screenshot(`radio-group-error-text`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Customizing supporting text is the same across modes and directions
|
||||
*/
|
||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('radio group: supporting text customization'), () => {
|
||||
test('should not have visual regressions when rendering helper text with custom css', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<style>
|
||||
.supporting-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.helper-text {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-radio-group value="1" helper-text="Helper text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
await expect(radioGroup).toHaveScreenshot(screenshot(`radio-group-helper-text-custom-css`));
|
||||
});
|
||||
test('should not have visual regressions when rendering error text with custom css', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<style>
|
||||
.supporting-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: purple;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ion-radio-group value="1" class="ion-invalid ion-touched" error-text="Error text">
|
||||
<ion-radio value="1">Label</ion-radio>
|
||||
<ion-radio value="2">Label</ion-radio>
|
||||
<ion-radio value="3">Label</ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const radioGroup = page.locator('ion-radio-group');
|
||||
await expect(radioGroup).toHaveScreenshot(screenshot(`radio-group-error-text-custom-css`));
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user