Playwright trên production — và lúc Selenium vẫn thắng

Playwright và Selenium không phải cuộc thi “tool nào hot”. Đây là chuyện chờ DOM, lúc 2 giờ sáng còn gì để mở, và constraint nào bạn không thương lượng được.

20views

0

Sơ đồ so sánh kiến trúc: WebDriver nhiều hop HTTP và Playwright WebSocket hai chiều trực tiếp

Hai giờ sáng. CI đỏ. Ticket ghi “flaky”. Không ai nhớ test đó click cái gì. Screenshot 200px. Team đoán như xem tranh trừu tượng.

Đó không phải chuyện “chọn thư viện sai”. Đó là kiến trúc: nói chuyện với browser thế nào, chờ thế nào, và lúc fail còn artifact nào — sự thật, không phải cảm giác.

Playwright (Microsoft) và Selenium (hệ sinh thái WebDriver) đều điều khiển browser thật. Chúng không cùng một mô hình. Gọi cả hai là “tool UI test” rồi thay qua lại là cách đội thu thập flake, không phải coverage.

Bạn đang mua cái gì?

Selenium 2026 vẫn là stack W3C WebDriver: code test → process driver (ChromeDriver, geckodriver, …) → browser. Giao thức là lệnh HTTP: tìm element, click, lấy text. Grid dàn session ra nhiều máy. Appium ngồi cạnh cùng ý tưởng cho native mobile. Cược: portability — nhiều ngôn ngữ, nhiều browser, nhiều vendor, dễ thuê người đã biết WebDriver.

Playwright là một engine với binding TypeScript/JavaScript, Python, Java, .NET. Nó mở (hoặc nối) Chromium, Firefox, WebKit bằng đường gần debug protocol của browser hơn là REST driver. Cược: determinism — auto-wait, context tách, trace, và giả định bạn chịu sở hữu phiên bản browser.

Công ty đã chốt WebDriver trên giấy? Selenium là mặc định.
SPA rerender liên tục mà suite phải xanh? Playwright là mặc định.

Hầu hết team có cả hai. Phần còn lại của bài: chọn mà không tự lừa mình.

Hai đường nói chuyện với browser

Sơ đồ: Selenium nhiều hop HTTP so với Playwright một kết nối bền

Hình 1. Trái: mỗi lệnh WebDriver là một round-trip. Phải: Playwright giữ kết nối, auto-wait trên đường nóng, context A/B/C trong một process.

WebDriver lệch kênh. Test gửi JSON HTTP tới driver, driver nói với browser. Mỗi hành động một vòng. “Đã visible chưa?” là vòng nữa — trừ khi bạn tự bọc wait. Dễ hiểu, dễ scale bằng Grid. Cũng dễ đua: DOM đã chạy giữa find và click. Như gửi thư cho người đang đổi nhà: thư tới, chuông cửa đã chuyển tầng.

Playwright giữ kết nối bền và auto-wait trên hot path. Click không phải “tìm rồi click”. Là “chờ locator nhận được click, rồi mới click”, timeout đặt một lần. Selector là locator — query lười, đánh lại đến khi được hoặc hết giờ — không phải snapshot findElement một phát rồi cầu nguyện.

Thêm browser context: cookie, storage, session tách trong một browser. Test song song không bắt buộc một browser đầy đủ mỗi worker. Selenium tách bằng session mới — đắt hơn nếu không cẩn.

Selenium 4 không kẹt năm 2014: relative locator, cửa sổ/iframe ổn hơn, CDP tùy driver. WebDriver BiDi là nỗ lực ngành cho ống hai chiều hiện đại. Việc đó quan trọng. Nó chưa bằng gói wait + trace “mở hộp là dùng” của Playwright quý này. Roadmap protocol ≠ suite tuần sau.

Nhà máy flake: chờ

