synora-test
v1.1.0
Published
Synora Test Automation Framework — web & API testing powered by Playwright
Maintainers
Readme
synora-test — YAML-first Web & API Test Automation
CLI test runner nhẹ, xây dựng trên Playwright.
Viết test bằng YAML dễ đọc — gọi JS helper cho logic phức tạp — test API ngay trong flow.
Cài Đặt
# Cài từ npm (global)
npm install -g synora-test
synora-test install # tải browser cho Playwright đi kèm (chỉ cần 1 lần)
# Hoặc cài vào project
npm install --save-dev synora-test
npx synora-test --help
# Từ source (dev local)
git clone https://github.com/huyngo92/synora-test.git
cd synora-test
npm link
# Kiểm tra
synora-test --helpPlaywright đi kèm
synora-test đóng gói sẵn một bản fork của Playwright (playwright-core) trong vendor/playwright-core, nên không cần cài playwright riêng. Bản fork bổ sung codegen ra YAML (--target=yaml, --domain-mapping).
Cập nhật bản fork (dành cho maintainer, fork phải được build trước):
npm run sync-playwright -- /path/to/playwright/packages/playwright-corePlaywright được phân phối theo Apache License 2.0, xem vendor/playwright-core/LICENSE và vendor/playwright-core/NOTICE.
Quick Start
1. Ghi test tự động (codegen)
# Mở trình duyệt, thao tác, xuất YAML ra terminal
synora-test codegen https://example.com
# Ghi vào file
synora-test codegen --output flows/login.yaml https://example.com2. Chạy test
# Chạy 1 flow
synora-test run flows/login.yaml
# Chạy có giao diện, chậm 300ms/bước (debug)
synora-test run flows/login.yaml --headed --slow 300
# Chạy toàn bộ thư mục, 3 flow song song
synora-test run flows/ --parallel 33. Ví dụ nhanh
synora-test run examples/google-search.yaml --headedCLI Reference
synora-test codegen [url]
| Flag | Mô tả |
|------|-------|
| --output <file> | Ghi YAML vào file (thư mục tự tạo nếu chưa có) |
| --domain-mapping <file> | File JSON ánh xạ domain tùy chỉnh |
synora-test run <file|dir>
| Flag | Mặc định | Mô tả |
|------|----------|-------|
| --headed | headless | Hiển thị cửa sổ trình duyệt |
| --slow <ms> | 0 | Delay (ms) giữa các bước |
| --browser <name> | chromium | chromium / firefox / webkit |
| --timeout <ms> | 30000 | Timeout mỗi action |
| --base-url <url> | — | Ghi đè config.baseUrl của tất cả flow |
| --parallel <n> / -p <n> | 1 | Số flow chạy đồng thời |
| --trace <mode> | off | on / retain-on-failure |
| --screenshot <mode> | only-on-failure | on / off / only-on-failure |
| --output-dir <dir> | test-results | Thư mục lưu kết quả |
| --no-report | — | Bỏ qua file HTML/JSON report |
synora-test suite <file>
Chạy nhiều nhóm flow với thứ tự, điều kiện, và song song linh hoạt.
synora-test suite suites/regression.yaml
synora-test suite suites/regression.yaml --headed --base-url https://staging.synoraCấu Trúc File YAML
appId: browser
name: Login Flow
config:
baseUrl: ${BASE_URL:-https://example.com}
data: ./data/users.json # file dữ liệu đơn
# data: # hoặc nhiều file
# - file: ./data/accounts.json
# as: accounts
# - file: ./data/products.json
# as: products
---
- openLink: ${config.baseUrl}/login
- tapOn: "Tên đăng nhập"
- inputText: ${admin.username}
- tapOn: "Mật khẩu"
- inputText: ${admin.password}
- tapOn:
role: button
name: "Đăng nhập"
- assertVisible: "Dashboard"Các Lệnh Hỗ Trợ (Commands)
| Lệnh | Ví dụ |
|------|-------|
| openLink | openLink: https://example.com |
| tapOn | tapOn: "Login" hoặc tapOn: { role: button, name: Login } |
| doubleTapOn | doubleTapOn: "item name" |
| inputText | inputText: [email protected] |
| clearText | clearText: { css: "#field" } |
| pressKey | pressKey: Enter |
| scroll | scroll: down / scroll: up |
| hover | hover: "Menu" |
| check | check: "Ghi nhớ đăng nhập" |
| uncheck | uncheck: "Đăng ký nhận tin" |
| selectOption | selectOption: { text: "Dropdown", option: "Lựa chọn A" } |
| wait | wait: 1000 |
| waitForVisible | waitForVisible: "Spinner" |
| waitForHidden | waitForHidden: "Loading" |
| assertVisible | assertVisible: "Chào mừng" |
| assertNotVisible | assertNotVisible: "Lỗi" |
| assertText | assertText: "Đăng nhập thành công" |
| assertTitle | assertTitle: "Dashboard" |
| assertUrl | assertUrl: /dashboard |
| assertScreenshot | assertScreenshot: login-page |
| api | Gọi HTTP API (xem docs/usage.md) |
| call | call: helpers/custom.js#myFn |
| capture | capture: { "vars.myVar": "document.title" } |
| loop | Lặp qua mảng dữ liệu (xem docs/usage.md) |
| runIf | Rẽ nhánh if / else theo biến (xem docs/usage.md) |
Locators
- tapOn: "Đăng nhập" # text hiển thị
- tapOn:
role: button
name: "Đăng nhập" # ARIA role + name
- tapOn:
label: "Email" # associated label
- tapOn:
css: "input[name=\"username\"]" # CSS selector
- tapOn:
id: "submit-btn" # data-testid hoặc id
- tapOn:
xpath: "//button[@type='submit']" # XPathNội Suy Biến (Variable Interpolation)
| Cú pháp | Giải thích |
|---------|-----------|
| ${key} | Giá trị trong data hoặc config |
| ${a.b.c} | Nested path |
| ${data.users[0].name} | Phần tử mảng |
| ${MY_ENV_VAR} | Biến môi trường |
| ${KEY:-default} | Default nếu key không tồn tại |
| ${loop.index} | Chỉ số vòng lặp (chỉ trong loop:) |
Tài Liệu Chi Tiết
Xem docs/usage.md để có hướng dẫn đầy đủ:
- Quản lý dữ liệu test (single file, multi-file, CSV)
- Data-driven với
loop: - Điều kiện rẽ nhánh
runIf:(if / else) - Chạy song song (
--parallel) - Reports: HTML, JSON, Trace, Screenshot
- Kiểm thử API (
api:) - JS Helpers &
BaseService/AuthService - Test Suite — nhóm flow, song song,
dependsOn - Ví dụ hoàn chỉnh
