| 
1 | 1 | import type { Locator } from '@playwright/test';  | 
2 | 2 | import { expect } from '@playwright/test';  | 
3 | 3 | import type { E2EPage, ScreenshotFn } from '@utils/test/playwright';  | 
4 |  | -import { configs, test } from '@utils/test/playwright';  | 
 | 4 | +import { configs, dragElementBy, test } from '@utils/test/playwright';  | 
5 | 5 | 
 
  | 
6 | 6 | configs().forEach(({ title, config, screenshot }) => {  | 
7 | 7 |   test.describe(title('menu: rendering'), () => {  | 
@@ -140,6 +140,97 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co  | 
140 | 140 |   });  | 
141 | 141 | });  | 
142 | 142 | 
 
  | 
 | 143 | +/**  | 
 | 144 | + * This behavior does not vary across modes/directions  | 
 | 145 | + */  | 
 | 146 | +configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {  | 
 | 147 | +  test.describe(title('menu: events'), () => {  | 
 | 148 | +    test.beforeEach(async ({ page }) => {  | 
 | 149 | +      await page.goto(`/src/components/menu/test/basic`, config);  | 
 | 150 | +    });  | 
 | 151 | + | 
 | 152 | +    test('should pass role when swiping to close', async ({ page }) => {  | 
 | 153 | +      const ionDidOpen = await page.spyOnEvent('ionDidOpen');  | 
 | 154 | +      const ionWillClose = await page.spyOnEvent('ionWillClose');  | 
 | 155 | +      const ionDidClose = await page.spyOnEvent('ionDidClose');  | 
 | 156 | + | 
 | 157 | +      await page.click('#open-start');  | 
 | 158 | +      await ionDidOpen.next();  | 
 | 159 | + | 
 | 160 | +      const menu = page.locator('#start-menu');  | 
 | 161 | +      await dragElementBy(menu, page, -150, 0);  | 
 | 162 | + | 
 | 163 | +      await ionWillClose.next();  | 
 | 164 | +      await ionDidClose.next();  | 
 | 165 | +      await expect(ionWillClose).toHaveReceivedEventDetail({ role: 'gesture' });  | 
 | 166 | +      await expect(ionDidClose).toHaveReceivedEventDetail({ role: 'gesture' });  | 
 | 167 | +    });  | 
 | 168 | + | 
 | 169 | +    test('should pass role when clicking backdrop to close', async ({ page }) => {  | 
 | 170 | +      const ionDidOpen = await page.spyOnEvent('ionDidOpen');  | 
 | 171 | +      const ionWillClose = await page.spyOnEvent('ionWillClose');  | 
 | 172 | +      const ionDidClose = await page.spyOnEvent('ionDidClose');  | 
 | 173 | + | 
 | 174 | +      await page.click('#open-start');  | 
 | 175 | +      await ionDidOpen.next();  | 
 | 176 | + | 
 | 177 | +      const menu = page.locator('#start-menu');  | 
 | 178 | +      const backdrop = menu.locator('ion-backdrop');  | 
 | 179 | + | 
 | 180 | +      /**  | 
 | 181 | +       * Coordinates for the click event.  | 
 | 182 | +       * These need to be near the right edge of the backdrop  | 
 | 183 | +       * in order to avoid clicking on the menu.  | 
 | 184 | +       */  | 
 | 185 | +      const backdropBoundingBox = await backdrop.boundingBox();  | 
 | 186 | +      const x = backdropBoundingBox!.width - 50;  | 
 | 187 | +      const y = backdropBoundingBox!.height - 50;  | 
 | 188 | + | 
 | 189 | +      // Click near the right side of the backdrop.  | 
 | 190 | +      await backdrop.click({  | 
 | 191 | +        position: { x, y },  | 
 | 192 | +      });  | 
 | 193 | + | 
 | 194 | +      await ionWillClose.next();  | 
 | 195 | +      await ionDidClose.next();  | 
 | 196 | +      await expect(ionWillClose).toHaveReceivedEventDetail({ role: 'backdrop' });  | 
 | 197 | +      await expect(ionDidClose).toHaveReceivedEventDetail({ role: 'backdrop' });  | 
 | 198 | +    });  | 
 | 199 | + | 
 | 200 | +    test('should pass role when pressing escape key to close', async ({ page }) => {  | 
 | 201 | +      const ionDidOpen = await page.spyOnEvent('ionDidOpen');  | 
 | 202 | +      const ionWillClose = await page.spyOnEvent('ionWillClose');  | 
 | 203 | +      const ionDidClose = await page.spyOnEvent('ionDidClose');  | 
 | 204 | + | 
 | 205 | +      await page.click('#open-start');  | 
 | 206 | +      await ionDidOpen.next();  | 
 | 207 | + | 
 | 208 | +      await page.keyboard.press('Escape');  | 
 | 209 | + | 
 | 210 | +      await ionWillClose.next();  | 
 | 211 | +      await ionDidClose.next();  | 
 | 212 | +      await expect(ionWillClose).toHaveReceivedEventDetail({ role: 'escape' });  | 
 | 213 | +      await expect(ionDidClose).toHaveReceivedEventDetail({ role: 'escape' });  | 
 | 214 | +    });  | 
 | 215 | + | 
 | 216 | +    test.only('should not pass role when clicking a menu toggle button to close', async ({ page }) => {  | 
 | 217 | +      const ionDidOpen = await page.spyOnEvent('ionDidOpen');  | 
 | 218 | +      const ionWillClose = await page.spyOnEvent('ionWillClose');  | 
 | 219 | +      const ionDidClose = await page.spyOnEvent('ionDidClose');  | 
 | 220 | + | 
 | 221 | +      await page.click('#open-start');  | 
 | 222 | +      await ionDidOpen.next();  | 
 | 223 | + | 
 | 224 | +      await page.click('#start-menu-button');  | 
 | 225 | + | 
 | 226 | +      await ionWillClose.next();  | 
 | 227 | +      await ionDidClose.next();  | 
 | 228 | +      await expect(ionWillClose).toHaveReceivedEventDetail({ role: undefined });  | 
 | 229 | +      await expect(ionDidClose).toHaveReceivedEventDetail({ role: undefined });  | 
 | 230 | +    });  | 
 | 231 | +  });  | 
 | 232 | +});  | 
 | 233 | + | 
143 | 234 | async function testMenu(page: E2EPage, menu: Locator, menuId: string, screenshot: ScreenshotFn) {  | 
144 | 235 |   const ionDidOpen = await page.spyOnEvent('ionDidOpen');  | 
145 | 236 |   const ionDidClose = await page.spyOnEvent('ionDidClose');  | 
 | 
0 commit comments