Migration: Selenium → Playwright (.NET)
Chiến lược chốt: viết bộ engine thứ 2 dùng Playwright song song với bộ Selenium hiện có. Runtime bật cái nào thì chạy cái đó (feature flag / config). Không xoá Selenium cho tới khi Playwright chạy ổn định ngang bằng.
Phạm vi đo được (từ source thật)
| Hạng mục | Số lượng | Ghi chú |
|---|---|---|
| File dùng Selenium (active) | 16 | +1 file QBCC comment-out vẫn ref Selenium |
| File dùng EO.WebBrowser (riêng biệt) | 13 | CoreLogic, GoogleRealestate, toàn bộ Share\Winform |
| Lớp trừu tượng trung tâm | Có (một phần) | SearchBaseService.chrome + DeSearchHelper gánh ~70% |
| Target framework các project worker | net4.5.2 | Dưới mức tối thiểu của Playwright |
| Selenium.WebDriver | 3.141.0 (đa số) / 4.10.0 (AutoLoad) | Lệch version trong cùng solution |
| Spike Playwright sẵn có | Microsoft.Playwright 1.41.2 đã ref trong .Share | Folder Playwright\ rỗng — chưa wire |
Hai tầng kiến trúc cần xử lý KHÁC NHAU
- Worker config-driven (dễ) — đi qua
SearchBaseService.chrome+DeSearchHelper.GetWebsiteElement/GetValue(đọc selector Id/Css/XPath từ JSON). Port tập trung 2 lớp này là phủ được phần lớn worker. - Scraper static + EO WinForm (khó) —
AsicSelenium,VevoSelenium,AutoLoadtự ôm driver riêng; CoreLogic/GoogleRealestate dùng EOWebView.LoadUrl/EvalScripttrong WinForm. Không có abstraction chung → phải port từng cái.
Đầu việc lớn (epics)
EPIC 0 — Retarget framework (điều kiện tiên quyết)
- Spike: retarget 1 worker đơn giản (
AccessCanberra_Act) net4.5.2 → net8.0, chuyển csproj sang SDK-style. Verify: project build + chạy 1 lượt search thật. - Đánh giá độ vỡ: EF6 EDMX, EO.WebBrowser, DevExpress trên .NET 8.
- Quyết định: retarget toàn bộ hay tách worker Playwright thành assembly .NET 8 mới gọi qua IPC.
EPIC 1 — Lớp trừu tượng Playwright (nền tảng)
- Thiết kế interface
IBrowserSessionthay cho việcISearch_BaselộChromeDriverra ngoài. Verify: Selenium impl cũ vẫn chạy qua interface mới (giữ tương thích). - Port
DeSearchHelper.GetWebsiteElement/GetValuesang Playwright locator (Id/Css/XPath →page.Locator). Verify: unit test resolve selector từ JSON mẫu của 1 site. - Port vòng đời driver:
OpenChrome/CloseChrome→Playwright.Chromium.LaunchAsync+ download API. Verify: mở/đóng sạch, không còn process mồ côi. - Cơ chế switch engine (Selenium ↔ Playwright) qua config. Verify: đổi flag, cùng input ra cùng output.
EPIC 2 — Port worker config-driven (mỗi worker 1 task)
Thứ tự từ dễ → khó: AccessCanberra_Act → OneGovNSW_AU → TPBGovAu → AbrBusinessGov (có hardcode selector + switch tab) → WhitePages.
- Mỗi worker: override
StartSearchAndDownload/GetDataFromWebsitebản Playwright. Verify: chạy song song Selenium vs Playwright, so khớp bản ghiTextSearch_Data_*.
EPIC 3 — Port các tính năng hạ tầng khó
- Captcha + human-in-the-loop: hiện reCaptcha được phát hiện → alert Google Chat → busy-wait chờ người RDP vào server giải trong cùng browser session đang chạy headed. Playwright chạy browser riêng → phải thiết kế lại luồng này (persistent context / CDP attach / headed bắt buộc). Verify: mô phỏng 1 lần chặn captcha, người giải, flow tiếp tục.
- Download PDF: thay hack "diff thư mục download trước/sau click" bằng Playwright download API. Verify: tải đúng file, không phụ thuộc polling.
- Anti-bot: chuyển
--disable-blink-features=AutomationControlled, overridenavigator.webdriver, xoay user-agent sang Playwright context options. Verify: site nguồn không chặn. - Bỏ
KillOrphanedChromeDriverProcesses(Playwright tự quản process).
EPIC 4 — Port scraper static + EO WinForm (khó nhất)
-
AsicSelenium(419 dòng, có retry captcha 15×, xoay UA). Verify: ASIC search ra PDF + parse field đúng. -
VevoSelenium(login form, download PDF). Verify: so với output cũ. - CoreLogic (EO → Playwright): thay
WebView.LoadUrl/EvalScript+ inject JS login bằng Playwright. Nhớ phụ thuộc AutoLoad giữ session. Verify: login + lấy data. - GoogleRealestate (EO → Playwright): gallery ảnh + screenshot Google Map. Verify: ra
ImageURLs+GoogleMapImage. - AutoLoad: app WinForm giữ phiên CoreLogic bằng reload timer → cân nhắc Playwright persistent context. Verify: session sống qua nhiều giờ.
3 thứ khó nhất (đã xác nhận từ source)
- Retarget framework là tiên quyết — toàn bộ worker net4.5.2, dưới mức tối thiểu Playwright. Không reference được cho tới khi retarget xong.
- Luồng captcha human-in-the-loop — headed browser + phát hiện reCaptcha + alert Google Chat + busy-wait chờ người giải trong chính session live. Playwright chạy browser riêng → phải thiết kế lại, không port 1-1.
- Hai stack browser sau UI WinForms/WPF — một nửa code là EO.WebBrowser nhúng trong WinForm với
EvalScriptthô. Playwright không có control nhúng → cần đổi kiến trúc (browser out-of-process), không phải swap thư viện.
Rủi ro & lưu ý
- Lệch version Selenium (3.141 vs 4.10) → đừng giả định API đồng nhất khi đọc code cũ.
- Một số selector hardcode trong C# (ASIC, ABR) chứ không nằm trong JSON → không port được tập trung hoàn toàn.
- 9 worker không nằm trong solution nào → build/migrate từng cái riêng.
Microsoft.Playwright 1.41.2đã được ref sẵn trong.Share(spike cũ) nhưng chưa wire — kiểm tra trước khi thêm mới.