Hầu hết chuyện “Selenium flaky” là chuyện wait. Implicit wait giấu race. WebDriverWait đúng nhưng dài. Deadline tới thì Thread.sleep. Load CI đổi nhịp — suite nói dối, bạn tin.

Hai timeline: sleep gãy vs auto-wait từng bước

Hình 2. Sleep / implicit wait tạo gai thời gian. Auto-wait đi attached → visible → stable → click — vẫn cần timeout thật, không phải timeout laptop.

Playwright không làm bạn miễn nhiễm. Nó biến mặc định thành thứ senior đã viết tay: attached, visible, stable, enabled, nhận event. Bạn vẫn phải:

  • Timeout theo trang tệ nhất production, không theo máy dev (máy dev là dối trá có Wi‑Fi)
  • Assert kết quả (URL, text, network, cây a11y) — không assert class CSS triển khai tuần này
  • Kỷ luật với force: true và waitForTimeout — đó là sleep mặc vest

Team Selenium đã có wait helper + data-testid sẽ không xanh magically vì rewrite Playwright. Họ được lớp wait ngắn hơn. Product không có hook ổn định thì cả hai tool đều cào đầm lầy. Tool không cứu selector div:nth-child(3).

// Playwright: chờ đúng điều kiện, không sleep
await page.getByRole("button", { name: "Thanh toán" }).click();
await expect(page).toHaveURL(/\/checkout\/done/);

2 giờ sáng: một file hay một cuộc khai quật

Đây là chỗ Playwright thường trả tiền migration.

Fail: Playwright dump trace (DOM snapshot, screenshot, network, console, source) — mở Trace Viewer. Runner được thiết kế để tự giải thích. HTML report, video, inspector/codegen cùng một hộp. Như hộp đen máy bay, không phải “ai đó nhớ có chụp hình không”.

Selenium debug là lắp ghép: listener chụp hình, Allure hoặc ReportPortal, video node Grid, log browser nếu driver chịu. Có thể rất hay. Không bao giờ là một flag. Người mới vào khảo cổ mỗi lần — năm tab, ba mật khẩu dashboard.

Trace một cửa sổ vs pipeline Selenium tự ráp

Hình 3. Một artifact vs năm mảnh: screenshot, Allure, video Grid, log. Pipeline già thì đừng vứt. Chưa có pipeline thì đừng dựng Allure trước — lấy trace + suite nhỏ.

Browser, Safari, điện thoại

Playwright ship WebKit (cùng Firefox, Chromium). Đó không phải “Safari trên Mac phòng họp”. Nhưng là WebKit mở, automate được mà nhiều CI từng không có. Selenium + Safari/WebDriver trên macOS vẫn thắng khi bug là browser Apple, không phải “na ná WebKit”. Khách kêu Safari, bạn đừng chỉ Chromium rồi gọi là xong.

Chrome ≠ Chromium — cả hai thế giới. Pháp lý / support đòi đúng browser khách cài: Grid, cloud (BrowserStack, Sauce, LambdaTest), lab máy. Playwright nối remote được; hệ sinh thái Selenium dày hơn. Đừng giả vờ Playwright thay device lab.

Mobile: Appium vẫn là câu WebDriver cho native. Playwright mạnh viewport web mobile và một phần WebView — không thay Appium. Team lai: Appium native, Playwright web. Tách đó tỉnh, không phải thiếu hoài bão.

Ngôn ngữ, thuê người, Grid

Selenium Playwright
Cược Chuẩn + fleet Control plane đóng gói
Wait mặc định Tự viết / sleep Auto-wait
Debug Tự ráp Trace Viewer
Scale quen Grid 2015-cơ Worker + shard CI
Native app Appium cạnh nhà Không phải Appium
Hiring Mọi ngôn ngữ WebDriver Ít binding, first-class

Grid (hoặc cloud Grid) vẫn pattern “500 session, năm version browser, ba OS”. Playwright parallel = worker và CI shard, cộng remote tùy chọn. Scale được — tự thiết kế hoặc mua vendor. Không được cơ nhớ Grid miễn phí.

Thêm Playwright khi đang chạy Grid = hai chính sách version, hai kho secret, hai runbook “sao CI đỏ”. Nước đi tỉnh: Playwright cho UI sản phẩm mới, Selenium cho suite Java cũ đến khi khai tử. Chạy đôi mãi là cách platform mục — và vẫn ship bug khách thấy bằng một click.

Mạng, login, mép component

route / mock / HAR: test là công dân mạng — stub dependency, chờ request, assert mutation. Selenium làm được qua CDP hoặc proxy. Playwright giả định bạn sẽ làm.

storageState (cất cookie/localStorage, dùng lại) giết cả lớp “login mỗi test”. Selenium serialize cookie được; Playwright biến thành recipe mặc định.

request context cạnh UI tiện. Không phải lý do xóa contract test HTTP ở Go/Java. Dùng để cắm state rồi assert UI — không phải suite contract duy nhất.

Nhanh — có caveat

Playwright thường nhanh vì: không thuế HTTP từng lệnh, reuse browser, context, wait thông minh (ít sleep). Grid cũng nhanh khi node nóng và test batch tốt.

Đừng chọn tool vì blog ghi “nhanh gấp 3”. Đo suite của bạn: wall clock CI, flake 30 ngày, thời gian chẩn đoán một fail. Suite chậm mà xanh thắng suite nhanh mà đỏ. Tốc độ không cứu được sleep(5000).

Selenium vẫn thắng khi

  1. WebDriver là chuẩn org — Grid chung, Appium, hợp đồng vendor, team Java.
  2. Browser bạn không kiểm soát — kiosk, engine lạ, Safari/IE-class (hiếm, vẫn thật).
  3. Suite đã xanh — giá rewrite > giá flake. Wedge Playwright trên mặt mới, không port big-bang.
  4. RFP đòi W3C trên giấy hơn là trace. Lạ — vẫn gặp. Giấy thắng file .zip trace.

Playwright là kiến trúc tốt hơn khi

  1. SPA hiện đại (React, Vue, island Astro…) và flake đang là wait.
  2. Muốn một toolchain: runner, trace, codegen, nhiều engine trên CI — không ráp sáu jar.
  3. Context + storageState khớp cách nghĩ tenant / user (SaaS).
  4. Team thật sự mở trace. Tool không ai mở là đồ trang trí — đắt hơn Allure bạn cũng không mở.

Migrate mà không thành rewrite

Đừng dịch 2.000 test Selenium từng dòng. Bạn sẽ port flake — cùng bug, syntax mới, ego cao hơn.

  • Đóng băng suite cũ làm cổng chất lượng; chỉ thêm khi cháy production.
  • Journey mới, tối hạn, viết Playwright: login, trả tiền, báo cáo sếp nhìn.
  • Chung hook (data-testid hoặc role + tên).
  • Chuyển journey chỉ khi xóa bản Selenium trong cùng PR.
  • Một dashboard “đường khách thấy” — không một dashboard một tool.

Đó là ADR: Playwright cho UI automation mới; Grid đến khi native/Appium và Java legacy nghỉ; xem lại khi chi phí Grid hoặc flake vượt chi phí chạy đôi.

Takeaway

Selenium là chuẩn và một fleet. Playwright là control plane đóng gói cho browser. Cái trước thắng hệ sinh thái và lực hút hiring. Cái sau thắng wait mặc định, trace, và test hình SPA.

Chọn constraint không thương lượng — Grid đã trả tiền, hoặc CI đang nói dối — rồi tối ưu cái đó. Trộn cả hai không có lối thoát là cách nuôi hai nền tảng automation… và vẫn ship bug khách thấy bằng một click.

Found this insightful? Like or share with your team:

Spread good engineering craft & architecture lessons.

20views

0

Comments

Email is not published. Keep it professional.

  1. No comments yet.