test(input): migrate tests to playwright (#25597)
38
core/src/components/input/test/a11y/input.e2e.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('input: a11y', () => {
|
||||
test('does not set a default aria-labelledby when there is not a neighboring ion-label', async ({
|
||||
page,
|
||||
}, testInfo) => {
|
||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
||||
|
||||
await page.setContent('<ion-input></ion-input>');
|
||||
|
||||
const input = page.locator('ion-input > input');
|
||||
const ariaLabelledBy = await input.getAttribute('aria-labelledby');
|
||||
|
||||
await expect(ariaLabelledBy).toBe(null);
|
||||
});
|
||||
|
||||
test('set a default aria-labelledby when a neighboring ion-label exists', async ({ page }, testInfo) => {
|
||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
||||
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-item>
|
||||
<ion-label>A11y Test</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
`
|
||||
);
|
||||
|
||||
const label = page.locator('ion-label');
|
||||
const input = page.locator('ion-input > input');
|
||||
|
||||
const ariaLabelledBy = await input.getAttribute('aria-labelledby');
|
||||
const labelId = await label.getAttribute('id');
|
||||
|
||||
await expect(ariaLabelledBy).toBe(labelId);
|
||||
});
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
import { Item } from '../../../item/item';
|
||||
import { Label } from '../../../label/label';
|
||||
import { Input } from '../../input';
|
||||
|
||||
describe('Input a11y', () => {
|
||||
it('does not set a default aria-labelledby when there is not a neighboring ion-label', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Input, Item, Label],
|
||||
html: `<ion-input></ion-input>`,
|
||||
});
|
||||
|
||||
const ariaLabelledBy = page.body.querySelector('ion-input > input').getAttribute('aria-labelledby');
|
||||
expect(ariaLabelledBy).toBe(null);
|
||||
});
|
||||
|
||||
it('set a default aria-labelledby when a neighboring ion-label exists', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Input, Item, Label],
|
||||
html: `<ion-item>
|
||||
<ion-label>A11y Test</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>`,
|
||||
});
|
||||
|
||||
const label = page.body.querySelector('ion-label');
|
||||
const ariaLabelledBy = page.body.querySelector('ion-input > input').getAttribute('aria-labelledby');
|
||||
expect(ariaLabelledBy).toBe(label.id);
|
||||
});
|
||||
});
|
@ -1,62 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('input: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/input/test/basic?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compares = [];
|
||||
|
||||
compares.push(await page.compareScreenshot());
|
||||
|
||||
const fullInput = await page.find('#fullInput');
|
||||
await fullInput.click();
|
||||
|
||||
const fullItem = await page.find('#fullItem');
|
||||
expect(fullItem).toHaveClass('item-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('full input focused'));
|
||||
|
||||
const insetInput = await page.find('#insetInput');
|
||||
await insetInput.click();
|
||||
|
||||
const insetItem = await page.find('#insetItem');
|
||||
expect(insetItem).toHaveClass('item-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('inset input focused'));
|
||||
|
||||
const noneInput = await page.find('#noneInput');
|
||||
await noneInput.click();
|
||||
|
||||
const noneItem = await page.find('#noneItem');
|
||||
expect(noneItem).toHaveClass('item-has-focus');
|
||||
|
||||
compares.push(await page.compareScreenshot('no lines input focused'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
||||
|
||||
test('input: basic should not error on input', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/input/test/basic?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const errors = [];
|
||||
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
errors.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
const inputs = await page.findAll('ion-input');
|
||||
|
||||
for (const input of inputs) {
|
||||
await input.click();
|
||||
await input.type('letters and 12345');
|
||||
}
|
||||
|
||||
expect(errors.length).toEqual(0);
|
||||
});
|
159
core/src/components/input/test/basic/input.e2e.ts
Normal file
@ -0,0 +1,159 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('input: basic', () => {
|
||||
test.describe('input with overflow', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-input value="reallylonglonglonginputtoseetheedgesreallylonglonglonginputtoseetheedges"></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
// Validates the display of an input where text extends off the edge of the component.
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-with-text-overflow-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('input with placeholder', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-input placeholder="Placeholder"></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
// Validates the display of an input with a placeholder.
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-with-placeholder-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('input disabled', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-input value="Input disabled" disabled></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
// Validates the display of an input in a disabled state.
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-disabled-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('input with lines="full"', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item lines="full">
|
||||
<ion-input placeholder="Full"></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
const input = page.locator('ion-input');
|
||||
// Validates the display of an input with an ion-item using lines="full".
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-with-lines-full-${page.getSnapshotSettings()}.png`);
|
||||
|
||||
await input.click();
|
||||
|
||||
// Verifies that the parent item receives .item-has-focus when the input is focused.
|
||||
await expect(item).toHaveClass(/item-has-focus/);
|
||||
// Validates the display of an input with an ion-item using lines="full" when focused.
|
||||
expect(await item.screenshot()).toMatchSnapshot(
|
||||
`input-with-lines-full-focused-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('input with lines="inset"', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item lines="inset">
|
||||
<ion-input placeholder="Inset"></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
const input = page.locator('ion-input');
|
||||
// Validates the display of an input with an ion-item using lines="inset".
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-with-lines-inset-${page.getSnapshotSettings()}.png`);
|
||||
|
||||
await input.click();
|
||||
|
||||
// Verifies that the parent item receives .item-has-focus when the input is focused.
|
||||
await expect(item).toHaveClass(/item-has-focus/);
|
||||
|
||||
// Validates the display of an input with an ion-item using lines="inset" when focused.
|
||||
expect(await item.screenshot()).toMatchSnapshot(
|
||||
`input-with-lines-inset-focused-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('input with lines="none"', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item lines="none">
|
||||
<ion-input placeholder="None"></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
const input = page.locator('ion-input');
|
||||
// Validates the display of an input with an ion-item using lines="none".
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-with-lines-none-${page.getSnapshotSettings()}.png`);
|
||||
|
||||
await input.click();
|
||||
|
||||
// Verifies that the parent item receives .item-has-focus when the input is focused.
|
||||
await expect(item).toHaveClass(/item-has-focus/);
|
||||
|
||||
// Validates the display of an input with an ion-item using lines="none" when focused.
|
||||
expect(await item.screenshot()).toMatchSnapshot(
|
||||
`input-with-lines-none-focused-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('input with clear button', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Clear Input</ion-label>
|
||||
<ion-input
|
||||
clear-input
|
||||
value="reallylonglonglonginputtoseetheedgesreallylonglonglonginputtoseetheedges"
|
||||
></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
`);
|
||||
const item = page.locator('ion-item');
|
||||
// Validates the display of an input with a clear button.
|
||||
expect(await item.screenshot()).toMatchSnapshot(`input-with-clear-button-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 937 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 953 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 917 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 901 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 937 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 953 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 900 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 888 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.4 KiB |