Skip to content

Commit 2c36049

Browse files
test(menu): migrate to playwright (#26187)
1 parent 9216744 commit 2c36049

File tree

48 files changed

+246
-341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+246
-341
lines changed

core/src/components/menu/test/a11y/e2e.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

core/src/components/menu/test/a11y/index.html

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,36 @@
22
<html lang="en" dir="ltr">
33
<head>
44
<meta charset="UTF-8" />
5-
<title>Segment - a11y</title>
5+
<title>Menu - a11y</title>
66
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
77
<link href="../../../../../css/core.css" rel="stylesheet" />
88
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
99
<script src="../../../../../scripts/testing/scripts.js"></script>
1010
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
1111
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
12+
<script type="module">
13+
import { menuController } from '../../../../dist/ionic/index.esm.js';
14+
window.menuController = menuController;
15+
</script>
1216
</head>
1317

1418
<body>
1519
<main>
16-
<h1>Menu</h1>
20+
<div class="ion-page" id="main-content">
21+
<ion-content class="ion-padding">
22+
<h1>Menu</h1>
23+
<ion-button id="open-menu" expand="block" onclick="openMenu()">Open Menu</ion-button>
24+
</ion-content>
25+
</div>
26+
1727
<ion-menu menu-id="menu" content-id="main-content">
1828
<ion-header>
1929
<ion-toolbar>
2030
<ion-title>Menu</ion-title>
2131
</ion-toolbar>
2232
</ion-header>
2333
<ion-content>
34+
<h1 class="ion-margin">Open Menu</h1>
2435
<ion-list>
2536
<ion-item>
2637
<ion-button>Button</ion-button>
@@ -35,5 +46,12 @@ <h1>Menu</h1>
3546
</ion-content>
3647
</ion-menu>
3748
</main>
49+
50+
<script>
51+
async function openMenu() {
52+
await menuController.enable(true, 'menu');
53+
await menuController.open('menu');
54+
}
55+
</script>
3856
</body>
3957
</html>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import AxeBuilder from '@axe-core/playwright';
2+
import { expect } from '@playwright/test';
3+
import { test } from '@utils/test/playwright';
4+
5+
test.describe('menu: a11y', () => {
6+
test.beforeEach(async ({ skip }) => {
7+
skip.rtl();
8+
skip.mode('md');
9+
});
10+
11+
test('menu should not have accessibility violations', async ({ page }) => {
12+
await page.goto(`/src/components/menu/test/a11y`);
13+
14+
const menu = page.locator('ion-menu');
15+
const button = page.locator('#open-menu');
16+
17+
await button.click();
18+
await page.waitForSelector('ion-menu', { state: 'visible' });
19+
20+
await expect(menu).toHaveAttribute('role', 'navigation');
21+
22+
const heading = page.locator('ion-menu h1');
23+
await expect(heading).toHaveText('Open Menu');
24+
25+
const results = await new AxeBuilder({ page }).analyze();
26+
expect(results.violations).toEqual([]);
27+
});
28+
});

core/src/components/menu/test/basic/e2e.ts

Lines changed: 0 additions & 81 deletions
This file was deleted.

core/src/components/menu/test/basic/index.html

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@
1212
<script src="../../../../../scripts/testing/scripts.js"></script>
1313
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
1414
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
15-
<script>
16-
const forceCSSAnimations = new URLSearchParams(window.location.search).get('ionic:_forceCSSAnimations');
17-
if (forceCSSAnimations) {
18-
window.Animation = null;
19-
}
20-
</script>
2115
<script type="module">
2216
import { menuController } from '../../../../dist/ionic/index.esm.js';
2317
window.menuController = menuController;
@@ -28,8 +22,8 @@
2822
<ion-app>
2923
<ion-menu
3024
side="start"
31-
menu-id="first"
3225
id="start-menu"
26+
menu-id="start-menu"
3327
content-id="main"
3428
class="menu-part"
3529
aria-label="start menu"
@@ -68,7 +62,7 @@
6862
</ion-content>
6963
</ion-menu>
7064

71-
<ion-menu side="start" menu-id="custom" class="my-custom-menu" id="custom-menu" content-id="main">
65+
<ion-menu side="start" menu-id="custom-menu" content-id="main" class="my-custom-menu">
7266
<ion-header>
7367
<ion-toolbar color="tertiary">
7468
<ion-title>Custom Menu</ion-title>
@@ -85,7 +79,7 @@
8579
</ion-content>
8680
</ion-menu>
8781

88-
<ion-menu side="end" type="push" id="end-menu" content-id="main">
82+
<ion-menu side="end" menu-id="end-menu" content-id="main" type="push">
8983
<ion-header>
9084
<ion-toolbar color="danger">
9185
<ion-title>End Menu</ion-title>
@@ -109,9 +103,9 @@
109103
</ion-toolbar>
110104
</ion-header>
111105
<ion-content class="ion-padding">
112-
<ion-button expand="block" id="open-first" onclick="openFirst()">Open Start Menu</ion-button>
113-
<ion-button expand="block" onclick="openEnd()">Open End Menu</ion-button>
114-
<ion-button expand="block" onclick="openCustom()">Open Custom Menu</ion-button>
106+
<ion-button expand="block" id="open-start" onclick="openStart()">Open Start Menu</ion-button>
107+
<ion-button expand="block" id="open-end" onclick="openEnd()">Open End Menu</ion-button>
108+
<ion-button expand="block" id="open-custom" onclick="openCustom()">Open Custom Menu</ion-button>
115109
</ion-content>
116110
</div>
117111
</ion-app>
@@ -133,18 +127,21 @@
133127
</style>
134128

135129
<script>
136-
async function openFirst() {
137-
await menuController.enable(true, 'first');
138-
await menuController.open('first');
130+
async function openStart() {
131+
// Open the menu by menu-id
132+
await menuController.enable(true, 'start-menu');
133+
await menuController.open('start-menu');
139134
}
140135

141136
async function openEnd() {
137+
// Open the menu by side
142138
await menuController.open('end');
143139
}
144140

145141
async function openCustom() {
146-
await menuController.enable(true, 'custom');
147-
await menuController.open('custom');
142+
// Open the menu by menu-id
143+
await menuController.enable(true, 'custom-menu');
144+
await menuController.open('custom-menu');
148145
}
149146
</script>
150147
</body>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import type { Locator } from '@playwright/test';
2+
import { expect } from '@playwright/test';
3+
import type { E2EPage } from '@utils/test/playwright';
4+
import { test } from '@utils/test/playwright';
5+
6+
test.describe('menu: basic', () => {
7+
test.beforeEach(async ({ page }) => {
8+
await page.goto(`/src/components/menu/test/basic`);
9+
});
10+
11+
test('should open selected menu by side', async ({ page }) => {
12+
const startMenu = page.locator('[menu-id="start-menu"]');
13+
const customMenu = page.locator('[menu-id="custom-menu"]');
14+
const endMenu = page.locator('[menu-id="end-menu"]');
15+
16+
await testMenu(page, startMenu, 'start');
17+
await testMenu(page, customMenu, 'custom');
18+
await testMenu(page, endMenu, 'end');
19+
});
20+
21+
test('should trap focus', async ({ page, skip, browserName }) => {
22+
skip.rtl('Trapping focus is not dependent on document direction');
23+
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
24+
25+
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
26+
27+
await page.click('#open-start');
28+
await ionDidOpen.next();
29+
30+
const button = await page.locator('#start-menu-button');
31+
32+
if (browserName === 'webkit') {
33+
await page.keyboard.down('Alt');
34+
}
35+
36+
await page.keyboard.press('Tab');
37+
38+
await expect(button).toBeFocused();
39+
40+
await page.keyboard.press('Tab');
41+
42+
if (browserName === 'webkit') {
43+
await page.keyboard.up('Alt');
44+
}
45+
46+
await expect(button).toBeFocused();
47+
});
48+
49+
test('should preserve scroll position', async ({ page, skip }) => {
50+
skip.rtl('Scroll position is not dependent on document direction');
51+
skip.browser('firefox', 'Firefox does not preserve scroll position');
52+
53+
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
54+
55+
await page.click('#open-start');
56+
await ionDidOpen.next();
57+
58+
await page.locator('#start-menu ion-content').evaluate(async (el: HTMLIonContentElement) => {
59+
await el.scrollToPoint(0, 200);
60+
});
61+
62+
await page.locator('#start-menu').evaluate(async (el: HTMLIonMenuElement) => {
63+
await el.close();
64+
});
65+
66+
await page.click('#open-start');
67+
await ionDidOpen.next();
68+
69+
const scrollTop = await page.locator('#start-menu ion-content').evaluate(async (el: HTMLIonContentElement) => {
70+
const contentScrollEl = await el.getScrollElement();
71+
return contentScrollEl.scrollTop;
72+
});
73+
74+
await expect(scrollTop).toBe(200);
75+
});
76+
});
77+
78+
async function testMenu(page: E2EPage, menu: Locator, menuId: string) {
79+
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
80+
const ionDidClose = await page.spyOnEvent('ionDidClose');
81+
82+
await page.click(`#open-${menuId}`);
83+
await ionDidOpen.next();
84+
85+
await expect(menu).toHaveClass(/show-menu/);
86+
87+
expect(await page.screenshot()).toMatchSnapshot(`menu-basic-${menuId}-${page.getSnapshotSettings()}.png`);
88+
89+
await menu.evaluate(async (el: HTMLIonMenuElement) => {
90+
await el.close();
91+
});
92+
await ionDidClose.next();
93+
}

0 commit comments

Comments
 (0)