xlibrary
v0.2.1
Published
Multi-language test codegen — record once, emit Robot Framework / SeleniumLibrary / Playwright TS / pytest-playwright with Self-Healing locators and patch/extract workflows
Maintainers
Readme
อ่านในภาษา: English | ภาษาไทย
xlibrary
บันทึกการใช้งานเบราว์เซอร์แล้วสร้างไฟล์ทดสอบสำหรับ Robot Framework + Browser Library, SeleniumLibrary, Playwright Test (TypeScript) หรือ pytest-playwright (Python) — ขับเคลื่อนด้วย Playwright
มีอะไรใหม่ใน v0.2
- รองรับหลายภาษา — บันทึกครั้งเดียว แล้ว emit เป็น
robot,selenium,tsหรือpythonผ่าน-l/--langบันทึก action stream ดิบด้วย--save-actionsแล้ว render ใหม่ภายหลังด้วยxlibrary emit - Self-healing locators — ตอนที่มี alternative selectors ระบบจะแนบคอมเมนต์
# xlib:step=N;alts=[...]พร้อม selector ทางเลือกสูงสุด 3 รายการที่ ranked และเกรดอักษร (A+ ถึง D) viewer แสดง grade chip สีต่างๆ ต่อ step (v0.2.1: ถ้าไม่มี alts ก็ไม่ใส่คอมเมนต์ — output ปกติจะสะอาด) - Re-record step —
xlibrary patch <file>เล่น replay ไฟล์ถึง step เป้าหมาย ให้คุณ re-record ในเบราว์เซอร์ แล้วนำผลลัพธ์ splicing กลับในที่เดิม รองรับ replace, insert-after/before, delete และ move ทุกภาษา output - Test Data Wizard —
--extract-data(หลังบันทึก) หรือxlibrary extract <file>(standalone) ตรวจจับค่า literal (email, password, URL) แสดง diff preview แล้ว extract เป็นการประกาศ variable ตามภาษา
ทำอะไรได้บ้าง
- เปิดหน้าต่างเบราว์เซอร์จริงพร้อม visual recorder ของ Playwright
- บันทึกทุกการคลิก กรอกข้อมูล navigate และ assertion ขณะที่คุณใช้งานหน้าเว็บ
- เขียนไฟล์ที่พร้อมรันทันทีในรูปแบบ output ที่คุณเลือก
- แนบ alternative selectors และ quality grades ให้กับทุก step
- หยุดการบันทึกเมื่อคุณปิดหน้าต่างเบราว์เซอร์ หรือกด
Ctrl+C
ความต้องการของระบบ
- Node.js >= 20
เริ่มใช้งานเร็ว
# 1. ติดตั้งครั้งแรก — ดาวน์โหลด binary ของ Chromium (~150 MB, จะถูก cache ไว้)
# ถ้าคุณติดตั้ง Playwright browsers ไว้แล้ว สามารถข้ามขั้นตอนนี้ได้
npx xlibrary install
# 2. บันทึก session โดยเริ่มจาก URL
npx xlibrary codegen https://example.com -o recorded.robot
# หรือ: emit รูปแบบอื่นโดยตรง
npx xlibrary codegen https://example.com -l ts -o test.spec.ts --save-actionsถ้าข้ามขั้นตอนที่ 1 แล้วรัน
codegenทันที xlibrary จะตรวจพบว่า binary ยังไม่มีและจะแสดงคำสั่งinstallที่ต้องใช้ให้คุณ
เบราว์เซอร์จะเปิดขึ้น ใช้งานหน้าเว็บตามที่ต้องการ จากนั้นปิดหน้าต่าง (หรือกด Ctrl+C) ไฟล์ output ของคุณจะถูกบันทึกพร้อมใช้:
*** Settings ***
Library Browser
*** Test Cases ***
Recorded Flow
New Browser chromium headless=${False} args=["--start-maximized"]
New Context viewport=None
New Page https://example.com
Click role=button[name="Get started"] # xlib:step=1;alts=["css=.btn-primary","text=Get started"]
Fill Text role=textbox[name="Search"] robot framework # xlib:step=2
Close Browsermarker
# xlib:step=N;alts=[...]จะถูกเพิ่มให้กับทุก step โดยอัตโนมัติ มันเป็น power ของ self-healing และxlibrary patchสามารถลบออกด้วยsed '/# xlib:/d'ถ้าต้องการ output ที่สะอาด
ติดตั้ง
ติดตั้ง global (เรียกใช้ได้จากทุกที่):
npm install -g xlibrary
xlibrary codegen https://example.com -o login.robotติดตั้งในโปรเจกต์ (ไม่ต้องติดตั้ง global):
npm install --save-dev xlibrary
npx xlibrary codegen https://example.com -o login.robotวิธีใช้งาน
xlibrary install [browsers...]
ดาวน์โหลด browser binaries ของ Playwright — เป็น wrapper ครอบ npx playwright install
npx xlibrary install # chromium (ค่าเริ่มต้น)
npx xlibrary install firefox # firefox อย่างเดียว
npx xlibrary install chromium firefox # หลายตัว
npx xlibrary install --with-deps # ติดตั้ง OS-level deps ด้วย (Linux เท่านั้น)xlibrary codegen [url] [options]
เปิดเบราว์เซอร์ บันทึกการใช้งาน เขียนไฟล์ output
| Flag | ค่าเริ่มต้น | คำอธิบาย |
| ----------------------- | ---------------- | ----------------------------------------------------------------------- |
| [url] | (ไม่มี) | URL ที่จะเปิด ถ้าไม่ระบุจะเปิดเบราว์เซอร์เปล่าให้พิมพ์ URL เอง |
| -o, --output <file> | recorded.robot | path ของไฟล์ output extension จะ infer ภาษาเมื่อไม่มี -l |
| -l, --lang <target> | (inferred) | ภาษา output: robot | selenium | ts | python |
| -b, --browser <name> | chromium | เบราว์เซอร์: chromium, firefox หรือ webkit |
| --test-name <name> | Recorded Flow | ชื่อของ test case ที่จะสร้าง |
| --save-actions [file] | (ปิด) | บันทึก action stream ดิบเป็น .jsonl artifact สำหรับใช้ emit ภายหลัง |
| --extract-data | (ปิด) | หลังจากบันทึกเสร็จ รัน Test Data Wizard |
| --quiet | (ปิด) | ปิดการแสดง keyword preview แบบ live ระหว่างบันทึก |
| --open | (ปิด) | เมื่อบันทึกเสร็จ เปิดไฟล์ output ใน editor ของคุณอัตโนมัติ |
| --no-viewer | (viewer เปิด) | ปิดหน้าต่าง live-viewer (เปิดเป็นค่าเริ่มต้น) |
| --open-viewer | (ปิด) | Auto-open หน้าต่าง viewer ในเบราว์เซอร์ของคุณเมื่อเริ่ม |
การ infer ภาษาจาก extension ของ -o:
| Extension | Target |
| ----------------- | ---------- |
| .robot | robot |
| .selenium.robot | selenium |
| .spec.ts, .ts | ts |
| .py | python |
| (อื่นๆ) | robot |
ตัวอย่าง:
# บันทึก Robot Framework output พร้อมตั้งชื่อ test case
npx xlibrary codegen https://example.com/login -o login.robot --test-name "Login Flow"
# บันทึก Playwright TypeScript output และบันทึก action artifact
npx xlibrary codegen https://example.com -l ts -o tests/login.spec.ts --save-actions
# บันทึก SeleniumLibrary output (infer จาก extension)
npx xlibrary codegen https://example.com -o login.selenium.robot
# บันทึกแล้ว extract variables ทันที
npx xlibrary codegen https://example.com -o login.robot --save-actions --extract-data
# ใช้ Firefox
npx xlibrary codegen https://example.com -b firefox -o firefox-test.robotxlibrary emit <actions.jsonl> [options]
Render artifact action ที่บันทึกไว้ก่อนหน้าเป็นภาษาเป้าหมาย — ไม่ต้อง re-record
รองรับใน v0.2: robot, selenium (ts และ python ต้องใช้ xlibrary codegen -l ts/python โดยตรง)
| Flag | Required | คำอธิบาย |
| --------------------- | -------- | ---------------------------------------- |
| -l, --lang <target> | ใช่ | Output target: robot | selenium |
| -o, --output <file> | ใช่ | path ของไฟล์ปลายทาง |
| --test-name <name> | ไม่ | Override ชื่อ test case จาก JSONL header |
# ขั้นแรก บันทึกและบันทึก artifact
npx xlibrary codegen https://example.com/login -o login.robot --save-actions
# Re-emit เป็น SeleniumLibrary (ไม่ต้องเปิดเบราว์เซอร์)
npx xlibrary emit recorded.robot.jsonl -l selenium -o login.selenium.robot
# Re-emit เป็น Robot Framework พร้อมเปลี่ยนชื่อ test
npx xlibrary emit recorded.robot.jsonl -l robot -o login-v2.robot --test-name "Login v2"xlibrary extract <file> [options]
รัน Test Data Wizard บนไฟล์ที่มีอยู่แล้ว ตรวจจับค่า literal (email, password, URL) แสดง diff preview และ extract เป็น variables
ต้องการ sidecar .jsonl จาก --save-actions หรือระบุด้วย --actions <path>
| Flag | ค่าเริ่มต้น | คำอธิบาย |
| ------------------------ | ------------ | ------------------------------------------------------------ |
| -o, --output <file> | (in-place) | เขียนไปยังไฟล์แยก แทนที่จะแก้ไข in-place |
| --yes | (ปิด) | ข้าม confirmation prompt แล้ว apply ทันที |
| -l, --lang <target> | (inferred) | Override การ infer ภาษาจาก extension ของไฟล์ |
| --actions <jsonl-path> | (auto) | Override path ของ sidecar .jsonl (default: <file>.jsonl) |
# ดูว่าจะ extract อะไร (interactive prompt)
npx xlibrary extract login.robot
# Apply โดยไม่ prompt (สำหรับ CI)
npx xlibrary extract login.robot --yes
# เขียนไปยังไฟล์ใหม่แทนที่จะแก้ไข in-place
npx xlibrary extract login.robot -o login-extracted.robotxlibrary patch <file> [options]
Re-record หนึ่งหรือหลาย step ในไฟล์ที่สร้างไว้แล้ว ถ้าไฟล์มี xlib:step=N markers จะค้นด้วย step number ตรงๆ ถ้าไม่มีก็ fallback เป็น fuzzy match บน keyword line (case-insensitive substring) พร้อมตาราง disambiguation ตอนเจอหลายตัว
| Flag | คำอธิบาย |
| ---------------------- | ----------------------------------------------------------- |
| --at <id> | แทนที่ step id คือ step number หรือ fuzzy keyword content |
| --insert-after <id> | บันทึก step ใหม่เพื่อ insert หลัง step id |
| --insert-before <id> | บันทึก step ใหม่เพื่อ insert ก่อน step id |
| --delete <id> | ลบ step หรือ range (เช่น 5 หรือ 3-7) |
| --move <spec> | จัดเรียง step ใหม่ — spec คือ "<from> to <to>" |
| --range <range> | แทนที่ range ของ steps — ใช้ร่วมกับ --at |
| --non-interactive | Fail-fast แทนที่จะหยุดรอเมื่อ replay ล้มเหลว |
| --no-backup | ข้ามการสร้างไฟล์ backup .bak |
# แทนที่ step 5 โดย re-record ในเบราว์เซอร์
npx xlibrary patch login.robot --at 5
# แทนที่โดยใช้ fuzzy keyword content
npx xlibrary patch login.robot --at "Click Sign in"
# ลบ step 6 ถึง 8
npx xlibrary patch login.robot --delete 6-8
# Insert step ใหม่หลัง step 3
npx xlibrary patch login.robot --insert-after 3
# ย้าย step 2 ไปที่ตำแหน่ง 5
npx xlibrary patch login.robot --move "2 to 5"ดู docs/USAGE.md สำหรับ CLI reference เต็มและ workflow ทั้งหมด
รูปแบบ output ที่รองรับ
Robot Framework + Browser Library (default)
*** Settings ***
Library Browser
*** Test Cases ***
Login Flow
New Browser chromium headless=${False} args=["--start-maximized"]
New Context viewport=None
New Page https://example.com/login
Fill Text role=textbox[name="Email"] ${VALID_EMAIL} # xlib:step=2;alts=["label=Email","css=#email"]
Click role=button[name="Sign in"] # xlib:step=3
Close BrowserSeleniumLibrary
*** Settings ***
Library SeleniumLibrary
*** Test Cases ***
Login Flow
Open Browser https://example.com/login Chrome
Input Text name:email ${VALID_EMAIL} # xlib:step=2
Click Button name:signin # xlib:step=3
Close BrowserPlaywright Test (TypeScript)
import { test, expect } from '@playwright/test';
test('Login Flow', async ({ page }) => {
await page.goto('https://example.com/login');
await page.getByRole('textbox', { name: 'Email' }).fill(VALID_EMAIL); // xlib:step=2;alts=["label=Email","css=#email"]
await page.getByRole('button', { name: 'Sign in' }).click(); // xlib:step=3
});pytest-playwright (Python)
def test_login_flow(page):
page.goto("https://example.com/login")
page.get_by_role("textbox", name="Email").fill(VALID_EMAIL) # xlib:step=2
page.get_by_role("button", name="Sign in").click() # xlib:step=3Self-healing locators
ทุก step ที่บันทึกมีคอมเมนต์ # xlib:step=N;alts=[...] inline ลิสต์ alts มี alternative selectors ranked สูงสุด 3 รายการที่สามารถแทน primary ได้ถ้ามันพัง
Selectors จะถูก grade ด้วย A+ ถึง D:
| ประเภท selector | Grade |
| ------------------------ | ----- |
| data-testid / test-id | A+ |
| role + accessible name | A |
| label text | A |
| placeholder text | B |
| visible text content | B |
| CSS (id / class) | C |
| XPath | D |
Grade จะถูก promote หนึ่ง tier เมื่อ selector match เพียง element เดียวบนหน้า
live viewer (--viewer เปิดเป็นค่าเริ่มต้น) แสดง grade เป็น colored chip ต่อ step hover เพื่อดู alternative list
รูปแบบไฟล์ที่สร้าง
ทุก session ที่บันทึกจะสร้างไฟล์หนึ่งไฟล์ สำหรับ Robot Framework:
*** Settings ***
Library Browser
*** Test Cases ***
<test-name>
New Browser chromium headless=${False} args=["--start-maximized"]
New Context viewport=None
New Page <url>
<...recorded steps with xlib:step markers...>
Close BrowserSelector ใช้ syntax แบบ semantic ของ Browser Library — role=, label=, css=, xpath= — ตามที่ Playwright recorder จับมาได้
Action → keyword mapping
| Recorded action | Browser Library keyword |
| ---------------------- | ------------------------------------------------------------------------------------------ |
| Open page | New Page ${url} |
| Navigate | Go To ${url} |
| Click | Click ${selector} |
| Double-click | Click ${selector} clickCount=2 |
| Modifier+Click | Keyboard Key down ${mod} / Click ${selector} / Keyboard Key up ${mod} |
| Fill input | Fill Text ${selector} ${text} |
| Press key | Press Keys ${selector} ${key} |
| Check checkbox | Check Checkbox ${selector} |
| Uncheck checkbox | Uncheck Checkbox ${selector} |
| Select option | Select Options By ${selector} value ${option} |
| Hover | Hover ${selector} |
| Upload file | Upload File By Selector ${selector} ${path} (one call per file) |
| Assert visible | Get Element States ${selector} *= visible |
| Assert text (exact) | Get Text ${selector} == ${text} |
| Assert text (contains) | Get Text ${selector} *= ${text} |
| Assert input value | Get Property ${selector} value == ${value} |
| Assert checkbox | Get Checkbox State ${selector} == checked |
ที่มาของ mapping ทั้งหมด: src/codegen/keywords-map.ts
ตัวอย่าง
- Login flow
- Form submission
- Navigation and assertions
- บันทึกครั้งเดียว emit หลายภาษา
- Self-healing locators ในทางปฏิบัติ
- Patch workflow — re-record step
- Extract test data variables
Troubleshooting
ดู Troubleshooting (English) สำหรับวิธีแก้ปัญหาที่พบบ่อย — รวมถึงปัญหา UNABLE_TO_GET_ISSUER_CERT_LOCALLY เมื่อดาวน์โหลด Chromium ผ่าน corporate proxy (Zscaler / Cisco Umbrella / Forcepoint ฯลฯ)
Programmatic API (experimental)
CLI คือ surface ที่ stable ส่วน programmatic API ยังเป็น experimental จนกว่า จะถึง 1.0 — ถ้าใช้งานในระบบจริง ให้ pin version แบบ exact (
[email protected])
import { runRecorder } from 'xlibrary';
import { RobotFrameworkLanguageGenerator } from 'xlibrary/codegen';
import type { ActionInContext } from 'xlibrary/types';
// บันทึกและเขียนไฟล์ output (เหมือนกับ CLI):
await runRecorder({
url: 'https://example.com',
output: 'recorded.robot',
browser: 'chromium',
testName: 'My Flow',
});
// หรือจะ feed actions ผ่าน generator เองก็ได้:
const gen = new RobotFrameworkLanguageGenerator('My Flow');
const header = gen.generateHeader({
browserName: 'chromium',
launchOptions: {},
contextOptions: {},
});
const step = gen.generateAction(someAction as ActionInContext);
const footer = gen.generateFooter();Sub-entries ที่มีให้ใช้:
| Import path | สิ่งที่ export ออกมา |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| xlibrary | ระดับสูง: runRecorder, createReplayController, generator classes |
| xlibrary/codegen | Generators + utilities: RobotFrameworkLanguageGenerator, translateSelector, escapeRobotValue, ACTION_TO_KEYWORD |
| xlibrary/recorder | Recorder orchestrator: runRecorder |
| xlibrary/types | public types ทั้งหมด: Action, ActionInContext, ActionName, options ต่าง ๆ |
เอกสารเพิ่มเติม
- CLI reference — flag ทั้งหมด workflow ที่ใช้บ่อย และ troubleshooting
- Contributing — โครงสร้าง repo การเพิ่ม action mapping ใหม่ การรันเทส
- Architecture — recorder กับ code generator ทำงานร่วมกันอย่างไร
- Security policy — การรายงาน vulnerability และ trust boundaries
License
MIT © Tassana Khrueawan
