Skip to content

Commit 8d886ed

Browse files
committed
add check if mobile menu is open before clicking it
1 parent 99d43ff commit 8d886ed

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

src/support/steps/general.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { ICustomWorld } from "../../common/custom-world";
1616
import { Given, When, Then } from '@cucumber/cucumber';
1717
import {WP_BASE_URL} from '../../../config/wp.config';
1818
import scenarioUrls from "./../../../config/scenarioUrls.json";
19-
import { compareReference, isTagPresent, getScenarioTag, batchUpdateVRTestUrl, openMobileMenu} from "../../../utils/helpers";
19+
import { compareReference, isTagPresent, getScenarioTag, batchUpdateVRTestUrl, openMobileMenu, isMobileMenuOpen, isMobileMenuOpenSimple} from "../../../utils/helpers";
2020
import type { Section } from "../../../utils/types";
2121
import { Page, ConsoleMessage } from '@playwright/test';
2222
import {
@@ -296,8 +296,8 @@ When('expand mobile menu and validate no console error', async function (this:IC
296296
const theme = process.env.THEME ? process.env.THEME : '';
297297

298298
// Get console messages when expanding menu on both versions
299-
const consoleMsg1 = await getConsoleMsgWithMenuExpansion(this.page, `${WP_BASE_URL}/?nowprocket`);
300299
const consoleMsg2 = await getConsoleMsgWithMenuExpansion(this.page, `${WP_BASE_URL}/`);
300+
const consoleMsg1 = await getConsoleMsgWithMenuExpansion(this.page, `${WP_BASE_URL}/?nowprocket`);
301301

302302
// Compare console messages
303303
try {
@@ -572,8 +572,16 @@ const getConsoleMsgWithMenuExpansion = async (page: Page, url: string): Promise<
572572
});
573573

574574
await page.goto(url);
575+
575576
await page.waitForLoadState('load', { timeout: 30000 });
576-
577+
578+
await page.mouse.move(0, 0); await page.mouse.down(); await page.mouse.up(); // full user gesture
579+
580+
// Check if mobile menu is already open
581+
const menuAlreadyOpen = await isMobileMenuOpen(page);
582+
if (menuAlreadyOpen) {
583+
throw new Error('Mobile menu is already open before attempting to open it');
584+
}
577585
// Open the mobile menu using the helper function
578586
try {
579587
await openMobileMenu(page);

utils/helpers.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,71 @@ export const isWprRelatedError = async(contents: string): Promise<boolean> => {
589589
return false;
590590
}
591591

592+
593+
/**
594+
* Checks if the mobile menu is currently open
595+
* This is useful for validating mobile menu state before attempting to open it
596+
*
597+
* @param {Page} page - The Playwright page instance to check
598+
* @returns {Promise<boolean>} - A Promise that resolves to true if menu is open, false otherwise
599+
*
600+
* @example
601+
* ```typescript
602+
* const isOpen = await isMobileMenuOpen(page);
603+
* if (isOpen) {
604+
* console.log('Menu is already open');
605+
* }
606+
* ```
607+
*/
608+
export const isMobileMenuOpen = async (page: Page): Promise<boolean> => {
609+
await page.waitForTimeout(5000);
610+
return await page.evaluate(() => {
611+
const candidates = Array.from(document.querySelectorAll<HTMLElement>(
612+
'nav, .mobile-menu, .mobile-navigation, #mobile-menu, .et_mobile_menu, [id*=mobile-menu]'
613+
));
614+
615+
for (const menu of candidates) {
616+
const style = window.getComputedStyle(menu);
617+
const rect = menu.getBoundingClientRect();
618+
619+
// Skip invisible elements
620+
if (
621+
style.display === 'none' ||
622+
style.visibility === 'hidden' ||
623+
Number(style.opacity) === 0
624+
) continue;
625+
626+
// Check if there is a transform
627+
const transform = style.transform;
628+
if (transform && transform !== 'none') {
629+
// Parse the matrix and check if it's fully translated offscreen
630+
const values = transform.match(/matrix.*\((.+)\)/)?.[1].split(',').map(Number);
631+
if (values) {
632+
const translateX = values.length === 6 ? values[4] : 0;
633+
const translateY = values.length === 6 ? values[5] : 0;
634+
635+
// If fully off-screen, menu is closed
636+
if (translateX <= -window.innerWidth || translateY <= -window.innerHeight) continue;
637+
}
638+
}
639+
640+
// Check if element is large enough to be considered open
641+
const coversScreen = rect.width >= window.innerWidth * 0.3 && rect.height >= window.innerHeight * 0.3;
642+
if (coversScreen) return true;
643+
}
644+
645+
// Fallback: toggle button aria-expanded
646+
const toggles = document.querySelectorAll<HTMLElement>(
647+
'.menu-toggle, .nav-toggle, .hamburger, .mobile_menu_bar, .et_mobile_menu'
648+
);
649+
for (const toggle of toggles) {
650+
if (toggle.getAttribute('aria-expanded') === 'true') return true;
651+
}
652+
653+
return false;
654+
});
655+
};
656+
592657
/**
593658
* Opens the mobile menu by finding and clicking toggle buttons
594659
* This is useful for testing mobile menu functionality

0 commit comments

Comments
 (0)