test(modal): migrate to generators (#27331)
Issue number: N/A
---------
<!-- Please refer to our contributing documentation for any questions on
submitting a pull request, or let us know here if you need any help:
https://ionicframework.com/docs/building/contributing -->
<!-- Some docs updates need to be made in the `ionic-docs` repo, in a
separate PR. See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#modifying-documentation
for details. -->
<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->
<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->
Modal tests are using legacy syntax
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- Modal tests use generator syntax
e3e83ef92f
- This had an unused screenshot test, so I removed it
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->
## Other information
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
Note: Some of these tests are quite slow, so you may see a CI slowdown
if this merges. However, I am working on addressing this in
https://github.com/ionic-team/ionic-framework/pull/27397.
@ -1,39 +0,0 @@
|
||||
import AxeBuilder from '@axe-core/playwright';
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('modal: a11y', () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
});
|
||||
|
||||
test('should not have accessibility violations', async ({ page }) => {
|
||||
await page.goto(`/src/components/modal/test/a11y`);
|
||||
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const button = page.locator('#open-modal');
|
||||
const modal = page.locator('ion-modal .modal-wrapper');
|
||||
|
||||
await expect(modal).toHaveAttribute('role', 'dialog');
|
||||
|
||||
await button.click();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const results = await new AxeBuilder({ page }).analyze();
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
|
||||
test('should allow for custom role', async ({ page }) => {
|
||||
/**
|
||||
* Note: This example should not be used in production.
|
||||
* This only serves to check that `role` can be customized.
|
||||
*/
|
||||
await page.setContent(`
|
||||
<ion-modal role="alertdialog"></ion-modal>
|
||||
`);
|
||||
const modal = page.locator('ion-modal .modal-wrapper');
|
||||
|
||||
await expect(modal).toHaveAttribute('role', 'alertdialog');
|
||||
});
|
||||
});
|
||||
39
core/src/components/modal/test/a11y/modal.e2e.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import AxeBuilder from '@axe-core/playwright';
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('modal: a11y'), () => {
|
||||
test('should not have accessibility violations', async ({ page }) => {
|
||||
await page.goto(`/src/components/modal/test/a11y`, config);
|
||||
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const button = page.locator('#open-modal');
|
||||
const modal = page.locator('ion-modal .modal-wrapper');
|
||||
|
||||
await expect(modal).toHaveAttribute('role', 'dialog');
|
||||
|
||||
await button.click();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const results = await new AxeBuilder({ page }).analyze();
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
|
||||
test('should allow for custom role', async ({ page }) => {
|
||||
/**
|
||||
* Note: This example should not be used in production.
|
||||
* This only serves to check that `role` can be customized.
|
||||
*/
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-modal role="alertdialog"></ion-modal>
|
||||
`,
|
||||
config
|
||||
);
|
||||
const modal = page.locator('ion-modal .modal-wrapper');
|
||||
|
||||
await expect(modal).toHaveAttribute('role', 'alertdialog');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,184 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test, Viewports } from '@utils/test/playwright';
|
||||
import type { E2EPage } from '@utils/test/playwright';
|
||||
|
||||
test.describe('modal: focus trapping', () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
||||
});
|
||||
test('focus should be trapped inside of modal', async ({ page, browserName }) => {
|
||||
/**
|
||||
* The default WebKit behavior is to
|
||||
* highlight items on webpages with Option-Tab.
|
||||
* See "Press Tab to highlight each item on a webpage"
|
||||
* in Safari Preferences > Advanced.
|
||||
*/
|
||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||
await page.goto('/src/components/modal/test/basic');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const dismissButton = page.locator('ion-button.dismiss');
|
||||
|
||||
await page.keyboard.press(tabKey);
|
||||
await expect(dismissButton).toBeFocused();
|
||||
|
||||
await page.keyboard.press(`Shift+${tabKey}`);
|
||||
|
||||
await expect(dismissButton).toBeFocused();
|
||||
|
||||
await page.keyboard.press(tabKey);
|
||||
await expect(dismissButton).toBeFocused();
|
||||
});
|
||||
|
||||
test('focus should be returned to previously focused element when dismissing modal', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await page.goto('/src/components/modal/test/basic');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const modalButton = page.locator('#basic-modal');
|
||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||
|
||||
// Focus #basic-modal button
|
||||
await page.keyboard.press(tabKey);
|
||||
await expect(modalButton).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Space');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await page.keyboard.press('Escape');
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
await expect(modalButton).toBeFocused();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('modal: rendering', () => {
|
||||
const runVisualTests = async (page: E2EPage, screenshotModifier = '') => {
|
||||
await page.goto('/src/components/modal/test/basic');
|
||||
|
||||
const ionModalWillDismiss = await page.spyOnEvent('ionModalWillDismiss');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionModalWillPresent = await page.spyOnEvent('ionModalWillPresent');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
|
||||
await ionModalWillPresent.next();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
await expect(modal).toHaveClass(/show-modal/);
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-basic-present-${screenshotModifier}${page.getSnapshotSettings()}.png`);
|
||||
|
||||
await modal.evaluate((el: HTMLIonModalElement) => {
|
||||
el.dismiss();
|
||||
});
|
||||
|
||||
await ionModalWillDismiss.next();
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
await expect(modal).not.toHaveClass(/show-modal/);
|
||||
await expect(modal).toBeHidden();
|
||||
};
|
||||
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await runVisualTests(page);
|
||||
});
|
||||
test('should not have visual regressions with tablet viewport', async ({ page }) => {
|
||||
await page.setViewportSize(Viewports.tablet.portrait);
|
||||
await runVisualTests(page, 'tablet-');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('modal: htmlAttributes inheritance', () => {
|
||||
test('should correctly inherit attributes on host', async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
await page.goto('/src/components/modal/test/basic');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
|
||||
const attribute = await modal.getAttribute('data-testid');
|
||||
expect(attribute).toBe('basic-modal');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('modal: backdrop', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
await page.goto('/src/components/modal/test/basic');
|
||||
});
|
||||
|
||||
test('it should dismiss the modal when clicking the backdrop', async ({ page }) => {
|
||||
await page.setViewportSize(Viewports.tablet.portrait);
|
||||
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await page.mouse.click(20, 20);
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('modal: incorrect usage', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
await page.goto('/src/components/modal/test/basic');
|
||||
});
|
||||
|
||||
test('it should warn when setting a breakpoint on a non-sheet modal', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
const warnings: string[] = [];
|
||||
|
||||
page.on('console', (ev) => {
|
||||
if (ev.type() === 'warning') {
|
||||
warnings.push(ev.text());
|
||||
}
|
||||
});
|
||||
|
||||
await page.click('#basic-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.setCurrentBreakpoint(0.5));
|
||||
|
||||
expect(warnings.length).toBe(1);
|
||||
expect(warnings[0]).toBe('[Ionic Warning]: setCurrentBreakpoint is only supported on sheet modals.');
|
||||
});
|
||||
|
||||
test('it should return undefined when getting the breakpoint on a non-sheet modal', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const breakpoint = await modal.evaluate((el: HTMLIonModalElement) => {
|
||||
return el.getCurrentBreakpoint();
|
||||
});
|
||||
|
||||
expect(breakpoint).toBe(undefined);
|
||||
});
|
||||
});
|
||||
181
core/src/components/modal/test/basic/modal.e2e.ts
Normal file
@ -0,0 +1,181 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, Viewports } from '@utils/test/playwright';
|
||||
import type { E2EPage } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('modal: focus trapping'), () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
||||
});
|
||||
test('focus should be trapped inside of modal', async ({ page, browserName }) => {
|
||||
/**
|
||||
* The default WebKit behavior is to
|
||||
* highlight items on webpages with Option-Tab.
|
||||
* See "Press Tab to highlight each item on a webpage"
|
||||
* in Safari Preferences > Advanced.
|
||||
*/
|
||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||
await page.goto('/src/components/modal/test/basic', config);
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const dismissButton = page.locator('ion-button.dismiss');
|
||||
|
||||
await page.keyboard.press(tabKey);
|
||||
await expect(dismissButton).toBeFocused();
|
||||
|
||||
await page.keyboard.press(`Shift+${tabKey}`);
|
||||
|
||||
await expect(dismissButton).toBeFocused();
|
||||
|
||||
await page.keyboard.press(tabKey);
|
||||
await expect(dismissButton).toBeFocused();
|
||||
});
|
||||
|
||||
test('focus should be returned to previously focused element when dismissing modal', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await page.goto('/src/components/modal/test/basic', config);
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const modalButton = page.locator('#basic-modal');
|
||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||
|
||||
// Focus #basic-modal button
|
||||
await page.keyboard.press(tabKey);
|
||||
await expect(modalButton).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Space');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await page.keyboard.press('Escape');
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
await expect(modalButton).toBeFocused();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
configs().forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('modal: rendering'), () => {
|
||||
const runVisualTests = async (page: E2EPage, screenshotModifier = '') => {
|
||||
await page.goto('/src/components/modal/test/basic', config);
|
||||
|
||||
const ionModalWillDismiss = await page.spyOnEvent('ionModalWillDismiss');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionModalWillPresent = await page.spyOnEvent('ionModalWillPresent');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
|
||||
await ionModalWillPresent.next();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
await expect(modal).toHaveClass(/show-modal/);
|
||||
|
||||
await page.setIonViewport();
|
||||
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-basic-present${screenshotModifier}`));
|
||||
|
||||
await modal.evaluate((el: HTMLIonModalElement) => {
|
||||
el.dismiss();
|
||||
});
|
||||
|
||||
await ionModalWillDismiss.next();
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
await expect(modal).not.toHaveClass(/show-modal/);
|
||||
await expect(modal).toBeHidden();
|
||||
};
|
||||
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await runVisualTests(page);
|
||||
});
|
||||
test('should not have visual regressions with tablet viewport', async ({ page }) => {
|
||||
await page.setViewportSize(Viewports.tablet.portrait);
|
||||
await runVisualTests(page, '-tablet');
|
||||
});
|
||||
});
|
||||
});
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('modal: htmlAttributes inheritance'), () => {
|
||||
test('should correctly inherit attributes on host', async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/basic', config);
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
|
||||
const attribute = await modal.getAttribute('data-testid');
|
||||
expect(attribute).toBe('basic-modal');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(title('modal: backdrop'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/basic', config);
|
||||
});
|
||||
|
||||
test('it should dismiss the modal when clicking the backdrop', async ({ page }) => {
|
||||
await page.setViewportSize(Viewports.tablet.portrait);
|
||||
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await page.mouse.click(20, 20);
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(title('modal: incorrect usage'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/basic', config);
|
||||
});
|
||||
|
||||
test('it should warn when setting a breakpoint on a non-sheet modal', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
const warnings: string[] = [];
|
||||
|
||||
page.on('console', (ev) => {
|
||||
if (ev.type() === 'warning') {
|
||||
warnings.push(ev.text());
|
||||
}
|
||||
});
|
||||
|
||||
await page.click('#basic-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.setCurrentBreakpoint(0.5));
|
||||
|
||||
expect(warnings.length).toBe(1);
|
||||
expect(warnings[0]).toBe('[Ionic Warning]: setCurrentBreakpoint is only supported on sheet modals.');
|
||||
});
|
||||
|
||||
test('it should return undefined when getting the breakpoint on a non-sheet modal', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#basic-modal');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const breakpoint = await modal.evaluate((el: HTMLIonModalElement) => {
|
||||
return el.getCurrentBreakpoint();
|
||||
});
|
||||
|
||||
expect(breakpoint).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@ -1,425 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
test.describe('modal: canDismiss', () => {
|
||||
test.describe('regular modal', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
await page.goto('/src/components/modal/test/can-dismiss');
|
||||
});
|
||||
test('should dismiss when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Action Sheet and user clicks confirm', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
await page.click('#radio-action-sheet');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await page.keyboard.press('Escape');
|
||||
|
||||
await ionActionSheetDidPresent.next();
|
||||
await page.click('.button-confirm');
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
test.describe('card modal', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
await page.goto('/src/components/modal/test/can-dismiss');
|
||||
await page.click('#radio-card');
|
||||
});
|
||||
test('should dismiss when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
});
|
||||
test.describe('card modal - iOS swiping', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
await page.goto('/src/components/modal/test/can-dismiss');
|
||||
await page.click('#radio-card');
|
||||
});
|
||||
|
||||
test('should dismiss on swipe when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('ion-modal #modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should dismiss on swipe when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionHandlerDone.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should dismiss when canDismiss is Action Sheet and user clicks confirm', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
await page.click('#radio-action-sheet');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionActionSheetDidPresent.next();
|
||||
await page.click('.button-confirm');
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('sheet modal', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
await page.goto('/src/components/modal/test/can-dismiss');
|
||||
await page.click('#radio-sheet');
|
||||
});
|
||||
test('should dismiss when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss on swipe when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should dismiss on swipe when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionHandlerDone.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should not dismiss on swipe when not attempting to close', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, -500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should hit the dismiss threshold when swiping', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 100);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should dismiss when canDismiss is Action Sheet and user clicks confirm', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
await page.click('#radio-action-sheet');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionActionSheetDidPresent.next();
|
||||
await page.click('.button-confirm');
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('function params', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.mode('md');
|
||||
skip.rtl();
|
||||
await page.goto('/src/components/modal/test/can-dismiss');
|
||||
});
|
||||
test('should pass data and role when calling dismiss', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss('my data', 'my role'));
|
||||
|
||||
await ionHandlerDone.next();
|
||||
await expect(ionHandlerDone).toHaveReceivedEventDetail({ data: 'my data', role: 'my role' });
|
||||
});
|
||||
test('should pass data and role when swiping', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-card');
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionHandlerDone.next();
|
||||
await expect(ionHandlerDone).toHaveReceivedEventDetail({ data: undefined, role: 'gesture' });
|
||||
});
|
||||
});
|
||||
});
|
||||
422
core/src/components/modal/test/can-dismiss/modal.e2e.ts
Normal file
@ -0,0 +1,422 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* This behavior does not vary across modes/directions
|
||||
*/
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('modal: canDismiss'), () => {
|
||||
test.describe('regular modal', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/can-dismiss', config);
|
||||
});
|
||||
test('should dismiss when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Action Sheet and user clicks confirm', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
await page.click('#radio-action-sheet');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
await page.keyboard.press('Escape');
|
||||
|
||||
await ionActionSheetDidPresent.next();
|
||||
await page.click('.button-confirm');
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
test.describe('card modal', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/can-dismiss', config);
|
||||
await page.click('#radio-card');
|
||||
});
|
||||
test('should dismiss when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
});
|
||||
test.describe('card modal - iOS swiping', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/can-dismiss', config);
|
||||
await page.click('#radio-card');
|
||||
});
|
||||
|
||||
test('should dismiss on swipe when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('ion-modal #modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should dismiss on swipe when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionHandlerDone.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should dismiss when canDismiss is Action Sheet and user clicks confirm', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
await page.click('#radio-action-sheet');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionActionSheetDidPresent.next();
|
||||
await page.click('.button-confirm');
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('sheet modal', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/can-dismiss', config);
|
||||
await page.click('#radio-sheet');
|
||||
});
|
||||
test('should dismiss when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(true);
|
||||
});
|
||||
test('should not dismiss when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const returnValue = await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||
|
||||
expect(returnValue).toBe(false);
|
||||
});
|
||||
test('should dismiss on swipe when canDismiss is true', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is false', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should dismiss on swipe when canDismiss is Promise<true>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should not dismiss on swipe when canDismiss is Promise<false>', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-promise-false');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionHandlerDone.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should not dismiss on swipe when not attempting to close', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, -500);
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
expect(modal).not.toBe(null);
|
||||
});
|
||||
test('should hit the dismiss threshold when swiping', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 100);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('should dismiss when canDismiss is Action Sheet and user clicks confirm', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent');
|
||||
|
||||
await page.click('#radio-action-sheet');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionActionSheetDidPresent.next();
|
||||
await page.click('.button-confirm');
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('function params', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/can-dismiss', config);
|
||||
});
|
||||
test('should pass data and role when calling dismiss', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss('my data', 'my role'));
|
||||
|
||||
await ionHandlerDone.next();
|
||||
await expect(ionHandlerDone).toHaveReceivedEventDetail({ data: 'my data', role: 'my role' });
|
||||
});
|
||||
test('should pass data and role when swiping', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionHandlerDone = await page.spyOnEvent('ionHandlerDone');
|
||||
|
||||
await page.click('#radio-card');
|
||||
await page.click('#radio-promise-true');
|
||||
await page.click('#show-modal');
|
||||
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modalHeader = page.locator('#modal-header');
|
||||
await dragElementBy(modalHeader, page, 0, 500);
|
||||
|
||||
await ionHandlerDone.next();
|
||||
await expect(ionHandlerDone).toHaveReceivedEventDetail({ data: undefined, role: 'gesture' });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,50 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
import { CardModalPage } from '../fixtures';
|
||||
|
||||
test.describe('card modal - nav', () => {
|
||||
let cardModalPage: CardModalPage;
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.mode('md');
|
||||
skip.rtl('This test only verifies that the gesture activates inside of a modal.');
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
|
||||
cardModalPage = new CardModalPage(page);
|
||||
await cardModalPage.navigate('/src/components/modal/test/card-nav?ionic:_testing=false');
|
||||
});
|
||||
test('it should swipe to go back', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#open-modal');
|
||||
|
||||
const nav = page.locator('ion-nav') as any;
|
||||
const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
|
||||
|
||||
await page.click('#go-page-two');
|
||||
|
||||
await ionNavDidChange.next();
|
||||
|
||||
const pageOne = page.locator('page-one');
|
||||
await expect(pageOne).toHaveClass(/ion-page-hidden/);
|
||||
|
||||
const content = page.locator('.page-two-content');
|
||||
|
||||
await dragElementBy(content, page, 1000, 0, 10);
|
||||
|
||||
await ionNavDidChange.next();
|
||||
});
|
||||
test('should swipe to close', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#open-modal');
|
||||
|
||||
const nav = page.locator('ion-nav') as any;
|
||||
const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
|
||||
|
||||
await page.click('#go-page-two');
|
||||
|
||||
await ionNavDidChange.next();
|
||||
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-content.page-two-content');
|
||||
});
|
||||
});
|
||||
53
core/src/components/modal/test/card-nav/modal.e2e.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test, dragElementBy } from '@utils/test/playwright';
|
||||
|
||||
import { CardModalPage } from '../fixtures';
|
||||
|
||||
/**
|
||||
* This test only verifies that the gesture activates inside of a modal.
|
||||
*/
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('card modal - nav'), () => {
|
||||
let cardModalPage: CardModalPage;
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.browser(
|
||||
(browserName: string) => browserName !== 'chromium',
|
||||
'dragElementBy is flaky outside of Chrome browsers.'
|
||||
);
|
||||
|
||||
cardModalPage = new CardModalPage(page);
|
||||
await cardModalPage.navigate('/src/components/modal/test/card-nav?ionic:_testing=false', config);
|
||||
});
|
||||
test('it should swipe to go back', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#open-modal');
|
||||
|
||||
const nav = page.locator('ion-nav') as any;
|
||||
const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
|
||||
|
||||
await page.click('#go-page-two');
|
||||
|
||||
await ionNavDidChange.next();
|
||||
|
||||
const pageOne = page.locator('page-one');
|
||||
await expect(pageOne).toHaveClass(/ion-page-hidden/);
|
||||
|
||||
const content = page.locator('.page-two-content');
|
||||
|
||||
await dragElementBy(content, page, 1000, 0, 10);
|
||||
|
||||
await ionNavDidChange.next();
|
||||
});
|
||||
test('should swipe to close', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#open-modal');
|
||||
|
||||
const nav = page.locator('ion-nav') as any;
|
||||
const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
|
||||
|
||||
await page.click('#go-page-two');
|
||||
|
||||
await ionNavDidChange.next();
|
||||
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-content.page-two-content');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,26 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { dragElementBy, test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('card modal - with refresher', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.mode('md');
|
||||
skip.rtl();
|
||||
|
||||
await page.goto('/src/components/modal/test/card-refresher');
|
||||
});
|
||||
test('it should not swipe to close on the content due to the presence of the refresher', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const content = (await page.$('ion-modal ion-content'))!;
|
||||
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await content.waitForElementState('stable');
|
||||
|
||||
await expect(modal).toBeVisible();
|
||||
});
|
||||
});
|
||||
25
core/src/components/modal/test/card-refresher/modal.e2e.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, dragElementBy, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('card modal - with refresher'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/card-refresher', config);
|
||||
});
|
||||
test('it should not swipe to close on the content due to the presence of the refresher', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const content = (await page.$('ion-modal ion-content'))!;
|
||||
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await content.waitForElementState('stable');
|
||||
|
||||
await expect(modal).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,53 +0,0 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { dragElementBy, test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('card modal - scroll target', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.mode('md');
|
||||
skip.rtl();
|
||||
|
||||
await page.goto('/src/components/modal/test/card-scroll-target');
|
||||
});
|
||||
test.describe('card modal: swipe to close', () => {
|
||||
test('it should swipe to close when swiped on the content', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const content = page.locator('ion-modal .ion-content-scroll-host');
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('it should not swipe to close when swiped on the content but the content is scrolled', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const content = (await page.$('ion-modal .ion-content-scroll-host'))!;
|
||||
|
||||
await content.evaluate((el: HTMLElement) => (el.scrollTop = 500));
|
||||
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await content.waitForElementState('stable');
|
||||
|
||||
await expect(modal).toBeVisible();
|
||||
});
|
||||
test('content should be scrollable after gesture ends', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const content = page.locator('ion-modal .ion-content-scroll-host');
|
||||
await dragElementBy(content, page, 0, 20);
|
||||
|
||||
await expect(content).not.toHaveCSS('overflow', 'hidden');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,52 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, dragElementBy, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||
test.describe(title('card modal - scroll target'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/src/components/modal/test/card-scroll-target', config);
|
||||
});
|
||||
test.describe('card modal: swipe to close', () => {
|
||||
test('it should swipe to close when swiped on the content', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const content = page.locator('ion-modal .ion-content-scroll-host');
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
});
|
||||
test('it should not swipe to close when swiped on the content but the content is scrolled', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = page.locator('ion-modal');
|
||||
const content = (await page.$('ion-modal .ion-content-scroll-host'))!;
|
||||
|
||||
await content.evaluate((el: HTMLElement) => (el.scrollTop = 500));
|
||||
|
||||
await dragElementBy(content, page, 0, 500);
|
||||
|
||||
await content.waitForElementState('stable');
|
||||
|
||||
await expect(modal).toBeVisible();
|
||||
});
|
||||
test('content should be scrollable after gesture ends', async ({ page }) => {
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#card');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const content = page.locator('ion-modal .ion-content-scroll-host');
|
||||
await dragElementBy(content, page, 0, 20);
|
||||
|
||||
await expect(content).not.toHaveCSS('overflow', 'hidden');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,49 +1,48 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test, Viewports } from '@utils/test/playwright';
|
||||
import { configs, test, Viewports } from '@utils/test/playwright';
|
||||
|
||||
import { CardModalPage } from '../fixtures';
|
||||
|
||||
test.describe('card modal', () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.mode('md');
|
||||
});
|
||||
test.describe('card modal: rendering', () => {
|
||||
configs({ modes: ['ios'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('card modal: rendering'), () => {
|
||||
let cardModalPage: CardModalPage;
|
||||
test.beforeEach(async ({ page }) => {
|
||||
cardModalPage = new CardModalPage(page);
|
||||
await cardModalPage.navigate('/src/components/modal/test/card');
|
||||
await cardModalPage.navigate('/src/components/modal/test/card', config);
|
||||
});
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-present-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-present`));
|
||||
});
|
||||
test('should not have visual regressions with custom modal', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card-custom');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-custom-present-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-custom-present`));
|
||||
});
|
||||
test('should not have visual regressions with stacked cards', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card');
|
||||
await cardModalPage.openModalByTrigger('.add');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-stacked-present-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-stacked-present`));
|
||||
});
|
||||
test('should not have visual regressions with stacked custom cards', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card-custom');
|
||||
await cardModalPage.openModalByTrigger('.add');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-custom-stacked-present-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-custom-stacked-present`));
|
||||
});
|
||||
});
|
||||
test.describe('card modal: functionality', () => {
|
||||
});
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('card modal: functionality'), () => {
|
||||
let cardModalPage: CardModalPage;
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
skip.rtl();
|
||||
test.beforeEach(async ({ page }) => {
|
||||
cardModalPage = new CardModalPage(page);
|
||||
await cardModalPage.navigate('/src/components/modal/test/card');
|
||||
await cardModalPage.navigate('/src/components/modal/test/card', config);
|
||||
});
|
||||
test.describe('card modal: swipe to close', () => {
|
||||
test.describe(title('card modal: swipe to close'), () => {
|
||||
test('it should swipe to close when swiped on the header', async () => {
|
||||
await cardModalPage.openModalByTrigger('#card');
|
||||
await cardModalPage.swipeToCloseModal('ion-modal ion-header');
|
||||
@ -86,36 +85,34 @@ test.describe('card modal', () => {
|
||||
await expect(content).toHaveJSProperty('scrollY', true);
|
||||
});
|
||||
});
|
||||
test.describe('card modal: rendering - tablet', () => {
|
||||
test.describe(title('card modal: rendering - tablet'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.setViewportSize(Viewports.tablet.portrait);
|
||||
});
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-present-tablet-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-present-tablet`));
|
||||
});
|
||||
test('should not have visual regressions with custom modal', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card-custom');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-custom-present-tablet-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-custom-present-tablet`));
|
||||
});
|
||||
test('should not have visual regressions with stacked cards', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card');
|
||||
await cardModalPage.openModalByTrigger('.add');
|
||||
|
||||
await expect(page).toHaveScreenshot(`modal-card-stacked-present-tablet-${page.getSnapshotSettings()}.png`);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-stacked-present-tablet`));
|
||||
});
|
||||
test('should not have visual regressions with stacked custom cards', async ({ page }) => {
|
||||
await cardModalPage.openModalByTrigger('#card-custom');
|
||||
await cardModalPage.openModalByTrigger('.add');
|
||||
|
||||
await expect(page).toHaveScreenshot(
|
||||
`modal-card-custom-stacked-present-tablet-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
await expect(page).toHaveScreenshot(screenshot(`modal-card-custom-stacked-present-tablet`));
|
||||
});
|
||||
});
|
||||
test.describe('card modal: swipe to close - tablet', () => {
|
||||
test.describe(title('card modal: swipe to close - tablet'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.setViewportSize(Viewports.tablet.portrait);
|
||||
});
|
||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 458 KiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 458 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 462 KiB After Width: | Height: | Size: 462 KiB |
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 459 KiB After Width: | Height: | Size: 459 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 449 KiB After Width: | Height: | Size: 449 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 451 KiB After Width: | Height: | Size: 451 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 451 KiB After Width: | Height: | Size: 451 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 197 KiB |