mirror of
https://github.com/Second-Hand-Friends/kleinanzeigen-bot.git
synced 2026-03-16 12:21:50 +01:00
fix: dismiss GDPR consent banner before publish and login (#873)
This commit is contained in:
@@ -1006,6 +1006,8 @@ class KleinanzeigenBot(WebScrapingMixin): # noqa: PLR0904
|
||||
if getattr(self, "page", None) is not None:
|
||||
LOG.debug("Current page URL after opening homepage: %s", self.page.url)
|
||||
|
||||
await self._dismiss_consent_banner()
|
||||
|
||||
state = await self.get_login_state()
|
||||
if state == LoginState.LOGGED_IN:
|
||||
LOG.info("Already logged in as [%s]. Skipping login.", self.config.login.username)
|
||||
@@ -1085,6 +1087,21 @@ class KleinanzeigenBot(WebScrapingMixin): # noqa: PLR0904
|
||||
# GDPR banner not shown within timeout.
|
||||
pass
|
||||
|
||||
async def _dismiss_consent_banner(self) -> None:
|
||||
"""Dismiss the GDPR/TCF consent banner if it is present.
|
||||
|
||||
This banner can appear on any page navigation (not just after login) and blocks
|
||||
all form interaction until dismissed. Uses a short timeout to avoid slowing down
|
||||
the flow when the banner is already gone.
|
||||
"""
|
||||
try:
|
||||
banner_timeout = self._timeout("quick_dom")
|
||||
await self.web_find(By.ID, "gdpr-banner-accept", timeout = banner_timeout)
|
||||
LOG.debug("Consent banner detected, clicking 'Alle akzeptieren'...")
|
||||
await self.web_click(By.ID, "gdpr-banner-accept")
|
||||
except TimeoutError:
|
||||
pass # Banner not present; nothing to dismiss
|
||||
|
||||
async def _auth_probe_login_state(self) -> LoginState:
|
||||
"""Probe an auth-required endpoint to classify login state.
|
||||
|
||||
@@ -1613,6 +1630,8 @@ class KleinanzeigenBot(WebScrapingMixin): # noqa: PLR0904
|
||||
LOG.info("Updating ad '%s'...", ad_cfg.title)
|
||||
await self.web_open(f"{self.root_url}/p-anzeige-bearbeiten.html?adId={ad_cfg.id}")
|
||||
|
||||
await self._dismiss_consent_banner()
|
||||
|
||||
if loggers.is_debug(LOG):
|
||||
LOG.debug(" -> effective ad meta:")
|
||||
YAML().dump(ad_cfg.model_dump(), sys.stdout)
|
||||
|
||||
@@ -704,6 +704,7 @@ class TestKleinanzeigenBotAuthentication:
|
||||
patch("kleinanzeigen_bot.ainput", new_callable = AsyncMock) as mock_ainput,
|
||||
):
|
||||
# Mock the sequence of web_find calls:
|
||||
# 0. Consent banner not found (in _dismiss_consent_banner, before login state check)
|
||||
# First login attempt:
|
||||
# 1. Captcha iframe found (in check_and_wait_for_captcha)
|
||||
# 2. Phone verification not found (in handle_after_login_logic)
|
||||
@@ -715,6 +716,7 @@ class TestKleinanzeigenBotAuthentication:
|
||||
# 7. Email verification not found (in handle_after_login_logic)
|
||||
# 8. GDPR banner not found (in handle_after_login_logic)
|
||||
mock_find.side_effect = [
|
||||
TimeoutError(), # Consent banner (before login state check)
|
||||
AsyncMock(), # Captcha iframe (first login)
|
||||
TimeoutError(), # Phone verification (first login)
|
||||
TimeoutError(), # Email verification (first login)
|
||||
@@ -731,7 +733,7 @@ class TestKleinanzeigenBotAuthentication:
|
||||
await test_bot.login()
|
||||
|
||||
# Verify the complete flow
|
||||
assert mock_find.call_count == 8 # Exactly 8 web_find calls
|
||||
assert mock_find.call_count == 9 # 1 consent banner + 8 original web_find calls
|
||||
assert mock_ainput.call_count == 2 # Two captcha prompts
|
||||
assert mock_input.call_count == 6 # Two login attempts with username, clear password, and set password
|
||||
assert mock_click.call_count == 2 # Two submit button clicks
|
||||
|
||||
Reference in New Issue
Block a user