diff --git a/sync/src/scraper.ts b/sync/src/scraper.ts index 1063d7c..a61246f 100644 --- a/sync/src/scraper.ts +++ b/sync/src/scraper.ts @@ -969,7 +969,6 @@ async function scrapeMemberUntersuchungen( + `?search=1&searchid_mitgliedschaften=${idMitgliedschaft}&id_personen=${idPersonen}` + `&id_mitgliedschaften=${idMitgliedschaft}&searchid_personen=${idPersonen}&searchid_maskmode=`; - // Always dump for diagnosis when debug is on await frame_goto(frame, url); const landed = frame.url(); @@ -979,70 +978,21 @@ async function scrapeMemberUntersuchungen( return []; } - // ASP.NET needs ViewState to properly process anzeige_count. - // Extract it from the loaded page and re-navigate with all params + ALLE. - const formState = await frame.evaluate(() => { - const vs = (document.getElementById('__VIEWSTATE') as HTMLInputElement)?.value ?? ''; - const vsg = (document.getElementById('__VIEWSTATEGENERATOR') as HTMLInputElement)?.value ?? ''; - return { vs, vsg }; - }).catch(() => ({ vs: '', vsg: '' })); + // The initial page load may only show a default number of rows. + // Set the dropdown to ALLE and submit the form (which includes ViewState) + // so ASP.NET returns all records. + const needsReload = await frame.evaluate(() => { + const sel = document.querySelector('select[name="anzeige_count"]') as HTMLSelectElement | null; + if (!sel) return false; + if (sel.value === 'ALLE') return false; + sel.value = 'ALLE'; + const form = sel.closest('form') as HTMLFormElement | null; + if (form) { form.submit(); return true; } + return false; + }).catch(() => false); - if (formState.vs) { - const alleUrl = `${BASE_URL}/fdisk/module/mgvw/untersuchungen/UntersuchungenList.aspx` - + `?__VIEWSTATE=${encodeURIComponent(formState.vs)}` - + `&__VIEWSTATEGENERATOR=${encodeURIComponent(formState.vsg)}` - + `&searchdatum=&searchanmerkungen=&searchid_untersuchungsarten=` - + `&searchid_personen=${idPersonen}&searchid_mitgliedschaften=${idMitgliedschaft}` - + `&id_personen=${idPersonen}&id_mitgliedschaften=${idMitgliedschaft}` - + `&anzeige_count=ALLE&offset=0&ordnung=2&orderType=ASC&search=1`; - await frame_goto(frame, alleUrl); - } - - // Try to navigate to history/detail view if available - // FDISK may show only the most recent per exam type on the list page. - // Look for a "Verlauf" or "Detail" or "Alle anzeigen" link/button - const hasHistoryLink = await frame.evaluate(() => { - const links = Array.from(document.querySelectorAll('a, input[type="button"], button')); - for (const el of links) { - const text = (el.textContent || '').toLowerCase(); - const title = (el.getAttribute('title') || '').toLowerCase(); - if (text.includes('verlauf') || text.includes('historie') || text.includes('alle anzeigen') - || title.includes('verlauf') || title.includes('historie')) { - return (el as HTMLElement).id || (el as HTMLAnchorElement).href || text; - } - } - return null; - }).catch(() => null); - - if (hasHistoryLink) { - log(` → Found history link: ${hasHistoryLink}, navigating...`); - // Try to click or navigate to the history page for more complete data - try { - const navigated = await frame.evaluate(() => { - const links = Array.from(document.querySelectorAll('a, input[type="button"], button')); - for (const el of links) { - const text = (el.textContent || '').toLowerCase(); - const title = (el.getAttribute('title') || '').toLowerCase(); - if (text.includes('verlauf') || text.includes('historie') || text.includes('alle anzeigen') - || title.includes('verlauf') || title.includes('historie')) { - if ((el as HTMLAnchorElement).href) { - return (el as HTMLAnchorElement).href; - } - (el as HTMLElement).click(); - return 'clicked'; - } - } - return null; - }).catch(() => null); - if (navigated && navigated !== 'clicked') { - await frame_goto(frame, navigated); - } else if (navigated === 'clicked') { - await frame.waitForNavigation({ timeout: 5000 }).catch(() => {}); - } - await selectAlleAnzeige(frame); - } catch (e) { - log(` → Failed to follow history link: ${e}`); - } + if (needsReload) { + await frame.waitForNavigation({ waitUntil: 'networkidle', timeout: 15000 }).catch(() => {}); } // Parse the table using navigateAndGetTableRows logic (reuse existing page state)