from typing import Callable, Optional, Sequence
from playwright.sync_api import Page
from . import config
def is_logged_in(page: Page, indicators: Optional[Sequence[str]] = None) -> bool:
for text in indicators or config.LOGGED_IN_INDICATORS:
if page.get_by_text(text, exact=False).count() > 0:
return True
return False
def wait_for_login(
page: Page,
timeout_s: int = 180,
log: Callable[[str], None] = print,
indicators: Optional[Sequence[str]] = None,
) -> None:
"""Väntar tills sidan visar inloggad status.
Vilken text som räknas som "inloggad" avgörs av `indicators` om det
anges, annars faller det tillbaka på config.LOGGED_IN_INDICATORS. I
webui:t sätts detta per flöde/steg (steget "Vänta på inloggning") så
olika sajter kan ha olika text utan att röra config.py.
Om redan inloggad returnerar direkt. Annars pollar tills tidsgränsen
slår till, medan du godkänner BankID manuellt i telefonen.
"""
if is_logged_in(page, indicators):
log("Redan inloggad (återanvänd session).")
return
log(
"Ej inloggad. Logga in manuellt i webbläsarfönstret som öppnades "
"(välj BankID och godkänn i appen). Väntar automatiskt upp till "
f"{timeout_s} sekunder."
)
poll_interval_s = 2
waited = 0
while waited < timeout_s:
if is_logged_in(page, indicators):
log("Inloggning klar.")
return
page.wait_for_timeout(poll_interval_s * 1000)
waited += poll_interval_s
raise TimeoutError(
"Ingen inloggning upptäcktes inom tidsgränsen. Höj timeout eller "
"kontrollera indikatortexterna (steget \"Vänta på inloggning\" i "
"flödet, annars config.LOGGED_IN_INDICATORS) mot faktisk sidtext "
"(kör python -m rpa.discover)."
)
def ensure_logged_in(page: Page, bankid_timeout_s: int = 180) -> None:
"""Bakåtkompatibel wrapper: navigerar till startsidan och loggar in."""
page.goto(config.START_URL, wait_until="domcontentloaded")
wait_for_login(page, bankid_timeout_s)