"""Explorační skript — přihlášení do EvaMed CRF, načtení všech formulářů, nalezení AE.""" import asyncio from playwright.async_api import async_playwright BASE_URL = "https://prod.evamed.com/etude/soft/index.php" LOGIN_URL = "https://prod.evamed.com/etude/soft/index.php?module=authentification&class=login&client=myopowers-dry" LOGIN = "vbuzalka" PASSWORD = "Vlado9674+" SCREENSHOTS_DIR = "screenshots" async def main(): async with async_playwright() as p: browser = await p.chromium.launch(headless=False) context = await browser.new_context(viewport={"width": 1400, "height": 900}) page = await context.new_page() # 1. Login await page.goto(LOGIN_URL) await page.wait_for_load_state("networkidle") await page.locator('#login').fill(LOGIN) await page.locator('input[type="password"]').first.fill(PASSWORD) await page.click('text=Connection') await page.wait_for_load_state("networkidle") print("Logged in") # 2. Go to Forms list await page.goto(f"{BASE_URL}?module=monitoring&class=formslisting") await page.wait_for_load_state("networkidle") print("Forms list loaded (page 1)") # 3. Switch to ALL records await page.select_option('select[name="l"]', 'ALL') print("Switched to ALL, waiting for all rows to load...") await page.wait_for_function( "() => document.querySelectorAll('tr').length > 3200", timeout=120000 ) print(f"All rows loaded") # 4. Count total rows and find AE rows stats = await page.evaluate("""() => { const rows = document.querySelectorAll('tr'); let totalRows = rows.length; let aeRows = []; let formCodes = {}; rows.forEach((row, idx) => { const cells = Array.from(row.querySelectorAll('td')); cells.forEach(cell => { // collect all unique form codes from the Formcode column }); // Look for AE in any cell const cellTexts = cells.map(c => c.innerText.trim()); // Formcode is typically column index 8 based on the header if (cells.length > 8) { const formcode = cells[8]?.innerText?.trim(); formCodes[formcode] = (formCodes[formcode] || 0) + 1; if (formcode === 'AE') { aeRows.push({ rowIndex: idx, subject: cells[0]?.innerText?.trim(), formcode: formcode, formName: cells[9]?.innerText?.trim(), allCells: cellTexts, links: Array.from(row.querySelectorAll('a')).map(a => ({ href: a.getAttribute('href'), title: a.title || '', text: a.innerText.trim().substring(0, 50) })) }); } } }); return { totalRows, aeCount: aeRows.length, aeRows: aeRows.slice(0, 5), formCodes }; }""") print(f"Total rows: {stats['totalRows']}") print(f"AE rows found: {stats['aeCount']}") print(f"Form codes: {stats['formCodes']}") if stats['aeRows']: print(f"\nFirst AE row sample:") ae = stats['aeRows'][0] print(f" Subject: {ae['subject']}") print(f" All cells: {ae['allCells']}") print(f" Links: {ae['links']}") # 5. Open first AE form for link in ae['links']: if link.get('href') and 'id=' in link['href']: ae_url = link['href'] if not ae_url.startswith('http'): ae_url = f"https://prod.evamed.com/etude/soft/{ae_url}" print(f"\nOpening AE form: {ae_url}") await page.goto(ae_url) await page.wait_for_load_state("networkidle") await page.screenshot(path=f"{SCREENSHOTS_DIR}/05_ae_form.png", full_page=True) print("Screenshot: AE form") # Extract all fields from the form fields = await page.evaluate("""() => { // Try input-group pattern const groups = document.querySelectorAll('.input-group'); let inputGroupFields = Array.from(groups).map(g => ({ html: g.outerHTML.substring(0, 800), text: g.innerText.trim().substring(0, 300) })); // Try label/value pattern in tableauFormulaire const tableFields = []; document.querySelectorAll('.tableauFormulaire td, .tableauFormulaire th').forEach(el => { tableFields.push({ tag: el.tagName, className: el.className, text: el.innerText.trim().substring(0, 200) }); }); // Try all form inputs const inputs = []; document.querySelectorAll('input, select, textarea').forEach(el => { inputs.push({ type: el.type, name: el.name, id: el.id, value: el.value?.substring(0, 200), className: el.className }); }); return { inputGroupFields, tableFields: tableFields.slice(0, 50), inputs: inputs.slice(0, 50) }; }""") print(f"\nInput groups: {len(fields['inputGroupFields'])}") for i, f in enumerate(fields['inputGroupFields'][:10]): print(f" [{i}] {f['text'][:120]}") print(f"\nTable fields: {len(fields['tableFields'])}") for i, f in enumerate(fields['tableFields'][:20]): print(f" [{i}] <{f['tag']} class='{f['className']}'> {f['text'][:100]}") print(f"\nForm inputs: {len(fields['inputs'])}") for i, f in enumerate(fields['inputs'][:20]): print(f" [{i}] {f['type']} name={f['name']} id={f['id']} val={f['value'][:60] if f['value'] else ''}") # Save full form HTML for analysis form_html = await page.content() with open(f"{SCREENSHOTS_DIR}/05_ae_form_full.html", "w", encoding="utf-8") as f: f.write(form_html) print("Saved: full AE form HTML") break else: print("NO AE ROWS FOUND!") await page.screenshot(path=f"{SCREENSHOTS_DIR}/04_all_forms.png", full_page=False) # Dump all unique form codes for debugging print("Available form codes:", list(stats['formCodes'].keys())[:30]) await browser.close() print("Done") if __name__ == "__main__": import os os.makedirs(SCREENSHOTS_DIR, exist_ok=True) asyncio.run(main())