feat(clickTtPlayerRegistrationService): enhance login flow and consent handling

- Added a new constant for the Click-TT login URL to streamline navigation during the login process.
- Improved the login flow by directly navigating to the login URL if no direct login fields are found, enhancing user experience.
- Introduced a method to dismiss consent overlays, improving the automation of the registration process by handling consent banners effectively.
This commit is contained in:
Torsten Schulz (local)
2026-03-11 15:36:24 +01:00
parent 8fc754c235
commit 2ddb63b932

View File

@@ -5,6 +5,7 @@ import { checkAccess } from '../utils/userUtils.js';
import HttpError from '../exceptions/HttpError.js';
const CLICKTT_ENTRY_URL = 'https://httv.click-tt.de/';
const CLICKTT_LOGIN_URL = 'https://httv.click-tt.de/cgi-bin/WebObjects/nuLigaTTDE.woa/wa/login?federation=HeTTV&region=DE';
const TRACE_LIMIT = 250;
function formatGermanDate(value) {
@@ -219,20 +220,13 @@ class ClickTtPlayerRegistrationService {
this._trace(trace, 'step', { name: 'open-entry', url: CLICKTT_ENTRY_URL });
await page.goto(CLICKTT_ENTRY_URL, { waitUntil: 'domcontentloaded', timeout: 45000 });
await this._dismissConsentOverlays(page, trace);
const directLoginOrAuth = page.locator('input[name="email"], input[name="password"]').first();
const loginLinkCandidates = [
page.getByRole('link', { name: /login|anmelden/i }).first(),
page.locator('a[href*="oauth2/authz"], a[href*="oAuthLogin"], a[href*="login"]').first()
];
if (!(await directLoginOrAuth.count())) {
for (const locator of loginLinkCandidates) {
if (await locator.count()) {
this._trace(trace, 'step', { name: 'click-login-entry' });
await locator.click();
await page.waitForLoadState('domcontentloaded');
break;
}
}
this._trace(trace, 'step', { name: 'open-login-entry', url: CLICKTT_LOGIN_URL });
await page.goto(CLICKTT_LOGIN_URL, { waitUntil: 'domcontentloaded', timeout: 45000 });
await this._dismissConsentOverlays(page, trace);
}
const needsLogin = await page.locator('input[name="email"], input[name="password"]').count();
@@ -256,6 +250,30 @@ class ClickTtPlayerRegistrationService {
await page.waitForURL(/click-tt\.de/, { timeout: 60000 });
}
async _dismissConsentOverlays(page, trace) {
const candidates = [
page.getByRole('button', { name: /akzeptieren|accept|zustimmen/i }).first(),
page.locator('#cmpwelcomebtnyes').first(),
page.locator('[id*="cmp"][class*="button"]:has-text("Akzeptieren")').first(),
page.locator('button:has-text("Akzeptieren")').first()
];
for (const locator of candidates) {
try {
if (await locator.count()) {
this._trace(trace, 'step', { name: 'dismiss-consent-banner' });
await locator.click({ timeout: 2000 });
await page.waitForTimeout(300);
return true;
}
} catch (_error) {
// ignore and continue with next selector
}
}
return false;
}
async _fillSearchForm(page, member) {
await this._fillFirstAvailable(page, [
'input[name*=".1"]',