test(toast): migrate tests to playwright (#25751)

This commit is contained in:
Liam DeBeasi
2022-08-12 10:54:25 -05:00
committed by GitHub
parent d7116581c8
commit f47c5de1e6
71 changed files with 198 additions and 214 deletions

View File

@ -1,44 +0,0 @@
import { AxePuppeteer } from '@axe-core/puppeteer';
import { newE2EPage } from '@stencil/core/testing';
describe('toast accessibility tests', () => {
test('it should not have any axe violations with polite toasts', async () => {
const page = await newE2EPage({
url: '/src/components/toast/test/a11y?ionic:_testing=true',
});
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
await page.click('#polite');
await ionToastDidPresent.next();
/**
* IonToast overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the toast.
*/
const results = await new AxePuppeteer(page).disableRules('color-contrast').analyze();
expect(results.violations.length).toEqual(0);
});
test('it should not have any axe violations with assertive toasts', async () => {
const page = await newE2EPage({
url: '/src/components/toast/test/a11y?ionic:_testing=true',
});
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
await page.click('#assertive');
await ionToastDidPresent.next();
/**
* IonToast overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the toast.
*/
const results = await new AxePuppeteer(page).disableRules('color-contrast').analyze();
expect(results.violations.length).toEqual(0);
});
});

View File

@ -0,0 +1,42 @@
import AxeBuilder from '@axe-core/playwright';
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('toast: a11y', () => {
test.beforeEach(async ({ page }, testInfo) => {
test.skip(testInfo.project.metadata.rtl === true, 'This test does not check LTR vs RTL layouts');
await page.goto(`/src/components/toast/test/a11y`);
});
test('should not have any axe violations with polite toasts', async ({ page }) => {
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
const politeButton = page.locator('#polite');
await politeButton.click();
await ionToastDidPresent.next();
/**
* IonToast overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the toast.
*/
const results = await new AxeBuilder({ page }).disableRules('color-contrast').analyze();
expect(results.violations).toEqual([]);
});
test('should not have any axe violations with assertive toasts', async ({ page }) => {
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
const politeButton = page.locator('#assertive');
await politeButton.click();
await ionToastDidPresent.next();
/**
* IonToast overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the toast.
*/
const results = await new AxeBuilder({ page }).disableRules('color-contrast').analyze();
expect(results.violations).toEqual([]);
});
});

View File

@ -1,123 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
import { testToast } from '../test.utils';
const DIRECTORY = 'basic';
test('toast: basic, bottom', async () => {
await testToast(DIRECTORY, '#show-bottom-toast');
});
test('toast: basic, middle', async () => {
await testToast(DIRECTORY, '#show-middle-toast');
});
test('toast: basic, top', async () => {
await testToast(DIRECTORY, '#show-top-toast');
});
test('toast: basic, two lines', async () => {
await testToast(DIRECTORY, '#two-line-toast');
});
test('toast: basic, close button', async () => {
await testToast(DIRECTORY, '#close-button-toast');
});
test('toast: basic, custom close text', async () => {
await testToast(DIRECTORY, '#custom-close-text-toast');
});
test('toast: basic, custom buttons', async () => {
await testToast(DIRECTORY, '#custom-action-buttons-toast');
});
test('toast: basic, translucent', async () => {
await testToast(DIRECTORY, '#translucent-toast');
});
test('toast: basic, color', async () => {
await testToast(DIRECTORY, '#color-toast');
});
test('toast: basic, custom class', async () => {
await testToast(DIRECTORY, '#custom-class-toast');
});
test('toast: start end position', async () => {
await testToast(DIRECTORY, '#toast-start-and-end');
});
test('toast: html', async () => {
await testToast(DIRECTORY, '#toast-html');
});
/**
* RTL Tests
*/
test('toast:rtl: basic, bottom', async () => {
await testToast(DIRECTORY, '#show-bottom-toast', true);
});
test('toast:rtl: basic, middle', async () => {
await testToast(DIRECTORY, '#show-middle-toast', true);
});
test('toast:rtl: basic, top', async () => {
await testToast(DIRECTORY, '#show-top-toast', true);
});
test('toast:rtl: basic, two lines', async () => {
await testToast(DIRECTORY, '#two-line-toast', true);
});
test('toast:rtl: basic, close button', async () => {
await testToast(DIRECTORY, '#close-button-toast', true);
});
test('toast:rtl: basic, custom close text', async () => {
await testToast(DIRECTORY, '#custom-close-text-toast', true);
});
test('toast:rtl: basic, custom buttons', async () => {
await testToast(DIRECTORY, '#custom-action-buttons-toast');
});
test('toast:rtl: basic, translucent', async () => {
await testToast(DIRECTORY, '#translucent-toast', true);
});
test('toast:rtl: basic, color', async () => {
await testToast(DIRECTORY, '#color-toast', true);
});
test('toast:rtl: basic, custom class', async () => {
await testToast(DIRECTORY, '#custom-class-toast', true);
});
test('toast:rtl: start end position', async () => {
await testToast(DIRECTORY, '#toast-start-and-end', true);
});
test('toast:rtl: html', async () => {
await testToast(DIRECTORY, '#toast-html', true);
});
// Attributes
test('toast: htmlAttributes', async () => {
const page = await newE2EPage({ url: '/src/components/toast/test/basic?ionic:_testing=true' });
await page.click('#show-bottom-toast');
await page.waitForSelector('#show-bottom-toast');
const toast = await page.find('ion-toast');
expect(toast).not.toBe(null);
await toast.waitForVisible();
const attribute = await page.evaluate(() => document.querySelector('ion-toast').getAttribute('data-testid'));
expect(attribute).toEqual('basic-toast');
});

View File

@ -67,7 +67,7 @@
<ion-button <ion-button
expand="block" expand="block"
id="two-line-toast" id="two-line-toast"
onclick="openToast({message: 'Two-line message\nwith action.', buttons: ['Action'] })" onclick="openToast({message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum in elit varius, maximus sem in, bibendum justo.', buttons: ['Action'] })"
> >
Long Message Long Message
</ion-button> </ion-button>

View File

@ -0,0 +1,136 @@
import { expect } from '@playwright/test';
import type { Locator, TestInfo } from '@playwright/test';
import type { E2EPage, EventSpy } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
class ToastFixture {
readonly page: E2EPage;
readonly testInfo: TestInfo;
private ionToastDidPresent!: EventSpy;
constructor(page: E2EPage, testInfo: TestInfo) {
this.page = page;
this.testInfo = testInfo;
}
async goto() {
const { page } = this;
await page.goto(`/src/components/toast/test/basic`);
this.ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
}
async openToast(selector: string) {
const { page, ionToastDidPresent } = this;
const button = page.locator(selector);
await button.click();
await ionToastDidPresent.next();
return {
toast: page.locator('ion-toast'),
container: page.locator('ion-toast .toast-container'),
};
}
async screenshot(screenshotModifier: string, el?: Locator) {
const { page } = this;
const reference = el !== undefined ? el : page;
expect(await reference.screenshot()).toMatchSnapshot(
`toast-${screenshotModifier}-${page.getSnapshotSettings()}.png`
);
}
skipRTL(testRef: typeof test, reason = 'This functionality does not have RTL-specific behaviors.') {
const { testInfo } = this;
testRef.skip(testInfo.project.metadata.rtl === true, reason);
}
skipMode(testRef: typeof test, mode: string, reason: string) {
const { testInfo } = this;
testRef.skip(testInfo.project.metadata.mode === mode, reason);
}
}
test.describe('toast: rendering', () => {
let toastFixture: ToastFixture;
test.beforeEach(async ({ page }, testInfo) => {
toastFixture = new ToastFixture(page, testInfo);
await toastFixture.goto();
});
test.describe('toast: position', () => {
test.beforeEach(() => {
toastFixture.skipRTL(test);
});
test('should render toast at the top', async () => {
await toastFixture.openToast('#show-top-toast');
await toastFixture.screenshot('top');
});
test('should render toast at the middle', async () => {
await toastFixture.openToast('#show-middle-toast');
await toastFixture.screenshot('middle');
});
test('should render toast at the bottom', async () => {
await toastFixture.openToast('#show-bottom-toast');
await toastFixture.screenshot('bottom');
});
});
test('should set buttons correctly', async () => {
const { container } = await toastFixture.openToast('#custom-action-buttons-toast');
await toastFixture.screenshot('buttons', container);
});
test('should set start/end positioning correctly', async () => {
const { container } = await toastFixture.openToast('#toast-start-and-end');
await toastFixture.screenshot('start-end', container);
});
test('should wrap text correctly', async () => {
toastFixture.skipRTL(test);
const { container } = await toastFixture.openToast('#two-line-toast');
await toastFixture.screenshot('text', container);
});
test('should set color correctly', async () => {
toastFixture.skipRTL(test);
const { container } = await toastFixture.openToast('#color-toast');
await toastFixture.screenshot('color', container);
});
test('should set translucency correctly', async () => {
toastFixture.skipRTL(test);
toastFixture.skipMode(test, 'md', 'Translucency only works on iOS');
const { container } = await toastFixture.openToast('#translucent-toast');
await toastFixture.screenshot('translucent', container);
});
});
test.describe('toast: properties', () => {
let toastFixture: ToastFixture;
test.beforeEach(async ({ page }, testInfo) => {
toastFixture = new ToastFixture(page, testInfo);
toastFixture.skipMode(test, 'md', 'This functionality has no mode specific logic.');
toastFixture.skipRTL(test);
await toastFixture.goto();
});
test('should correctly set htmlAttributes', async () => {
const { toast } = await toastFixture.openToast('#show-bottom-toast');
await expect(toast).toHaveAttribute('data-testid', 'basic-toast');
});
test('should correctly set custom html', async () => {
const { toast } = await toastFixture.openToast('#toast-html');
await expect(toast.locator('ion-button')).toBeVisible();
});
test('should correctly set custom class', async () => {
const { toast } = await toastFixture.openToast('#custom-class-toast');
await expect(toast).toHaveClass(/my-custom-class/);
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,39 +0,0 @@
import { testToast } from '../test.utils';
const DIRECTORY = 'buttons';
test('toast: buttons, close array', async () => {
await testToast(DIRECTORY, '#closeArray');
});
test('toast: buttons, two buttons', async () => {
await testToast(DIRECTORY, '#twoButtons');
});
test('toast: buttons, multiple buttons', async () => {
await testToast(DIRECTORY, '#multipleButtons');
});
test('toast: buttons, long button', async () => {
await testToast(DIRECTORY, '#longButton');
});
/**
* RTL Tests
*/
test('toast:rtl: buttons, close array', async () => {
await testToast(DIRECTORY, '#closeArray', true);
});
test('toast:rtl: buttons, two buttons', async () => {
await testToast(DIRECTORY, '#twoButtons', true);
});
test('toast:rtl: buttons, multiple buttons', async () => {
await testToast(DIRECTORY, '#multipleButtons', true);
});
test('toast:rtl: buttons, long button', async () => {
await testToast(DIRECTORY, '#longButton', true);
});

View File

@ -1,7 +0,0 @@
import { testToast } from '../test.utils';
const DIRECTORY = 'standalone';
test('toast: standalone', async () => {
await testToast(DIRECTORY, '#basic-toast');
});

View File

@ -0,0 +1,19 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('toast: standalone', () => {
test.beforeEach(async ({ page }, testInfo) => {
test.skip(testInfo.project.metadata.rtl === true, 'This test does not check LTR vs RTL layouts');
await page.goto(`/src/components/toast/test/standalone`);
});
test('should not have visual regressions', async ({ page }) => {
const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
const basicButton = page.locator('#basic-toast');
await basicButton.click();
await ionToastDidPresent.next();
expect(await page.screenshot()).toMatchSnapshot(`toast-standalone-${page.getSnapshotSettings()}.png`);
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB