fix(myTischtennis): enhance CAPTCHA handling and login reliability

- Improved CAPTCHA interaction by adding checks for readiness before form submission, ensuring smoother login processes.
- Increased the maximum attempts for cookie retrieval to enhance reliability in detecting authentication tokens.
- Updated error messages to provide clearer feedback on login failures related to CAPTCHA and password issues.
This commit is contained in:
Torsten Schulz (local)
2026-03-02 10:40:50 +01:00
parent cf8cf17dc7
commit e1e8b5f4a4

View File

@@ -393,9 +393,15 @@ class MyTischtennisClient {
await page.locator('input[name="password"]').first().fill(password, { timeout: 10000 });
console.log('[myTischtennisClient.playwright] Credentials filled');
// Try to interact with private-captcha if present.
// Try to interact with private-captcha if present (it may render with delay).
try {
await page.waitForSelector('private-captcha', { timeout: 8000 });
} catch (_e) {
// ignore: captcha host might not be present in all flows
}
const captchaHost = page.locator('private-captcha').first();
if (await captchaHost.count()) {
const hasCaptchaHost = (await captchaHost.count()) > 0;
if (hasCaptchaHost) {
try {
await page.waitForTimeout(1200);
const captchaVisualStateBefore = await page.evaluate(() => {
@@ -514,6 +520,34 @@ class MyTischtennisClient {
}
});
// Before submit, ensure CAPTCHA fields are actually ready if captcha widget exists.
if (hasCaptchaHost) {
const isCaptchaReadyNow = await page.evaluate(() => {
const captchaField = document.querySelector('input[name="captcha"]');
const clickedField = document.querySelector('input[name="captcha_clicked"]');
const captchaValue = (captchaField && captchaField.value ? captchaField.value.trim() : '');
const clickedValue = (clickedField && clickedField.value ? clickedField.value.toLowerCase() : '');
return captchaValue.length > 80 && (clickedValue === 'true' || clickedValue === '1');
});
if (!isCaptchaReadyNow) {
try {
await page.waitForFunction(() => {
const captchaField = document.querySelector('input[name="captcha"]');
const clickedField = document.querySelector('input[name="captcha_clicked"]');
const captchaValue = (captchaField && captchaField.value ? captchaField.value.trim() : '');
const clickedValue = (clickedField && clickedField.value ? clickedField.value.toLowerCase() : '');
return captchaValue.length > 80 && (clickedValue === 'true' || clickedValue === '1');
}, { timeout: 45000 });
} catch (_captchaNotReadyErr) {
return {
success: false,
error: 'Playwright-Login fehlgeschlagen: CAPTCHA wurde im Browser nicht als gelöst erkannt'
};
}
}
}
// Submit form
const submitButton = page.locator('button[type="submit"], input[type="submit"]').first();
if (await submitButton.count()) {
@@ -525,11 +559,14 @@ class MyTischtennisClient {
// Wait for auth cookie after submit (polling avoids timing races).
let authCookieObj = null;
const maxAttempts = 20;
const maxAttempts = 80;
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const cookies = await context.cookies();
authCookieObj = cookies.find((c) => c.name === 'sb-10-auth-token');
authCookieObj = cookies.find((c) => c.name === 'sb-10-auth-token')
|| cookies.find((c) => /^sb-\d+-auth-token$/.test(c.name))
|| cookies.find((c) => c.name.includes('auth-token'));
if (authCookieObj?.value) {
console.log('[myTischtennisClient.playwright] Auth cookie detected:', authCookieObj.name);
break;
}
await page.waitForTimeout(500);
@@ -541,6 +578,9 @@ class MyTischtennisClient {
if (textContent?.includes('Captcha-Bestätigung fehlgeschlagen')) {
errorText = 'Captcha-Bestätigung fehlgeschlagen';
}
if (!errorText && textContent?.includes('Passwort')) {
errorText = 'Login vermutlich fehlgeschlagen (Passwort oder CAPTCHA)';
}
} catch (_e) {
// ignore text read errors
}