Fix: mobile menu backdrop fails to dismiss modal (#37430)

* Fix: mobile menu backdrop fails to dismiss modal

* test: add mobile RHS focus functional spec

* fix: stabilize mobile RHS focus tests and handle keyboard trap

* fix: refine mobile menu tests and scope focus trap to backdrop interaction

* e2e: test mobile menu backdrop dismissal with click action

* style: fix trailing whitespace and missing eol newline

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Yashveer Singh
2026-08-04 09:53:46 -04:00
committed by GitHub
co-authored by Mattermost Build
parent cd920652fb
commit ddffe7896e
4 changed files with 43 additions and 3 deletions
@@ -30,8 +30,14 @@ export default class ChannelsHeader {
}
async openChannelMenu() {
await this.channelMenuDropdown.isVisible();
await this.channelMenuDropdown.click();
const page = this.container.page();
const mobileMenuButton = page.locator('#navbar #channelHeaderDropdownButton');
const mobileVisible = await mobileMenuButton.isVisible({timeout: 1000}).catch(() => false);
const menuButton = mobileVisible ? mobileMenuButton : this.channelMenuDropdown;
await expect(menuButton).toBeVisible();
await menuButton.scrollIntoViewIfNeeded();
await menuButton.click();
}
async openCalls() {
@@ -73,6 +73,33 @@ test.describe('Mobile view RHS auto-focus', () => {
await expect(channelsPage.sidebarRight.mobileSearchInput).toBeFocused();
});
/**
* @objective Tapping the mobile menu backdrop should dismiss/close the modal
*/
test('closes mobile menu when clicking the backdrop layer', {tag: '@mobile'}, async ({pw}) => {
const {user} = await pw.initSetup();
// # Log in as the test user and navigate to channels page
const {channelsPage, page} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
// # Open the mobile channel header menu
await channelsPage.centerView.header.openChannelMenu();
// # Define the mobile menu modal locator
const menuModal = page.locator('.modal-dialog.menuModal');
// * Verify the menu modal is visible after the click
await expect(menuModal).toBeVisible();
// # Click the modal's backdrop layer outside the menu content
await page.mouse.click(5, 5);
// * Verify the mobile menu modal is now successfully dismissed/hidden
await expect(menuModal).toBeHidden();
});
/**
* @objective Verify that in narrow/mobile view, the channel header shows an icon-only Search
* button; clicking it opens the RHS search panel where a search can be performed, and closing
@@ -20,6 +20,14 @@
}
}
.modal-dialog.menuModal {
pointer-events: none;
}
.modal-dialog.menuModal .modal-content {
pointer-events: auto;
}
.menuModal {
& .modal-header {
display: none;
@@ -198,7 +198,6 @@ function isElementVisible(element: HTMLElement): boolean {
if (
style.display === 'none' ||
style.visibility === 'hidden' ||
style.pointerEvents === 'none' ||
currentElement.hasAttribute('hidden')
) {
return false;