Skip to content

Commit 9af4f69

Browse files
committed
check if expanded menu exists before reading its property
1 parent 4f6ba4c commit 9af4f69

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

  • browser_utils/initialization

browser_utils/initialization/core.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -593,16 +593,15 @@ async def _is_temporary_chat_active(page: AsyncPage) -> bool:
593593
'button[aria-label="Toggle temporary chat"]'
594594
)
595595
if await toggle_locator.count() > 0:
596-
toggle_button = toggle_locator.first
597-
598596
# New UI: active state is represented by a checkmark inside the menu item.
599597
try:
600-
checkmark_locator = toggle_button.locator(
601-
"[data-test-incognito-checkmark]"
598+
checkmark_locator = page.locator(
599+
"button[data-test-incognito-toggle] [data-test-incognito-checkmark], "
600+
'button[aria-label="Temporary chat toggle"] [data-test-incognito-checkmark], '
601+
'button[aria-label="Toggle temporary chat"] [data-test-incognito-checkmark]'
602602
)
603603
if (
604604
await checkmark_locator.count() > 0
605-
and await checkmark_locator.first.is_visible(timeout=500)
606605
):
607606
return True
608607
except Exception:
@@ -611,14 +610,14 @@ async def _is_temporary_chat_active(page: AsyncPage) -> bool:
611610
# Legacy/alternative signals.
612611
for attr_name in ("aria-pressed", "aria-checked"):
613612
try:
614-
attr_value = await toggle_button.get_attribute(attr_name)
613+
attr_value = await toggle_locator.get_attribute(attr_name)
615614
if attr_value and attr_value.lower() == "true":
616615
return True
617616
except Exception:
618617
pass
619618

620619
try:
621-
button_classes = await toggle_button.get_attribute("class") or ""
620+
button_classes = await toggle_locator.get_attribute("class") or ""
622621
if "ms-button-active" in button_classes:
623622
return True
624623
except Exception:
@@ -644,6 +643,18 @@ async def enable_temporary_chat_mode(page: AsyncPage) -> bool: # pragma: no cov
644643
incognito_locator = page.locator(incognito_selector)
645644
menu_trigger = page.locator(menu_trigger_selector)
646645

646+
async def _close_menu_if_needed() -> None:
647+
"""Best-effort menu cleanup that tolerates UI variants without a menu trigger."""
648+
try:
649+
if await menu_trigger.count() == 0:
650+
return
651+
if await menu_trigger.is_visible():
652+
if await menu_trigger.get_attribute("aria-expanded") == "true":
653+
logger.debug("[UI] Closing menu to restore UI state")
654+
await page.keyboard.press("Escape")
655+
except Exception:
656+
pass
657+
647658
try:
648659
# Fast path
649660
logger.debug("[UI] Searching for temporary chat button (Fast path)")
@@ -670,17 +681,13 @@ async def enable_temporary_chat_mode(page: AsyncPage) -> bool: # pragma: no cov
670681
enabled = await _is_temporary_chat_active(page)
671682

672683
# Recovery: Close menu if still expanded
673-
# Checking aria-expanded is more precise than a boolean flag
674-
if await menu_trigger.get_attribute("aria-expanded") == "true":
675-
logger.debug("[UI] Closing menu to restore UI state")
676-
await page.keyboard.press("Escape")
684+
await _close_menu_if_needed()
677685
return enabled
678686

679687
except asyncio.CancelledError:
680688
raise
681689
except Exception as e:
682690
logger.warning(f"[UI] Error in temporary chat mode: {e}")
683691
# Final safety attempt to clear any stuck UI
684-
if await menu_trigger.get_attribute("aria-expanded") == "true":
685-
await page.keyboard.press("Escape")
692+
await _close_menu_if_needed()
686693
return await _is_temporary_chat_active(page)

0 commit comments

Comments
 (0)