PKD / LITE

TypeScript hay JavaScript khi khởi tạo Playwright?

Chọn ngôn ngữ cho Playwright không phải là chọn thứ “thời thượng hơn”, mà là chọn lớp rào chắn bắt lỗi phù hợp với vòng đời dự án và năng lực đội ngũ.

Điểm khác biệt cốt lõi nằm ở thời điểm phát hiện lỗi: trước lúc chạy (compile time) hay sau khi mở trình duyệt (runtime).

🧭 Mô hình tổng thể

npm init playwright@latest
       |
       +-- [TypeScript] (Khuyên dùng) -> tsc check -> Playwright -> Report
       |                                  (Bắt lỗi cú pháp/hợp đồng trước CI)
       |
       `-- [JavaScript] (Dự án legacy) -----------> Playwright -> Browser
                                          (Chỉ lộ lỗi khi runtime chạy tới)

TypeScript bổ sung lớp kiểm tra kiểu tĩnh (static typing). Playwright có sẵn bộ type definition hoàn chỉnh cho toàn bộ hệ sinh thái (@playwright/test), giúp IDE hiểu sâu fixture và cấu trúc dữ liệu kiểm thử.

⚡ So sánh thực chiến: Bắt lỗi trước runtime

Hãy nhìn một lỗi gõ nhầm thuộc tính (typo) rất phổ biến trong Playwright:

// Gõ nhầm 'name' thành 'nam' khi tìm nút bấm:
await page.getByRole('button', { nam: 'Đăng nhập' });
  • TypeScript (Phát hiện trong 1 giây): IDE gạch đỏ cảnh báo ngay lập tức, tsc --noEmit chặn trước pre-commit. Bạn sửa xong lỗi trước khi browser kịp mở.
  • JavaScript (Mất 30 giây trên CI): Không có cảnh báo tĩnh. Code được đẩy lên repo, CI kéo runner, khởi tạo Chromium, tương tác thất bại, chờ hết timeout 30 giây rồi mới fail kịch bản.

🎯 Ma trận quyết định trong 30 giây

Tiêu chí Chọn TypeScript Chọn JavaScript
Quy mô bộ test Suite lớn, chạy CI dài hạn, nhiều người cùng viết. Kịch bản ngắn, smoke test tạm thời, ít file.
Hệ thống code hiện tại Web app dùng TS, hoặc muốn tái sử dụng type DTO/API. Codebase thuần JS, team chưa quen với cú pháp type.
Tái sử dụng code Dùng nhiều custom fixture, helper, POM, API client. Test độc lập, kịch bản tương tác thẳng trên page.
Trải nghiệm IDE Đầy đủ autocomplete, gợi ý method locator, an toàn refactor. Cần thêm JSDoc thủ công nếu muốn có autocomplete.

Lưu ý: Playwright hỗ trợ TypeScript mặc định out-of-the-box (không cần cài thêm Webpack/Babel hay build tool phức tạp).

🛠️ Baseline triển khai chuẩn

1. Cấu hình CI cho TypeScript

Playwright tự transpile TypeScript để chạy, nhưng không type-check toàn suite. Để chặn lỗi kiểu lọt vào CI, thêm script kiểm tra tĩnh:

{
  "scripts": {
    "typecheck:e2e": "tsc --noEmit",
    "test:e2e": "playwright test"
  }
}
  • Prompt mẫu:

Tôi đang viết Playwright test bằng TypeScript. Hãy review helper function sau, chuẩn hóa kiểu dữ liệu tối thiểu cho tham số đầu vào và fixture, không làm phức tạp hóa logic test.

2. Baseline an toàn nếu chọn JavaScript

Nếu team quyết định dùng JavaScript, hãy kích hoạt kiểm tra kiểu nhẹ nhàng qua JSDoc mà không cần đổi đuôi file:

// @ts-check
/**
 * @param {import('@playwright/test').Page} page
 * @param {{ email: string, pass: string }} creds
 */
async function login(page, creds) {
  await page.getByLabel('Email').fill(creds.email);
  await page.getByLabel('Mật khẩu').fill(creds.pass);
}

⚠️ Những điều TypeScript không thay thế được

TypeScript chỉ kiểm tra kiểu tĩnh của mã nguồn, không tự động giải quyết các bài toán runtime của E2E:

Code E2E Test
   |
   +-- [TypeScript xử lý] ---> Bắt lỗi typo, sai kiểu, đổi API contract
   |
   |   (Những thứ TypeScript BỎ LỌT):
   +-- Quên 'await' ---------> Bắt bằng ESLint: no-floating-promises
   +-- Flaky test / DOM trễ -> Dùng Playwright Auto-wait & getByRole
   `-- Dữ liệu / Staging bẩn -> Dùng Fixture setup & teardown độc lập

📚 Kết luận

Dự án mới / Chạy CI dài hạn           Codebase thuần JS / Test tạm
             |                                      |
             v                                      v
    [ TypeScript (Mặc định) ]                [ JavaScript ]
             |                                      |
    Bắt lỗi compile-time                   Khởi đầu nhanh tức thì
    An toàn khi refactor                   Nâng cấp dần bằng @ts-check

Chọn TypeScript làm mặc định để mua sự bảo vệ lâu dài với chi phí cài đặt bằng 0 (Playwright hỗ trợ sẵn out-of-the-box). Chỉ chọn JavaScript khi team có ràng buộc cụ thể với codebase legacy hiện hữu.

🧾 Tóm tắt bỏ túi (Take away)

Điểm chính Hành động
Khả năng thực thi TS và JS chạy cùng runner, cùng browser, cùng bộ API Playwright.
Lựa chọn mặc định Ưu tiên TypeScript cho mọi suite chạy CI và duy trì dài hạn.
Chốt chặn CI Luôn chạy tsc --noEmit trên CI trước khi chạy playwright test.
Tránh lỗi await Bật ESLint no-floating-promises để bắt các lệnh Playwright quên await.
Lựa chọn JavaScript Dùng khi team thuần JS; tận dụng // @ts-check và JSDoc để có type gợi ý.

🔗 Tài liệu tham khảo