fix: use hover() instead of click() to trigger Teams profile hover card

This commit is contained in:
Oliver Hofmann 2026-05-17 15:07:37 +02:00
parent 00bbd196bf
commit badb2f698d

View File

@ -45,31 +45,30 @@ class Resolver:
encoding="utf-8", encoding="utf-8",
) )
def _find_and_click_sender(self, display_name: str) -> bool: def _hover_sender(self, display_name: str) -> bool:
"""Find the sender in the visible chat and click to open their profile card.""" """Find the sender's avatar in the visible chat and hover to open the profile card."""
# Strategy 1: find reply-message-header containing the name, click its avatar # Strategy 1: reply-message-header (channel meetings) — hover the avatar
for header in self._page.query_selector_all("[data-tid='reply-message-header']"): for header in self._page.query_selector_all("[data-tid='reply-message-header']"):
try: try:
name_spans = header.query_selector_all("span") for span in header.query_selector_all("span"):
for span in name_spans:
if span.inner_text().strip() == display_name: if span.inner_text().strip() == display_name:
avatar = header.query_selector( avatar = header.query_selector(
"[data-tid='reply-message-header-avatar']" "[data-tid='reply-message-header-avatar']"
) )
target = avatar or span target = avatar or span
target.scroll_into_view_if_needed() target.scroll_into_view_if_needed()
target.click() target.hover()
return True return True
except Exception: except Exception:
continue continue
# Strategy 2: message-author-name (private meeting chat) # Strategy 2: message-author-name (private meeting chat) — hover the element
for el in self._page.query_selector_all("[data-tid='message-author-name']"): for el in self._page.query_selector_all("[data-tid='message-author-name']"):
try: try:
if el.inner_text().strip() == display_name: if el.inner_text().strip() == display_name:
el.scroll_into_view_if_needed() el.scroll_into_view_if_needed()
el.click() el.hover()
return True return True
except Exception: except Exception:
continue continue
@ -78,21 +77,21 @@ class Resolver:
def _extract_email_from_profile(self, display_name: str) -> str | None: def _extract_email_from_profile(self, display_name: str) -> str | None:
try: try:
clicked = self._find_and_click_sender(display_name) hovered = self._hover_sender(display_name)
except Exception as e: except Exception as e:
print(f" Klick auf '{display_name}' fehlgeschlagen: {e}") print(f" Hover auf '{display_name}' fehlgeschlagen: {e}")
return None return None
if not clicked: if not hovered:
print(f" '{display_name}' nicht im sichtbaren Chat gefunden.") print(f" '{display_name}' nicht im sichtbaren Chat gefunden.")
return None return None
try: try:
# Wait for profile card container # Wait for hover card container
self._page.wait_for_selector(".lpc_ip_root_class", timeout=5000) self._page.wait_for_selector(".lpc_ip_root_class", timeout=5000)
except Exception: except Exception:
print(f" Profilkarte für '{display_name}' öffnet sich nicht.") print(f" Hover-Card für '{display_name}' erscheint nicht.")
self._page.keyboard.press("Escape") self._page.mouse.move(0, 0)
return None return None
try: try:
@ -116,11 +115,12 @@ class Resolver:
card_text = card.inner_text().strip()[:200] if card else "(leer)" card_text = card.inner_text().strip()[:200] if card else "(leer)"
print(f" Karte geöffnet, E-Mail nicht gefunden. Inhalt: {card_text!r}") print(f" Karte geöffnet, E-Mail nicht gefunden. Inhalt: {card_text!r}")
self._page.keyboard.press("Escape") # Dismiss by moving mouse away
self._page.mouse.move(0, 0)
time.sleep(0.5) time.sleep(0.5)
return email return email
except Exception as e: except Exception as e:
print(f" Fehler beim Lesen der Profilkarte: {e}") print(f" Fehler beim Lesen der Hover-Card: {e}")
self._page.keyboard.press("Escape") self._page.mouse.move(0, 0)
return None return None