test(alert): migrate to generator (#27247)

Issue number: N/A

---------

This PR migrates the alert tests to use the generator infrastructure.

In
91ba3a1290
I migrated the basic test to use [Playwright
Fixtures](https://playwright.dev/docs/test-fixtures#creating-a-fixture)
instead since it is a) a best practice and b) easier to add the
generator support to.
This commit is contained in:
Liam DeBeasi
2023-04-26 16:01:28 -04:00
committed by GitHub
parent ff7e3740ad
commit 37aa7e9bdb
118 changed files with 295 additions and 261 deletions

View File

@@ -1,63 +0,0 @@
import AxeBuilder from '@axe-core/playwright';
import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
const testAria = async (
page: E2EPage,
buttonID: string,
expectedAriaLabelledBy: string | null,
expectedAriaDescribedBy: string | null
) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
const button = page.locator(`#${buttonID}`);
await button.click();
await didPresent.next();
const alert = page.locator('ion-alert');
/**
* expect().toHaveAttribute() can't check for a null value, so grab and check
* the values manually instead.
*/
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
const ariaDescribedBy = await alert.getAttribute('aria-describedby');
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
expect(ariaDescribedBy).toBe(expectedAriaDescribedBy);
};
test.describe('alert: a11y', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/a11y`);
});
test('should not have accessibility violations when header and message are defined', async ({ page }) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
const button = page.locator('#bothHeaders');
await button.click();
await didPresent.next();
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
test('should have aria-labelledby when header is set', async ({ page }) => {
await testAria(page, 'noMessage', 'alert-1-hdr', null);
});
test('should have aria-describedby when message is set', async ({ page }) => {
await testAria(page, 'noHeaders', null, 'alert-1-msg');
});
test('should fall back to subHeader for aria-labelledby if header is not defined', async ({ page }) => {
await testAria(page, 'subHeaderOnly', 'alert-1-sub-hdr', 'alert-1-msg');
});
test('should allow for manually specifying aria attributes', async ({ page }) => {
await testAria(page, 'customAria', 'Custom title', 'Custom description');
});
});

View File

@@ -0,0 +1,63 @@
import AxeBuilder from '@axe-core/playwright';
import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { configs, test } from '@utils/test/playwright';
const testAria = async (
page: E2EPage,
buttonID: string,
expectedAriaLabelledBy: string | null,
expectedAriaDescribedBy: string | null
) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
const button = page.locator(`#${buttonID}`);
await button.click();
await didPresent.next();
const alert = page.locator('ion-alert');
/**
* expect().toHaveAttribute() can't check for a null value, so grab and check
* the values manually instead.
*/
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
const ariaDescribedBy = await alert.getAttribute('aria-describedby');
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
expect(ariaDescribedBy).toBe(expectedAriaDescribedBy);
};
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('alert: a11y'), () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/src/components/alert/test/a11y`, config);
});
test('should not have accessibility violations when header and message are defined', async ({ page }) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
const button = page.locator('#bothHeaders');
await button.click();
await didPresent.next();
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
test('should have aria-labelledby when header is set', async ({ page }) => {
await testAria(page, 'noMessage', 'alert-1-hdr', null);
});
test('should have aria-describedby when message is set', async ({ page }) => {
await testAria(page, 'noHeaders', null, 'alert-1-msg');
});
test('should fall back to subHeader for aria-labelledby if header is not defined', async ({ page }) => {
await testAria(page, 'subHeaderOnly', 'alert-1-sub-hdr', 'alert-1-msg');
});
test('should allow for manually specifying aria attributes', async ({ page }) => {
await testAria(page, 'customAria', 'Custom title', 'Custom description');
});
});
});

View File

@@ -1,113 +0,0 @@
import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
const openAlert = async (page: E2EPage, buttonID: string) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
await page.click(`#${buttonID}`);
await didPresent.next();
return page.locator('ion-alert');
};
const testAlert = async (page: E2EPage, buttonID: string) => {
await page.goto(`/src/components/alert/test/basic`);
const didDismiss = await page.spyOnEvent('ionAlertDidDismiss');
const alert = await openAlert(page, buttonID);
await expect(alert).toBeVisible();
await expect(alert).toHaveScreenshot(`alert-${buttonID}-${page.getSnapshotSettings()}.png`);
await alert.evaluate((el: HTMLIonAlertElement) => el.dismiss());
await didDismiss.next();
await expect(alert).toHaveCount(0);
};
test.describe('alert: basic', () => {
test('focus trap should work correctly', async ({ page, skip, browserName }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/basic`);
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
const alert = await openAlert(page, 'multipleButtons');
const alertBtns = alert.locator('button');
await page.keyboard.press(tabKey);
await expect(alertBtns.nth(0)).toBeFocused();
await page.keyboard.press(`Shift+${tabKey}`);
await expect(alertBtns.nth(2)).toBeFocused();
await page.keyboard.press(tabKey);
await expect(alertBtns.nth(0)).toBeFocused();
});
test('should set custom attributes', async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/basic`);
const alert = await openAlert(page, 'basic');
await expect(alert).toHaveAttribute('data-testid', 'basic-alert');
});
test('should dismiss when async handler resolves', async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/basic`);
const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent');
const ionAlertDidDismiss = await page.spyOnEvent('ionAlertDidDismiss');
const ionLoadingDidDismiss = await page.spyOnEvent('ionLoadingDidDismiss');
const alert = page.locator('ion-alert');
await page.click('#asyncHandler');
await ionAlertDidPresent.next();
await page.click('.alert-button');
await expect(alert).toBeVisible();
await ionLoadingDidDismiss.next();
await ionAlertDidDismiss.next();
await expect(alert).toBeHidden();
});
test.describe('should not have visual regressions', () => {
test('header, subheader, message', async ({ page }) => {
await testAlert(page, 'basic');
});
test('long message', async ({ page }) => {
await testAlert(page, 'longMessage');
});
test('more than two buttons', async ({ page }) => {
await testAlert(page, 'multipleButtons');
});
test('no message', async ({ page }) => {
await testAlert(page, 'noMessage');
});
test('two buttons', async ({ page }) => {
await testAlert(page, 'confirm');
});
test('form prompt', async ({ page }) => {
await testAlert(page, 'prompt');
});
test('radios', async ({ page }) => {
await testAlert(page, 'radio');
});
test('checkboxes', async ({ page }) => {
await testAlert(page, 'checkbox');
});
});
});

View File

@@ -0,0 +1,147 @@
import { expect } from '@playwright/test';
import type { Locator } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { configs, test } from '@utils/test/playwright';
configs({ directions: ['ltr'] }).forEach(({ config, screenshot, title }) => {
test.describe(title('alert: basic'), () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/alert/test/basic', config);
});
test('focus trap should work correctly', async ({ page, browserName }) => {
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
const alertFixture = new AlertFixture(page, screenshot);
const alert = await alertFixture.open('#multipleButtons');
const alertBtns = alert.locator('button');
await page.keyboard.press(tabKey);
await expect(alertBtns.nth(0)).toBeFocused();
await page.keyboard.press(`Shift+${tabKey}`);
await expect(alertBtns.nth(2)).toBeFocused();
await page.keyboard.press(tabKey);
await expect(alertBtns.nth(0)).toBeFocused();
});
test('should set custom attributes', async ({ page }) => {
const alertFixture = new AlertFixture(page, screenshot);
const alert = await alertFixture.open('#basic');
await expect(alert).toHaveAttribute('data-testid', 'basic-alert');
});
test('should dismiss when async handler resolves', async ({ page }) => {
const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent');
const ionAlertDidDismiss = await page.spyOnEvent('ionAlertDidDismiss');
const ionLoadingDidDismiss = await page.spyOnEvent('ionLoadingDidDismiss');
const alert = page.locator('ion-alert');
await page.click('#asyncHandler');
await ionAlertDidPresent.next();
await page.click('.alert-button');
await expect(alert).toBeVisible();
await ionLoadingDidDismiss.next();
await ionAlertDidDismiss.next();
await expect(alert).toBeHidden();
});
});
});
configs().forEach(({ config, screenshot, title }) => {
test.describe(title('should not have visual regressions'), () => {
let alertFixture!: AlertFixture;
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/alert/test/basic', config);
alertFixture = new AlertFixture(page, screenshot);
});
test('header, subheader, message', async () => {
await alertFixture.open('#basic');
await alertFixture.screenshot('basic');
});
test('long message', async () => {
await alertFixture.open('#longMessage');
await alertFixture.screenshot('longMessage');
});
test('more than two buttons', async () => {
await alertFixture.open('#multipleButtons');
await alertFixture.screenshot('multipleButtons');
});
test('no message', async () => {
await alertFixture.open('#noMessage');
await alertFixture.screenshot('noMessage');
});
test('two buttons', async () => {
await alertFixture.open('#confirm');
await alertFixture.screenshot('confirm');
});
test('form prompt', async () => {
await alertFixture.open('#prompt');
await alertFixture.screenshot('prompt');
});
test('radios', async () => {
await alertFixture.open('#radio');
await alertFixture.screenshot('radio');
});
test('checkboxes', async () => {
await alertFixture.open('#checkbox');
await alertFixture.screenshot('checkbox');
});
});
});
class AlertFixture {
readonly page: E2EPage;
readonly screenshotFn?: (file: string) => string;
private alert!: Locator;
constructor(page: E2EPage, screenshot?: (file: string) => string) {
this.page = page;
this.screenshotFn = screenshot;
}
async open(selector: string) {
const ionAlertDidPresent = await this.page.spyOnEvent('ionAlertDidPresent');
await this.page.locator(selector).click();
await ionAlertDidPresent.next();
this.alert = this.page.locator('ion-alert');
await expect(this.alert).toBeVisible();
return this.alert;
}
async dismiss() {
const ionAlertDidDismiss = await this.page.spyOnEvent('ionAlertDidDismiss');
await this.alert.evaluate((el: HTMLIonAlertElement) => el.dismiss());
await ionAlertDidDismiss.next();
await expect(this.alert).not.toBeVisible();
}
async screenshot(modifier: string) {
const { screenshotFn } = this;
if (!screenshotFn) {
throw new Error(
'A screenshot function is required to take a screenshot. Pass one in when creating ActionSheetFixture.'
);
}
await expect(this.alert).toHaveScreenshot(screenshotFn(`alert-${modifier}`));
}
}

Some files were not shown because too many files have changed in this diff Show More