diff --git a/src/teampulse/resolver.py b/src/teampulse/resolver.py index 5811caf..38e9cd3 100644 --- a/src/teampulse/resolver.py +++ b/src/teampulse/resolver.py @@ -106,52 +106,44 @@ class Resolver: print(f" '{display_name}' via '{strategy}' geklickt — warte auf Dialog...") - print(f" Warte auf E-Mail-Adresse im Dialog (bis 30s)...") - try: - # Wait directly for an email address to appear in the lpc-card light DOM. - # This covers both slow dialog opening AND slow content loading. - self._page.wait_for_function( - r"""() => { - const card = document.querySelector('.lpc_ip_root_class lpc-card'); - if (!card) return false; - const EMAIL_RE = /[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/; - if (EMAIL_RE.test(card.textContent)) return true; - if (card.shadowRoot && EMAIL_RE.test(card.shadowRoot.textContent)) return true; - return false; - }""", - timeout=30_000, - ) - except Exception: - card_text = self._page.evaluate("""() => { - const card = document.querySelector('.lpc_ip_root_class lpc-card'); - if (!card) return '(kein lpc-card)'; - return card.textContent.trim().substring(0, 200); - }""") or "(leer)" - print(f" Profil-Dialog Timeout — Light-DOM-Inhalt: {card_text!r}") - self._page.keyboard.press("Escape") - return None + # Do NOT poll with wait_for_selector/wait_for_function — + # Playwright's JS polling blocks Teams' async loading of the dialog. + # Simply wait for the dialog to load without interference. + time.sleep(5) try: email = self._page.evaluate(r"""() => { const EMAIL_RE = /[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/; const card = document.querySelector('.lpc_ip_root_class lpc-card'); - if (!card) return null; - // Light DOM (slotted content) + if (!card) return '__NO_CARD__'; + // Light DOM (slotted content inserted into elements) const lightLink = card.querySelector('a[href*="mailto:"]'); if (lightLink) return lightLink.href.replace('mailto:', '').trim(); const lightMatch = card.textContent.match(EMAIL_RE); if (lightMatch) return lightMatch[0]; - // Shadow root + // Shadow root fallback if (card.shadowRoot) { const shadowMatch = card.shadowRoot.textContent.match(EMAIL_RE); if (shadowMatch) return shadowMatch[0]; } - return null; + return '__NO_EMAIL__' + card.textContent.trim().substring(0, 200); }""") + + if not email or email == '__NO_CARD__': + print(f" Kein Profil-Dialog erschienen.") + self._page.keyboard.press("Escape") + return None + + if email.startswith('__NO_EMAIL__'): + print(f" Dialog offen, E-Mail nicht gefunden. Inhalt: {email[12:150]!r}") + self._page.keyboard.press("Escape") + return None + self._page.keyboard.press("Escape") time.sleep(0.3) - return email or None + return email + except Exception as e: - print(f" Fehler beim Lesen: {e}") + print(f" Fehler beim Lesen des Profil-Dialogs: {e}") self._page.keyboard.press("Escape") return None