Kiểm thử / Playwright

Kiểm thử đăng nhập bằng Playwright với AI agent

Một test đăng nhập cần xác nhận trạng thái sau thao tác, không chỉ việc nút đã được bấm. Bài này phát triển từ hướng dẫn Playwright tổng quát thành hai ca cụ thể: đăng nhập đúng và từ chối thông tin sai.

Trong bài này

1. Chuẩn bị trước khi yêu cầu agent viết test

Ví dụ dành cho dự án Node.js/TypeScript đã cài @playwright/test và browser runtime phù hợp. Ứng dụng phải chạy ở http://127.0.0.1:3000, có tài khoản thử riêng và database thử có thể phục hồi. Nếu dự án dùng runner khác, giữ quy ước hiện có thay vì chép đè cấu hình.

Ứng dụng minh họa có nhãn Email, Password, nút Sign in, trang /dashboard và heading Dashboard. Agent phải quan sát DOM thật và thay các locator, URL, thông báo cho đúng ứng dụng. Các tên dưới đây không phải kết quả khám phá website của bạn.

Dùng webapp-testing để kiểm tra URL, công cụ và dữ liệu trước. Cấp thông tin tài khoản thử qua biến môi trường E2E_EMAIL, E2E_PASSWORD theo cơ chế secret của môi trường; không ghi giá trị vào test hoặc commit.

2. Giữ bằng chứng khi thất bại

Ghép các tùy chọn phù hợp vào playwright.config.ts hiện có. Ví dụ dùng một worker và không retry để việc điều tra ban đầu dễ theo dõi.

import {defineConfig} from '@playwright/test';

export default defineConfig({
  testDir: './tests/e2e',
  workers: 1,
  retries: 0,
  reporter: [['list'], ['html', {open: 'never'}]],
  use: {
    baseURL: 'http://127.0.0.1:3000',
    trace: 'retain-on-failure',
    screenshot: 'only-on-failure',
  },
});

Thêm script gọi binary đã cài trong package.json; giữ các script khác của dự án:

{
  "scripts": {
    "test:e2e": "playwright test",
    "test:report": "playwright show-report",
    "test:trace": "playwright show-trace"
  }
}

3. Kiểm tra thành công và từ chối đăng nhập

Tạo tests/e2e/login.spec.ts trong dự án thử. Ca thành công kiểm tra cả điều hướng và nội dung sau reload. Ca thất bại dùng email minh họa phải được xác nhận là không tồn tại trong fixture, tránh gây khóa tài khoản người dùng.

import {test, expect} from '@playwright/test';

test('valid credentials create a usable session', async ({page}) => {
  const email = process.env.E2E_EMAIL;
  const password = process.env.E2E_PASSWORD;
  if (!email || !password) {
    throw new Error('Configure dedicated E2E_EMAIL and E2E_PASSWORD');
  }

  await page.goto('/login');
  await page.getByLabel('Email', {exact: true}).fill(email);
  await page.getByLabel('Password', {exact: true}).fill(password);
  await page.getByRole('button', {name: 'Sign in', exact: true}).click();
  await expect(page).toHaveURL(/\/dashboard(?:[/?#]|$)/);
  await expect(page.getByRole('heading', {name: 'Dashboard', exact: true}))
    .toBeVisible();
  await page.reload();
  await expect(page.getByRole('heading', {name: 'Dashboard', exact: true}))
    .toBeVisible();
});

test('invalid credentials remain unauthenticated', async ({page}) => {
  await page.goto('/login');
  await page.getByLabel('Email', {exact: true}).fill('not-a-user@example.test');
  await page.getByLabel('Password', {exact: true}).fill('deliberately-invalid');
  await page.getByRole('button', {name: 'Sign in', exact: true}).click();
  await expect(page.getByRole('alert'))
    .toContainText('Invalid email or password');
  await expect(page).toHaveURL(/\/login(?:[/?#]|$)/);
});

Mỗi test bắt đầu với browser context riêng. Nếu cấu hình chung đang nạp storageState đã đăng nhập, cần một project test sạch cho các ca này. Không dùng timeout cố định để chờ đăng nhập; assertion của Playwright sẽ chờ điều kiện mong đợi trong giới hạn cấu hình.

4. Chạy ca nhỏ và đọc đúng loại lỗi

npm run test:e2e -- tests/e2e/login.spec.ts
npm run test:report
  • Connection refused: kiểm tra server, cổng và môi trường trước khi sửa test.
  • Không tìm thấy locator: đối chiếu DOM và nhãn accessible thật; đừng chỉ tăng timeout.
  • Thông tin hợp lệ vẫn bị từ chối: kiểm tra dữ liệu seed, trạng thái tài khoản và request trong môi trường thử.
  • Đã đổi URL nhưng chưa có nội dung: kiểm tra lỗi tải trang, session hoặc response tiếp theo.

Trace và ảnh có thể chứa dữ liệu nhạy cảm, cookie hoặc nội dung request. Lưu cục bộ, loại thông tin riêng trước khi chia sẻ và không commit trạng thái xác thực. Ghi lệnh chạy, phiên bản ứng dụng, bước lỗi và artifact tương ứng trong báo cáo.

5. Mở rộng sau khi hai ca cơ bản ổn định

Theo yêu cầu sản phẩm, bổ sung logout, truy cập trang được bảo vệ khi chưa đăng nhập, session hết hạn và điều hướng bàn phím. SSO hoặc MFA cần fixture và chính sách riêng; hai test minh họa này không kiểm chứng các luồng đó. Khi chia sẻ tài khoản giữa các test song song, kiểm tra xem chúng có thay đổi cùng trạng thái phía server không.

Nguồn đối chiếu