diff --git a/backend/clients/myTischtennisClient.js b/backend/clients/myTischtennisClient.js index 9f6260ed..483034ef 100644 --- a/backend/clients/myTischtennisClient.js +++ b/backend/clients/myTischtennisClient.js @@ -365,11 +365,9 @@ class MyTischtennisClient { }); context = await browser.newContext(); const page = await context.newPage(); - await page.goto(`${this.baseURL}/login?next=%2F`, { waitUntil: 'domcontentloaded', timeout: 45000 }); - console.log('[myTischtennisClient.playwright] Page loaded'); - // Dismiss CMP/consent dialog. The dialog can appear with a delay, so we wait - // briefly for it and try multiple selectors including the explicit "Akzeptieren" button. + // Helper: click the CMP/consent "Akzeptieren" button if visible. + // Tries multiple selectors to cover different CMP implementations. const acceptConsentDialog = async (waitMs = 0) => { if (waitMs > 0) await page.waitForTimeout(waitMs); const consentSelectors = [ @@ -388,23 +386,35 @@ class MyTischtennisClient { if (await button.count()) { await button.click({ timeout: 2500 }); console.log('[myTischtennisClient.playwright] Consent dialog accepted via:', selector); - await page.waitForTimeout(600); + await page.waitForTimeout(800); return true; } } catch (_e) { - // ignore, try next selector + // try next selector } } return false; }; - // First attempt immediately after page load. - const consentAcceptedEarly = await acceptConsentDialog(0); - // Second attempt with a short delay if not accepted yet (CMP often renders async). - if (!consentAcceptedEarly) { - await acceptConsentDialog(2500); + // Visit the homepage first so the browser receives and stores the correct CMP + // consent cookies (the TCF v2 format cannot be guessed and set manually). + // After accepting consent here, the login page will not show the banner again. + try { + await page.goto(this.baseURL, { waitUntil: 'domcontentloaded', timeout: 30000 }); + const acceptedOnHome = await acceptConsentDialog(0); + if (!acceptedOnHome) await acceptConsentDialog(2500); + console.log('[myTischtennisClient.playwright] Homepage visited, consent handled'); + } catch (_homeErr) { + console.log('[myTischtennisClient.playwright] Homepage pre-visit failed (continuing):', _homeErr.message); } + await page.goto(`${this.baseURL}/login?next=%2F`, { waitUntil: 'domcontentloaded', timeout: 45000 }); + console.log('[myTischtennisClient.playwright] Login page loaded'); + + // Second consent attempt in case it re-appears on the login page. + const consentOnLogin = await acceptConsentDialog(0); + if (!consentOnLogin) await acceptConsentDialog(1500); + // Fill credentials await page.locator('input[name="email"]').first().fill(email, { timeout: 10000 }); await page.locator('input[name="password"]').first().fill(password, { timeout: 10000 }); @@ -594,8 +604,10 @@ class MyTischtennisClient { break; } - // Probe page text periodically to fail fast instead of waiting full timeout. + // Periodically: dismiss consent banner (may reappear after submit redirect) + // and probe page text to fail fast on known error strings. if (attempt % 4 === 0) { + try { await acceptConsentDialog(0); } catch (_e) { /* ignore */ } try { const textContent = await page.locator('body').innerText({ timeout: 600 }); if (textContent?.includes('Captcha-Bestätigung fehlgeschlagen')) {