test(menu): migrate to playwright (#26187)
@@ -1,15 +0,0 @@
|
||||
import { AxePuppeteer } from '@axe-core/puppeteer';
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('menu: axe', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/menu/test/a11y?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const menu = await page.find('ion-menu');
|
||||
await menu.callMethod('open');
|
||||
await menu.waitForVisible();
|
||||
|
||||
const results = await new AxePuppeteer(page).analyze();
|
||||
expect(results.violations.length).toEqual(0);
|
||||
});
|
||||
@@ -2,18 +2,28 @@
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Segment - a11y</title>
|
||||
<title>Menu - a11y</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
||||
<link href="../../../../../css/core.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<script type="module">
|
||||
import { menuController } from '../../../../dist/ionic/index.esm.js';
|
||||
window.menuController = menuController;
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>Menu</h1>
|
||||
<div class="ion-page" id="main-content">
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Menu</h1>
|
||||
<ion-button id="open-menu" expand="block" onclick="openMenu()">Open Menu</ion-button>
|
||||
</ion-content>
|
||||
</div>
|
||||
|
||||
<ion-menu menu-id="menu" content-id="main-content">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
@@ -21,6 +31,7 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<h1 class="ion-margin">Open Menu</h1>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-button>Button</ion-button>
|
||||
@@ -35,5 +46,12 @@
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
async function openMenu() {
|
||||
await menuController.enable(true, 'menu');
|
||||
await menuController.open('menu');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
28
core/src/components/menu/test/a11y/menu.e2e.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import AxeBuilder from '@axe-core/playwright';
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('menu: a11y', () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('md');
|
||||
});
|
||||
|
||||
test('menu should not have accessibility violations', async ({ page }) => {
|
||||
await page.goto(`/src/components/menu/test/a11y`);
|
||||
|
||||
const menu = page.locator('ion-menu');
|
||||
const button = page.locator('#open-menu');
|
||||
|
||||
await button.click();
|
||||
await page.waitForSelector('ion-menu', { state: 'visible' });
|
||||
|
||||
await expect(menu).toHaveAttribute('role', 'navigation');
|
||||
|
||||
const heading = page.locator('ion-menu h1');
|
||||
await expect(heading).toHaveText('Open Menu');
|
||||
|
||||
const results = await new AxeBuilder({ page }).analyze();
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,81 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
import { testMenu } from '../test.utils';
|
||||
|
||||
const DIRECTORY = 'basic';
|
||||
const getActiveElementID = async (page) => {
|
||||
const activeElement = await page.evaluateHandle(() => document.activeElement);
|
||||
return page.evaluate((el) => el?.id, activeElement);
|
||||
};
|
||||
|
||||
test('menu: start menu', async () => {
|
||||
await testMenu(DIRECTORY, '#start-menu', 'first');
|
||||
});
|
||||
|
||||
test('menu: start custom menu', async () => {
|
||||
await testMenu(DIRECTORY, '#custom-menu', 'custom');
|
||||
});
|
||||
|
||||
test('menu: end menu', async () => {
|
||||
await testMenu(DIRECTORY, '#end-menu');
|
||||
});
|
||||
|
||||
test('menu: focus trap', async () => {
|
||||
const page = await newE2EPage({ url: '/src/components/menu/test/basic?ionic:_testing=true' });
|
||||
|
||||
await page.click('#open-first');
|
||||
const menu = await page.find('#start-menu');
|
||||
await menu.waitForVisible();
|
||||
|
||||
let activeElID = await getActiveElementID(page);
|
||||
expect(activeElID).toEqual('start-menu');
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
activeElID = await getActiveElementID(page);
|
||||
expect(activeElID).toEqual('start-menu-button');
|
||||
|
||||
// do it again to make sure focus stays inside menu
|
||||
await page.keyboard.press('Tab');
|
||||
activeElID = await getActiveElementID(page);
|
||||
expect(activeElID).toEqual('start-menu-button');
|
||||
});
|
||||
|
||||
test('menu: preserve scroll position', async () => {
|
||||
const page = await newE2EPage({ url: '/src/components/menu/test/basic?ionic:_testing=true' });
|
||||
|
||||
await page.click('#open-first');
|
||||
const menu = await page.find('#start-menu');
|
||||
await menu.waitForVisible();
|
||||
|
||||
await page.$eval('#start-menu ion-content', (menuContentEl: any) => {
|
||||
return menuContentEl.scrollToPoint(0, 200);
|
||||
});
|
||||
|
||||
await menu.callMethod('close');
|
||||
|
||||
await page.click('#open-first');
|
||||
await menu.waitForVisible();
|
||||
|
||||
const scrollTop = await page.$eval('#start-menu ion-content', async (menuContentEl: any) => {
|
||||
const contentScrollEl = await menuContentEl.getScrollElement();
|
||||
return contentScrollEl.scrollTop;
|
||||
});
|
||||
|
||||
expect(scrollTop).toEqual(200);
|
||||
});
|
||||
|
||||
/**
|
||||
* RTL Tests
|
||||
*/
|
||||
|
||||
test('menu:rtl: start menu', async () => {
|
||||
await testMenu(DIRECTORY, '#start-menu', 'first', true);
|
||||
});
|
||||
|
||||
test('menu:rtl: start custom menu', async () => {
|
||||
await testMenu(DIRECTORY, '#custom-menu', 'custom', true);
|
||||
});
|
||||
|
||||
test('menu:rtl: end menu', async () => {
|
||||
await testMenu(DIRECTORY, '#end-menu', '', true);
|
||||
});
|
||||
@@ -12,12 +12,6 @@
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<script>
|
||||
const forceCSSAnimations = new URLSearchParams(window.location.search).get('ionic:_forceCSSAnimations');
|
||||
if (forceCSSAnimations) {
|
||||
window.Animation = null;
|
||||
}
|
||||
</script>
|
||||
<script type="module">
|
||||
import { menuController } from '../../../../dist/ionic/index.esm.js';
|
||||
window.menuController = menuController;
|
||||
@@ -28,8 +22,8 @@
|
||||
<ion-app>
|
||||
<ion-menu
|
||||
side="start"
|
||||
menu-id="first"
|
||||
id="start-menu"
|
||||
menu-id="start-menu"
|
||||
content-id="main"
|
||||
class="menu-part"
|
||||
aria-label="start menu"
|
||||
@@ -68,7 +62,7 @@
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-menu side="start" menu-id="custom" class="my-custom-menu" id="custom-menu" content-id="main">
|
||||
<ion-menu side="start" menu-id="custom-menu" content-id="main" class="my-custom-menu">
|
||||
<ion-header>
|
||||
<ion-toolbar color="tertiary">
|
||||
<ion-title>Custom Menu</ion-title>
|
||||
@@ -85,7 +79,7 @@
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-menu side="end" type="push" id="end-menu" content-id="main">
|
||||
<ion-menu side="end" menu-id="end-menu" content-id="main" type="push">
|
||||
<ion-header>
|
||||
<ion-toolbar color="danger">
|
||||
<ion-title>End Menu</ion-title>
|
||||
@@ -109,9 +103,9 @@
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button expand="block" id="open-first" onclick="openFirst()">Open Start Menu</ion-button>
|
||||
<ion-button expand="block" onclick="openEnd()">Open End Menu</ion-button>
|
||||
<ion-button expand="block" onclick="openCustom()">Open Custom Menu</ion-button>
|
||||
<ion-button expand="block" id="open-start" onclick="openStart()">Open Start Menu</ion-button>
|
||||
<ion-button expand="block" id="open-end" onclick="openEnd()">Open End Menu</ion-button>
|
||||
<ion-button expand="block" id="open-custom" onclick="openCustom()">Open Custom Menu</ion-button>
|
||||
</ion-content>
|
||||
</div>
|
||||
</ion-app>
|
||||
@@ -133,18 +127,21 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
async function openFirst() {
|
||||
await menuController.enable(true, 'first');
|
||||
await menuController.open('first');
|
||||
async function openStart() {
|
||||
// Open the menu by menu-id
|
||||
await menuController.enable(true, 'start-menu');
|
||||
await menuController.open('start-menu');
|
||||
}
|
||||
|
||||
async function openEnd() {
|
||||
// Open the menu by side
|
||||
await menuController.open('end');
|
||||
}
|
||||
|
||||
async function openCustom() {
|
||||
await menuController.enable(true, 'custom');
|
||||
await menuController.open('custom');
|
||||
// Open the menu by menu-id
|
||||
await menuController.enable(true, 'custom-menu');
|
||||
await menuController.open('custom-menu');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
93
core/src/components/menu/test/basic/menu.e2e.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import type { Locator } from '@playwright/test';
|
||||
import { expect } from '@playwright/test';
|
||||
import type { E2EPage } from '@utils/test/playwright';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('menu: basic', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(`/src/components/menu/test/basic`);
|
||||
});
|
||||
|
||||
test('should open selected menu by side', async ({ page }) => {
|
||||
const startMenu = page.locator('[menu-id="start-menu"]');
|
||||
const customMenu = page.locator('[menu-id="custom-menu"]');
|
||||
const endMenu = page.locator('[menu-id="end-menu"]');
|
||||
|
||||
await testMenu(page, startMenu, 'start');
|
||||
await testMenu(page, customMenu, 'custom');
|
||||
await testMenu(page, endMenu, 'end');
|
||||
});
|
||||
|
||||
test('should trap focus', async ({ page, skip, browserName }) => {
|
||||
skip.rtl('Trapping focus is not dependent on document direction');
|
||||
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
||||
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
|
||||
await page.click('#open-start');
|
||||
await ionDidOpen.next();
|
||||
|
||||
const button = await page.locator('#start-menu-button');
|
||||
|
||||
if (browserName === 'webkit') {
|
||||
await page.keyboard.down('Alt');
|
||||
}
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
|
||||
await expect(button).toBeFocused();
|
||||
|
||||
await page.keyboard.press('Tab');
|
||||
|
||||
if (browserName === 'webkit') {
|
||||
await page.keyboard.up('Alt');
|
||||
}
|
||||
|
||||
await expect(button).toBeFocused();
|
||||
});
|
||||
|
||||
test('should preserve scroll position', async ({ page, skip }) => {
|
||||
skip.rtl('Scroll position is not dependent on document direction');
|
||||
skip.browser('firefox', 'Firefox does not preserve scroll position');
|
||||
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
|
||||
await page.click('#open-start');
|
||||
await ionDidOpen.next();
|
||||
|
||||
await page.locator('#start-menu ion-content').evaluate(async (el: HTMLIonContentElement) => {
|
||||
await el.scrollToPoint(0, 200);
|
||||
});
|
||||
|
||||
await page.locator('#start-menu').evaluate(async (el: HTMLIonMenuElement) => {
|
||||
await el.close();
|
||||
});
|
||||
|
||||
await page.click('#open-start');
|
||||
await ionDidOpen.next();
|
||||
|
||||
const scrollTop = await page.locator('#start-menu ion-content').evaluate(async (el: HTMLIonContentElement) => {
|
||||
const contentScrollEl = await el.getScrollElement();
|
||||
return contentScrollEl.scrollTop;
|
||||
});
|
||||
|
||||
await expect(scrollTop).toBe(200);
|
||||
});
|
||||
});
|
||||
|
||||
async function testMenu(page: E2EPage, menu: Locator, menuId: string) {
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionDidClose = await page.spyOnEvent('ionDidClose');
|
||||
|
||||
await page.click(`#open-${menuId}`);
|
||||
await ionDidOpen.next();
|
||||
|
||||
await expect(menu).toHaveClass(/show-menu/);
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(`menu-basic-${menuId}-${page.getSnapshotSettings()}.png`);
|
||||
|
||||
await menu.evaluate(async (el: HTMLIonMenuElement) => {
|
||||
await el.close();
|
||||
});
|
||||
await ionDidClose.next();
|
||||
}
|
||||
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 64 KiB |
@@ -1,90 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
const getActiveElementID = async (page) => {
|
||||
const activeElement = await page.evaluateHandle(() => document.activeElement);
|
||||
return page.evaluate((el) => el?.id, activeElement);
|
||||
};
|
||||
|
||||
test('menu: focus trap with overlays', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/menu/test/focus-trap?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
const menu = await page.find('ion-menu');
|
||||
await menu.callMethod('open');
|
||||
await ionDidOpen.next();
|
||||
|
||||
expect(await getActiveElementID(page)).toEqual('menu');
|
||||
|
||||
const openModal = await page.find('#open-modal-button');
|
||||
await openModal.click();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
expect(await getActiveElementID(page)).toEqual('modal-element');
|
||||
|
||||
const modal = await page.find('ion-modal');
|
||||
await modal.callMethod('dismiss');
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
expect(await getActiveElementID(page)).toEqual('open-modal-button');
|
||||
});
|
||||
|
||||
test('menu: focus trap with content inside overlays', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/menu/test/focus-trap?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
const menu = await page.find('ion-menu');
|
||||
await menu.callMethod('open');
|
||||
await ionDidOpen.next();
|
||||
|
||||
expect(await getActiveElementID(page)).toEqual('menu');
|
||||
|
||||
const openModal = await page.find('#open-modal-button');
|
||||
await openModal.click();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const button = await page.find('#other-button');
|
||||
await button.click();
|
||||
|
||||
expect(await getActiveElementID(page)).toEqual('other-button');
|
||||
});
|
||||
|
||||
test('menu: should work with swipe gestures after modal is dismissed', async () => {
|
||||
const page = await newE2EPage({
|
||||
url: '/src/components/menu/test/focus-trap?ionic:_testing=true',
|
||||
});
|
||||
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
const menu = await page.find('ion-menu');
|
||||
await menu.callMethod('open');
|
||||
await ionDidOpen.next();
|
||||
|
||||
const openModal = await page.find('#open-modal-button');
|
||||
await openModal.click();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = await page.find('ion-modal');
|
||||
await modal.callMethod('dismiss');
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
await page.mouse.move(30, 168);
|
||||
await page.mouse.down();
|
||||
|
||||
await page.mouse.move(384, 168);
|
||||
await page.mouse.up();
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(menu.classList.contains('show-menu')).toBeTruthy();
|
||||
});
|
||||
@@ -14,7 +14,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-menu content-id="main" id="menu">
|
||||
<ion-menu id="menu" content-id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Menu</ion-title>
|
||||
@@ -24,7 +24,7 @@
|
||||
<ion-item>
|
||||
<ion-button id="open-modal-button">Open Modal</ion-button>
|
||||
</ion-item>
|
||||
<ion-modal id="modal-element" trigger="open-modal-button">
|
||||
<ion-modal id="modal" trigger="open-modal-button">
|
||||
<ion-content class="ion-padding">
|
||||
Modal content
|
||||
<ion-button onclick="dismissModal()">Dismiss Modal</ion-button>
|
||||
|
||||
89
core/src/components/menu/test/focus-trap/menu.e2e.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
test.describe('menu: focus trap', () => {
|
||||
test.beforeEach(async ({ page, skip }) => {
|
||||
await page.goto(`/src/components/menu/test/focus-trap`);
|
||||
|
||||
skip.rtl('Trapping focus is not dependent on document direction');
|
||||
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
||||
});
|
||||
|
||||
test('should trap focus with overlays', async ({ page, browserName }) => {
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#open-menu-button');
|
||||
await ionDidOpen.next();
|
||||
|
||||
const menu = await page.locator('#menu');
|
||||
await expect(menu).toBeFocused();
|
||||
|
||||
const openModalButton = await page.locator('#open-modal-button');
|
||||
await openModalButton.click();
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = await page.locator('#modal');
|
||||
await expect(modal).toBeFocused();
|
||||
|
||||
await modal.evaluate(async (el: HTMLIonModalElement) => {
|
||||
await el.dismiss();
|
||||
});
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
// Safari focuses the body after the modal is dismissed
|
||||
if (browserName !== 'webkit') {
|
||||
await expect(openModalButton).toBeFocused();
|
||||
}
|
||||
});
|
||||
|
||||
test('should trap focus with content inside overlays', async ({ page }) => {
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
|
||||
await page.click('#open-menu-button');
|
||||
await ionDidOpen.next();
|
||||
|
||||
const menu = await page.locator('#menu');
|
||||
await expect(menu).toBeFocused();
|
||||
|
||||
await page.click('#open-modal-button');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = await page.locator('#modal');
|
||||
await expect(modal).toBeFocused();
|
||||
});
|
||||
|
||||
test('should work with swipe gestures after modal is dismissed', async ({ page }) => {
|
||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
|
||||
await page.click('#open-menu-button');
|
||||
await ionDidOpen.next();
|
||||
|
||||
const menu = await page.locator('#menu');
|
||||
await expect(menu).toBeFocused();
|
||||
|
||||
await page.click('#open-modal-button');
|
||||
await ionModalDidPresent.next();
|
||||
|
||||
const modal = await page.locator('#modal');
|
||||
|
||||
await modal.evaluate(async (el: HTMLIonModalElement) => {
|
||||
await el.dismiss();
|
||||
});
|
||||
await ionModalDidDismiss.next();
|
||||
|
||||
await page.mouse.move(30, 168);
|
||||
await page.mouse.down();
|
||||
|
||||
await page.mouse.move(384, 168);
|
||||
await page.mouse.up();
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(menu).toHaveClass(/show-menu/);
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { testMenu } from '../test.utils';
|
||||
|
||||
const DIRECTORY = 'standalone';
|
||||
|
||||
test('menu: start standalone', async () => {
|
||||
await testMenu(DIRECTORY, '#start-menu');
|
||||
});
|
||||
|
||||
test('menu: end standalone', async () => {
|
||||
await testMenu(DIRECTORY, '#end-menu');
|
||||
});
|
||||
@@ -1,85 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Menu - Standalone</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<link href="../../../../../css/core.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<script type="module">
|
||||
import { menuController } from '../../../../dist/ionic/index.esm.js';
|
||||
window.menuController = menuController;
|
||||
</script>
|
||||
<style>
|
||||
.ion-page ion-content {
|
||||
--padding-top: 16px;
|
||||
--padding-end: 16px;
|
||||
--padding-bottom: 16px;
|
||||
--padding-start: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-menu side="start" id="start-menu" content-id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Start Menu</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-menu side="end" type="push" id="end-menu" content-id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>End Menu</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
<ion-item>Menu Item</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<div class="ion-page" id="main">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Menu - Standalone</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-button expand="block" onclick="openStart()">Open Start Menu</ion-button>
|
||||
<ion-button expand="block" onclick="openEnd()">Open End Menu</ion-button>
|
||||
</ion-content>
|
||||
</div>
|
||||
<script>
|
||||
function openStart() {
|
||||
menuController.open('start');
|
||||
}
|
||||
|
||||
function openEnd() {
|
||||
menuController.open('end');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
import { generateE2EUrl } from '@utils/test';
|
||||
|
||||
import { menuController } from '../../../utils/menu-controller';
|
||||
|
||||
export const testMenu = async (type: string, selector: string, menuId = '', rtl = false) => {
|
||||
try {
|
||||
const pageUrl = generateE2EUrl('menu', type, rtl);
|
||||
|
||||
const page = await newE2EPage({
|
||||
url: pageUrl,
|
||||
});
|
||||
|
||||
const screenshotCompares = [];
|
||||
|
||||
if (menuId.length > 0) {
|
||||
await menuController.enable(true, menuId);
|
||||
}
|
||||
|
||||
const menu = await page.find(selector);
|
||||
|
||||
await menu.callMethod('open');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
await menu.callMethod('close');
|
||||
await page.waitForTimeout(250);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot('dismiss'));
|
||||
|
||||
for (const screenshotCompare of screenshotCompares) {
|
||||
expect(screenshotCompare).toMatchScreenshot();
|
||||
}
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||