Files
janssen/Covance/Trash/download_test_results_v1.1.md
T
2026-06-09 08:22:49 +02:00

232 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# download_test_results_v1.1.py — dokumentace
**Verze:** 1.1 · **Datum:** 2026-05-29
**Umístění:** `U:\PythonProject\Janssen\Covance_UCO3001\download_test_results_v1.1.py`
> **Změny v1.1 oproti 1.0:** přidána **druhá studie 35472 (MDD)** a druhý typ
> reportu **Microbiology**. Dříve jen 36940 + Standard.
---
## 1. Účel
Automatické stažení reportů **Test Results** z portálu Labcorp Sponsor Portal
(`xsp.labcorp.com`). Skript projde **2 studie × jejich centra × 2 typy reportu**,
u každého vyexportuje grid do CSV a uloží ho timestampovaný do `Source/`.
| Studie | Interní ID | Význam | Počet center |
|---|---|---|---|
| UC | `36940` | 77242113UCO3001 | 12 |
| MDD | `35472` | druhá studie | 5 |
Typy reportu (záložka v URL): **Standard** (`/standard-test-results`) a
**Microbiology** (`/microbiology`).
**Celkem: (12 + 5) × 2 = 34 reportů** (prázdná centra se přeskakují, viz 6.5).
---
## 2. Spuštění
```bat
U:\PythonProject\Janssen\.venv\Scripts\python.exe ^
U:\PythonProject\Janssen\Covance_UCO3001\download_test_results_v1.1.py
```
- Prohlížeč běží **viditelně** (`headless=False`), maximalizovaný.
- **Persistent profile** (`browser_profile/` vedle skriptu) — session přežívá.
### Dočasný test (1 centrum / studie)
Pro rychlé ověření stačí dočasně zúžit `STUDIES`, např.:
```python
STUDIES = [
{"study": "36940", "sites": ["930557"]}, # UC — centrum s daty
{"study": "35472", "sites": ["898745"]}, # MDD — první centrum
]
```
→ proběhnou 4 reporty (2 centra × 2 typy). Po testu vrátit plný seznam.
---
## 3. Konfigurace (konstanty v hlavičce skriptu)
| Konstanta | Hodnota / význam |
|---|---|
| `EMAIL` | `vbuzalka@its.jnj.com` (login přes iMedidata/OKTA na xsp.covance.com) |
| `PASSWORD` | heslo k účtu (uložené přímo v kódu) |
| `LOGIN_URL` | `https://xsp.covance.com/` — po přihlášení redirect na xsp.labcorp.com |
| `OUT_DIR` | `U:\PythonProject\Janssen\Covance_UCO3001\Source` |
| `PROFILE_DIR` | `browser_profile/` vedle skriptu (persistent Chromium profil) |
| `STUDIES` | seznam studií, každá má `study` (interní ID) + `sites` (interní ID center) |
| `REPORT_TYPES` | `standard-test-results`/`standard` a `microbiology`/`microbiology` |
### Interní čísla center
```
36940 (UC): 930551, 930556, 930525, 930549, 930543, 930547,
930555, 930557, 930539, 930536, 930553, 930531
35472 (MDD): 898745, 898739, 898733, 898744, 898727
```
> **Pozor:** jsou to **interní ID** Labcorpu, **nikoli** čísla center typu
> CZ10001. V URL test-results se používá právě toto interní ID:
> `…/test-results/{SITE_ID}/{standard-test-results|microbiology}`.
> (Pozn.: 36940 zdroj = `download_equeries_report_v1.1.py SITES`;
> 35472 zdroj = ručně dodaná čísla center.)
### Generování REPORTS (DRY)
`REPORTS` se sestaví automaticky jako **kartézský součin**
`STUDIES × sites × REPORT_TYPES`. Přidání/odebrání centra, studie nebo typu
reportu = úprava příslušného seznamu, vzor URL i názvu se píše jen jednou.
---
## 4. Výstupní soubory
Formát názvu (timestamp + popisný název):
```
{YYYY-MM-DD_HHMMSS} sponsor-study-{STUDY}-test-results-{SITE_ID}-{TYP}.csv
```
`{TYP}` = `standard` nebo `microbiology`. Příklady:
```
2026-05-29_131121 sponsor-study-36940-test-results-930557-standard.csv
2026-05-29_131500 sponsor-study-36940-test-results-930557-microbiology.csv
2026-05-29_131800 sponsor-study-35472-test-results-898745-standard.csv
```
- Timestamp se generuje pro **každý** report zvlášť (v okamžiku exportu).
- Staré soubory se **nikdy nemažou** (verzování přes timestamp).
- `expect_download` zachytí download event, `save_as()` uloží pod naším názvem.
---
## 5. Průběh skriptu (kroky + logging)
Každý krok se loguje s časem (`[HH:MM:SS]`, `flush=True`).
| Fáze | Co dělá |
|---|---|
| START | spustí prohlížeč |
| LOGIN | otevře login; **pokud je session aktivní, přihlášení přeskočí** |
| Pro každý report (studie × centrum × typ): | |
| KROK 1/5 | navigace na report URL |
| KROK 2/5 | čeká na řádky gridu `.ag-row` **nebo** prázdný grid („No Data"); pak stabilizace počtu |
| KROK 3/5 | klik na viditelné tři tečky (`more_horiz`) → otevře menu |
| KROK 4/5 | klik na viditelné „Export to CSV" → zachytí download |
| KROK 5/5 | uloží soubor do `OUT_DIR` |
| KONEC | souhrn `hotovo X/34` + seznam selhaných (`site/typ`) |
Log u každého reportu ukazuje i typ: `=== Centrum 930557 / microbiology (studie 36940) ===`.
---
## 6. Klíčové technické poznatky (PROČ to tak je) — ověřeno přes Chrome MCP
Stránka test-results je **Angular SPA** s knihovnou **MDL** a tabulkou **AG Grid**.
Microbiology záložka má **stejnou** strukturu jako Standard → vše níže platí pro oba.
### 6.1 Čekání na data = řádky AG Gridu
- Data jsou načtena, jakmile se objeví řádky **`div.ag-row`** (count 0 → N).
- **Řádky jsou `position-absolute`** (virtuální render) → Playwright je
**nepovažuje za „visible"**. Proto:
-`wait_for_selector("div.ag-row")` (default visible) **timeoutuje**.
-`wait_for_function("() => document.querySelectorAll('div.ag-row').length > 0")`.
- Stabilizace: počet řádků se čte co 2 s, dokud se 2× po sobě neshodne.
- **POZN.: počet `.ag-row` se „zastropuje"** (typicky ~153) kvůli virtuálnímu
renderu — NENÍ to skutečný počet záznamů. Slouží jen jako signál „data jsou".
**Export do CSV ale vyexportuje VŠECHNY řádky** (ověřeno: různé velikosti CSV).
### 6.2 „Fetching Data" / spinner — NEPLATÍ pro tuto stránku
- Na test-results **NENÍ** text „Fetching Data" (ten je na *samples* reportu).
- `<loading-bar>` jen problikne při route-loadu → nespoléhat. Signál = `.ag-row`.
### 6.3 Tři tečky (export) — na stránce jsou DVA `<ag-export>`
- 2× `<ag-export>` (1 skrytý), 3× ikona `more_horiz`. Proto filtr na viditelnost:
`page.locator("ag-export button:visible", has_text="more_horiz").first.click()`
### 6.4 „Export to CSV" — v DOM jsou DVĚ položky
- 2× `mdl-menu-item` „Export to CSV" (1 skrytá). Proto:
`page.locator("mdl-menu-item:visible", has_text="Export to CSV").first.click()`
-`get_by_text("Export to CSV")` → strict mode violation (2 elementy).
### 6.5 Prázdné centrum (ověřeno přes Chrome MCP na centru 930551)
- AG Grid při 0 záznamech zobrazí no-rows overlay s textem **„No Data"**.
- Struktura: `.ag-overlay``.ag-overlay-panel`
**`.ag-overlay-no-rows-wrapper`** → `<span>No Data</span>`.
- ⚠️ Třída **NENÍ** `.ag-overlay-no-rows-center` (chybný předpoklad, nikdy
nezabral) — správně je **`.ag-overlay-no-rows-wrapper`**.
- ⚠️ Text „No Data" **NENÍ** v `.ag-body-viewport` (ten je prázdný, `height: 1px`).
- ⚠️ Na stránce jsou **2 overlaye** (1 skrytý, 1 viditelný) → kontrola
viditelnosti `offsetParent !== null`.
- Detekce (KROK 2):
```js
() => {
if (document.querySelectorAll('div.ag-row').length > 0) return false;
return [...document.querySelectorAll('.ag-overlay-no-rows-wrapper')]
.some(e => e.offsetParent !== null);
}
```
- KROK 2 čeká na `.ag-row` **NEBO** tuto detekci → prázdné centrum necheká
zbytečně 120 s a export se přeskočí.
---
## 7. Login logika (sdílená napříč Covance skripty)
```python
page.goto(LOGIN_URL)
page.wait_for_load_state("networkidle")
if not page.get_by_label("Email").is_visible():
return # session aktivní → login přeskočit
# jinak: Email → Next → Password → Verify → wait redirect (code= zmizí z URL)
```
- **Proč `is_visible()` a ne kontrola URL:** po `goto(LOGIN_URL)` zůstane URL
`xsp.covance.com` i po redirectu, takže URL test je nespolehlivý.
- `is_visible()` neháže výjimku — když pole není, vrátí `False`.
---
## 8. Chrome flagy proti „Restore pages" / broken session
```
--disable-restore-session-state # neobnovovat předchozí session
--disable-session-crashed-bubble # potlačit "Chromium didn't shut down correctly"
```
---
## 9. Robustnost smyčky
- Každý report je v `try/except` → **chyba u jednoho nezastaví zbytek**.
- Na konci souhrn: `hotovo X/34` + seznam `SELHALA centra: site/typ, …`.
---
## 10. Možná budoucí rozšíření
- **Další studie / centra**: přidat položku do `STUDIES`.
- **Další typ reportu**: přidat položku do `REPORT_TYPES` (slug + suffix).
- **Ověření počtu**: počet `.ag-row` se loguje — POZOR, je zastropený virtuálním
renderem, takže ho nelze porovnávat s počtem řádků v CSV (CSV má všechny).
---
## 11. Příbuzné skripty (stejná složka / portál)
| Skript | Co stahuje |
|---|---|
| `download_samples_report_v1.1.py` | All Samples (sampletracking, čeká na „Fetching Data") |
| `download_kit_inventory_v2.1.py` | Kit inventory (on-hand expiration) |
| `download_equeries_report_v1.1.py` | eQuery reporty (zdroj SITE_IDS pro 36940) |
| `download_test_results_v1.1.py` | **tento** — Test Results (Standard + Microbiology, 2 studie) |
Všechny sdílejí: persistent profile, login s `is_visible()` checkem,
`ag-export` + „Export to CSV" pattern.