test(textarea): migrate tests to playwright (#25512)
30
core/src/components/textarea/test/a11y/textarea.e2e.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('textarea: a11y', () => {
|
||||
test('does not set a default aria-labelledby when there is not a neighboring ion-label', async ({ page }) => {
|
||||
await page.setContent(`<ion-textarea></ion-textarea>`);
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
const textarea = page.locator('ion-textarea textarea');
|
||||
const ariaLabelledBy = await textarea.getAttribute('aria-labelledby');
|
||||
|
||||
expect(ariaLabelledBy).toBe(null);
|
||||
});
|
||||
|
||||
test('set a default aria-labelledby when a neighboring ion-label exist', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-item>
|
||||
<ion-label>A11y Test</ion-label>
|
||||
<ion-textarea></ion-textarea>
|
||||
</ion-item>
|
||||
`);
|
||||
|
||||
const label = page.locator('ion-label');
|
||||
const textarea = page.locator('ion-textarea textarea');
|
||||
const ariaLabelledBy = await textarea.getAttribute('aria-labelledby');
|
||||
|
||||
expect(ariaLabelledBy).toBe(await label.getAttribute('id'));
|
||||
});
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
import { Item } from '../../../item/item';
|
||||
import { Label } from '../../../label/label';
|
||||
import { Textarea } from '../../textarea';
|
||||
|
||||
describe('Textarea a11y', () => {
|
||||
it('does not set a default aria-labelledby when there is not a neighboring ion-label', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Textarea, Item, Label],
|
||||
html: `<ion-textarea></ion-textarea>`,
|
||||
});
|
||||
|
||||
const ariaLabelledBy = page.body.querySelector('ion-textarea textarea').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: [Textarea, Item, Label],
|
||||
html: `<ion-item>
|
||||
<ion-label>A11y Test</ion-label>
|
||||
<ion-textarea></ion-textarea>
|
||||
</ion-item>`,
|
||||
});
|
||||
|
||||
const label = page.body.querySelector('ion-label');
|
||||
const ariaLabelledBy = page.body.querySelector('ion-textarea textarea').getAttribute('aria-labelledby');
|
||||
expect(ariaLabelledBy).toBe(label.id);
|
||||
});
|
||||
});
|
@ -1,18 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('textarea: autogrow', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/textarea/test/autogrow?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compares = [];
|
||||
|
||||
compares.push(await page.compareScreenshot());
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
compares.push(await page.compareScreenshot('value changed'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
50
core/src/components/textarea/test/autogrow/textarea.e2e.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('textarea: autogrow', () => {
|
||||
test.skip('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/textarea/test/autogrow`);
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(`textarea-autogrow-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
|
||||
test('should grow when typing', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-app>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-textarea auto-grow="true"></ion-textarea>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-app>`
|
||||
);
|
||||
|
||||
const textarea = await page.waitForSelector('ion-textarea');
|
||||
|
||||
await textarea.click();
|
||||
|
||||
await textarea.type('Now, this is a story all about how');
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
expect(await textarea.screenshot()).toMatchSnapshot(`textarea-autogrow-initial-${page.getSnapshotSettings()}.png`);
|
||||
|
||||
await textarea.type(
|
||||
[
|
||||
`\nMy life got flipped-turned upside down`,
|
||||
`And I'd like to take a minute`,
|
||||
`Just sit right there`,
|
||||
`I'll tell you how I became the prince of a town called Bel-Air`,
|
||||
].join('\n')
|
||||
);
|
||||
|
||||
expect(await textarea.screenshot()).toMatchSnapshot(`textarea-autogrow-after-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 8.1 KiB |
@ -1,18 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('textarea: basic', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/textarea/test/basic?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compares = [];
|
||||
|
||||
compares.push(await page.compareScreenshot());
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
compares.push(await page.compareScreenshot('value changed'));
|
||||
|
||||
for (const compare of compares) {
|
||||
expect(compare).toMatchScreenshot();
|
||||
}
|
||||
});
|
@ -45,7 +45,7 @@
|
||||
|
||||
<ion-item>
|
||||
<ion-label color="primary" position="floating">Floating Label</ion-label>
|
||||
<ion-textarea id="timeout"></ion-textarea>
|
||||
<ion-textarea></ion-textarea>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
@ -68,10 +68,11 @@
|
||||
<ion-textarea clear-on-edit="true"></ion-textarea>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<!-- TODO: Re-add auto grow with PR#24205 -->
|
||||
<!-- <ion-item>
|
||||
<ion-label color="primary">Autogrow</ion-label>
|
||||
<ion-textarea auto-grow="true"></ion-textarea>
|
||||
</ion-item>
|
||||
</ion-item> -->
|
||||
</ion-list>
|
||||
|
||||
<div class="ion-text-center">
|
||||
@ -88,11 +89,6 @@
|
||||
</ion-content>
|
||||
|
||||
<script>
|
||||
var textarea = document.getElementById('timeout');
|
||||
setTimeout(() => {
|
||||
textarea.value = 'timeout';
|
||||
}, 1000);
|
||||
|
||||
function toggleBoolean(id, prop) {
|
||||
var el = document.getElementById(id);
|
||||
|
||||
|
51
core/src/components/textarea/test/basic/textarea.e2e.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('textarea: basic', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/textarea/test/basic`);
|
||||
|
||||
/**
|
||||
* The auto grow implementation uses a requestAnimationFrame to append styles to the textarea
|
||||
* on load. We need to wait for changes otherwise the screenshot can be taken before the
|
||||
* styles are applied.
|
||||
*/
|
||||
await page.waitForChanges();
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(`textarea-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
|
||||
test.describe('with floating labels', () => {
|
||||
/**
|
||||
* Verifies the display of a floating label above an `ion-textarea`.
|
||||
* Captures a screenshot of the initial state (without a value) and verifies
|
||||
* that the label translates correctly after the value is set.
|
||||
*/
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-item>
|
||||
<ion-label position="floating">Floating Label</ion-label>
|
||||
<ion-textarea></ion-textarea>
|
||||
</ion-item>`);
|
||||
|
||||
const item = page.locator('ion-item');
|
||||
const textarea = page.locator('ion-textarea');
|
||||
|
||||
expect(await item.screenshot()).toMatchSnapshot(
|
||||
`textarea-floating-label-initial-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
|
||||
await textarea.evaluate((el: HTMLIonTextareaElement) => {
|
||||
el.value = 'Updated value';
|
||||
});
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
expect(await item.screenshot()).toMatchSnapshot(`textarea-floating-label-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 6.3 KiB |
@ -1,10 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('textarea: standalone', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/textarea/test/standalone?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const compare = await page.compareScreenshot();
|
||||
expect(compare).toMatchScreenshot();
|
||||
});
|
@ -21,7 +21,7 @@
|
||||
<ion-textarea value="thus shuld git spellchuk" spellcheck="true"></ion-textarea>
|
||||
<ion-textarea value="thus shuld NOT git spellchuk" spellcheck="false"></ion-textarea>
|
||||
<ion-textarea placeholder="Custom" class="custom"></ion-textarea>
|
||||
<ion-textarea id="nowrap" rows="15"></ion-textarea>
|
||||
<ion-textarea id="ascii" rows="15"></ion-textarea>
|
||||
<ion-textarea placeholder="Auto Grow!" auto-grow="true"></ion-textarea>
|
||||
|
||||
<style>
|
||||
@ -30,17 +30,17 @@
|
||||
--color: blue;
|
||||
}
|
||||
|
||||
#nowrap {
|
||||
#ascii {
|
||||
font-size: 8px;
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
|
||||
white-space: nowrap;
|
||||
white-space: pre;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var textarea = document.querySelector('#nowrap');
|
||||
var textarea = document.querySelector('#ascii');
|
||||
|
||||
textarea.value = `@@@@@@@////////////////@@@(/#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@/////@@@@@@@@@@@@@@@///////@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
15
core/src/components/textarea/test/standalone/textarea.e2e.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('textarea: standalone', () => {
|
||||
/**
|
||||
* Verifies `ion-textarea` visual display when used outside of an `ion-app` component.
|
||||
*/
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/textarea/test/standalone`);
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(`textarea-standalone-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 69 KiB |