test(action-sheet): migrate to generator (#27246)

Issue number: N/A

---------

This PR migrates the action sheet tests to use the generator
infrastructure.
This commit is contained in:
Liam DeBeasi
2023-04-26 16:38:45 -04:00
committed by GitHub
parent 37aa7e9bdb
commit a667b3e5b3
72 changed files with 203 additions and 177 deletions

View File

@@ -1,57 +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) => {
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const button = page.locator(`#${buttonID}`);
await button.click();
await didPresent.next();
const alert = page.locator('ion-action-sheet');
/**
* expect().toHaveAttribute() can't check for a null value, so grab and check
* the value manually instead.
*/
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
};
test.describe('action-sheet: a11y', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/action-sheet/test/a11y`);
});
test('should not have accessibility violations when header is defined', async ({ page }) => {
const button = page.locator('#bothHeaders');
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
await button.click();
await didPresent.next();
/**
* action-sheet overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the backdrop.
*/
const results = await new AxeBuilder({ page }).disableRules('color-contrast').analyze();
expect(results.violations).toEqual([]);
});
test('should have aria-labelledby when header is set', async ({ page }) => {
await testAria(page, 'bothHeaders', 'action-sheet-1-header');
});
test('should not have aria-labelledby when header is not set', async ({ page }) => {
await testAria(page, 'noHeaders', null);
});
test('should allow for manually specifying aria attributes', async ({ page }) => {
await testAria(page, 'customAria', 'Custom title');
});
});

View File

@@ -0,0 +1,56 @@
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) => {
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const button = page.locator(`#${buttonID}`);
await button.click();
await didPresent.next();
const alert = page.locator('ion-action-sheet');
/**
* expect().toHaveAttribute() can't check for a null value, so grab and check
* the value manually instead.
*/
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
};
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('action-sheet: a11y'), () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/src/components/action-sheet/test/a11y`, config);
});
test('should not have accessibility violations when header is defined', async ({ page }) => {
const button = page.locator('#bothHeaders');
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
await button.click();
await didPresent.next();
/**
* action-sheet overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the backdrop.
*/
const results = await new AxeBuilder({ page }).disableRules('color-contrast').analyze();
expect(results.violations).toEqual([]);
});
test('should have aria-labelledby when header is set', async ({ page }) => {
await testAria(page, 'bothHeaders', 'action-sheet-1-header');
});
test('should not have aria-labelledby when header is not set', async ({ page }) => {
await testAria(page, 'noHeaders', null);
});
test('should allow for manually specifying aria attributes', async ({ page }) => {
await testAria(page, 'customAria', 'Custom title');
});
});
});

View File

@@ -1,17 +1,17 @@
import { expect } from '@playwright/test';
import type { Locator } from '@playwright/test';
import { test } from '@utils/test/playwright';
import { configs, test } from '@utils/test/playwright';
import type { E2EPage } from '@utils/test/playwright';
test.describe('action sheet: basic', () => {
let actionSheetFixture: ActionSheetFixture;
test.beforeEach(async ({ page }) => {
await page.goto(`/src/components/action-sheet/test/basic`);
actionSheetFixture = new ActionSheetFixture(page);
});
test.describe('action sheet: data', () => {
test('should return data', async ({ page, skip }) => {
skip.rtl();
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('action sheet: data'), () => {
let actionSheetFixture!: ActionSheetFixture;
test.beforeEach(async ({ page }) => {
actionSheetFixture = new ActionSheetFixture(page);
await page.goto(`/src/components/action-sheet/test/basic`, config);
});
test('should return data', async ({ page }) => {
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
await actionSheetFixture.open('#buttonData');
@@ -22,8 +22,7 @@ test.describe('action sheet: basic', () => {
await ionActionSheetDidDismiss.next();
expect(ionActionSheetDidDismiss).toHaveReceivedEventDetail({ data: { type: '1' }, role: undefined });
});
test('should return cancel button data', async ({ page, skip }) => {
skip.rtl();
test('should return cancel button data', async ({ page }) => {
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
await actionSheetFixture.open('#buttonData');
@@ -35,16 +34,28 @@ test.describe('action sheet: basic', () => {
expect(ionActionSheetDidDismiss).toHaveReceivedEventDetail({ data: { type: 'cancel' }, role: 'cancel' });
});
});
test.describe('action sheet: attributes', () => {
test('should set htmlAttributes', async ({ page, skip }) => {
skip.rtl();
});
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('action sheet: attributes'), () => {
test('should set htmlAttributes', async ({ page }) => {
await page.goto(`/src/components/action-sheet/test/basic`, config);
const actionSheetFixture = new ActionSheetFixture(page);
await actionSheetFixture.open('#basic');
const actionSheet = page.locator('ion-action-sheet');
await expect(actionSheet).toHaveAttribute('data-testid', 'basic-action-sheet');
});
});
test.describe('action sheet: variants', () => {
});
configs().forEach(({ config, screenshot, title }) => {
test.describe(title('action sheet: variant rendering'), () => {
let actionSheetFixture!: ActionSheetFixture;
test.beforeEach(async ({ page }) => {
actionSheetFixture = new ActionSheetFixture(page, screenshot);
await page.goto(`/src/components/action-sheet/test/basic`, config);
});
test('should open basic action sheet', async () => {
await actionSheetFixture.open('#basic');
await actionSheetFixture.screenshot('basic');
@@ -73,15 +84,23 @@ test.describe('action sheet: basic', () => {
await actionSheetFixture.open('#scrollWithoutCancel');
await actionSheetFixture.screenshot('scroll-without-cancel');
});
test('should open custom backdrop action sheet', async ({ page, skip }) => {
skip.rtl();
});
});
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('action sheet: variant functionality'), () => {
let actionSheetFixture!: ActionSheetFixture;
test.beforeEach(async ({ page }) => {
actionSheetFixture = new ActionSheetFixture(page);
await page.goto(`/src/components/action-sheet/test/basic`, config);
});
test('should open custom backdrop action sheet', async ({ page }) => {
await actionSheetFixture.open('#customBackdrop');
const backdrop = page.locator('ion-action-sheet ion-backdrop');
await expect(backdrop).toHaveCSS('opacity', '1');
});
test('should open alert from action sheet', async ({ page, skip }) => {
skip.rtl();
test('should open alert from action sheet', async ({ page }) => {
const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent');
await actionSheetFixture.open('#alertFromActionSheet');
@@ -89,8 +108,7 @@ test.describe('action sheet: basic', () => {
await ionAlertDidPresent.next();
});
test('should not dismiss action sheet when backdropDismiss: false', async ({ page, skip }) => {
skip.rtl();
test('should not dismiss action sheet when backdropDismiss: false', async ({ page }) => {
await actionSheetFixture.open('#noBackdropDismiss');
const actionSheet = page.locator('ion-action-sheet');
@@ -99,9 +117,13 @@ test.describe('action sheet: basic', () => {
await expect(actionSheet).toBeVisible();
});
});
test.describe('action sheet: focus trap', () => {
test('it should trap focus in action sheet', async ({ page, skip, browserName }) => {
skip.rtl();
});
configs({ directions: ['ltr'] }).forEach(({ config, title }) => {
test.describe(title('action sheet: focus trap'), () => {
test('it should trap focus in action sheet', async ({ page, browserName }) => {
await page.goto(`/src/components/action-sheet/test/basic`, config);
const actionSheetFixture = new ActionSheetFixture(page);
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
await actionSheetFixture.open('#basic');
@@ -121,11 +143,13 @@ test.describe('action sheet: basic', () => {
class ActionSheetFixture {
readonly page: E2EPage;
readonly screenshotFn?: (file: string) => string;
private actionSheet!: Locator;
constructor(page: E2EPage) {
constructor(page: E2EPage, screenshot?: (file: string) => string) {
this.page = page;
this.screenshotFn = screenshot;
}
async open(selector: string) {
@@ -144,8 +168,14 @@ class ActionSheetFixture {
}
async screenshot(modifier: string) {
await expect(this.actionSheet).toHaveScreenshot(
`action-sheet-${modifier}-diff-${this.page.getSnapshotSettings()}.png`
);
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.actionSheet).toHaveScreenshot(screenshotFn(`action-sheet-${modifier}-diff`));
}
}

View File

@@ -1,35 +0,0 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('action sheet: isOpen', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl('isOpen does not behave differently in RTL');
skip.mode('md', 'isOpen does not behave differently in MD');
await page.goto('/src/components/action-sheet/test/is-open');
});
test('should open the action sheet', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const actionSheet = page.locator('ion-action-sheet');
await page.click('#default');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
});
test('should open the action sheet then close after a timeout', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
const actionSheet = page.locator('ion-action-sheet');
await page.click('#timeout');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
await ionActionSheetDidDismiss.next();
await expect(actionSheet).toBeHidden();
});
});

View File

@@ -0,0 +1,34 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ config, title }) => {
test.describe(title('action sheet: isOpen'), () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/action-sheet/test/is-open', config);
});
test('should open the action sheet', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const actionSheet = page.locator('ion-action-sheet');
await page.click('#default');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
});
test('should open the action sheet then close after a timeout', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
const actionSheet = page.locator('ion-action-sheet');
await page.click('#timeout');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
await ionActionSheetDidDismiss.next();
await expect(actionSheet).toBeHidden();
});
});
});

View File

@@ -1,21 +0,0 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('action sheet: translucent', () => {
test('should not have visual regressions', async ({ page, skip }) => {
skip.mode('md', 'Translucent effect is only active on iOS mode');
skip.rtl('This tests how the component is painted, not layout. RTL tests are not needed here');
await page.goto(`/src/components/action-sheet/test/translucent`);
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const basic = page.locator('#basic');
await basic.click();
await ionActionSheetDidPresent.next();
const actionSheet = page.locator('ion-action-sheet');
await expect(actionSheet).toHaveScreenshot(`action-sheet-translucent-${page.getSnapshotSettings()}.png`);
});
});

View File

@@ -0,0 +1,20 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ config, screenshot, title }) => {
test.describe(title('action sheet: translucent'), () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/action-sheet/test/translucent`, config);
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const basic = page.locator('#basic');
await basic.click();
await ionActionSheetDidPresent.next();
const actionSheet = page.locator('ion-action-sheet');
await expect(actionSheet).toHaveScreenshot(screenshot('action-sheet-translucent'));
});
});
});

View File

@@ -1,35 +0,0 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('action sheet: trigger', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl('trigger does not behave differently in RTL');
skip.mode('md');
await page.goto('/src/components/action-sheet/test/trigger');
});
test('should open the action sheet', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const actionSheet = page.locator('#default-action-sheet');
await page.click('#default');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
});
test('should present a previously presented action sheet', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
const actionSheet = page.locator('#timeout-action-sheet');
await page.click('#timeout');
await ionActionSheetDidDismiss.next();
await page.click('#timeout');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
});
});

View File

@@ -0,0 +1,34 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ config, title }) => {
test.describe(title('action sheet: trigger'), () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/action-sheet/test/trigger', config);
});
test('should open the action sheet', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const actionSheet = page.locator('#default-action-sheet');
await page.click('#default');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
});
test('should present a previously presented action sheet', async ({ page }) => {
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
const actionSheet = page.locator('#timeout-action-sheet');
await page.click('#timeout');
await ionActionSheetDidDismiss.next();
await page.click('#timeout');
await ionActionSheetDidPresent.next();
await expect(actionSheet).toBeVisible();
});
});
});