สำหรับทีมพัฒนาและทีม QA

มาตรฐานเดียวสำหรับ test idPlaywright ที่ไม่พังเมื่อมีการ refactor

AI เสนอ id ส่วนคนยังคงเป็นผู้ควบคุม

tidwright ให้ AI เติม data-testid ตามข้อกำหนดเดียวกันทั่วทั้งโปรเจกต์ พร้อมการตรวจสอบเพื่อให้โค้ดยัง build ได้ จากนั้น QA เขียน E2E บน id เหล่านั้นผ่าน getByTestId โดยไม่ต้องอ่าน source หรือคาดเดา CSS selector

/plugin install tidwright@tidwright-marketplace
  • ไม่มี runtime dependency
  • ไม่เขียนไฟล์หากยังไม่ได้รับอนุมัติ
  • คืนไฟล์ทั้งหมดหาก build ไม่ผ่าน

React · Next · Vue · Nuxt · Svelte · Angular · HTML

TL;DR

tidwright เติม data-testid ให้โค้ดของท่านตามมาตรฐานเดียว โดยเครื่องมือทำการแก้ไขชุดที่ปลอดภัย ส่วนที่เหลือ AI ตัดสินผ่าน plan ที่ผ่านการตรวจสอบ parser เป็นผู้กำหนดตำแหน่งการแก้ไขทุกจุด build ต้องผ่านมิฉะนั้นไฟล์ทั้งหมดจะถูกคืนสภาพ และไม่มีการเขียนไฟล์หากยังไม่ได้รับอนุมัติ จากนั้น QA เขียน Playwright test บน id เหล่านั้น

01เปรียบเทียบ

ความแตกต่างระหว่างการใช้และไม่ใช้

เปรียบเทียบวิธีทำงานของทีม ก่อนและหลังมีมาตรฐาน

หัวข้อ
ไม่ใช้ tidwright
ใช้ tidwright
การตั้งชื่อ id
ไม่ใช้ tidwrightแต่ละคนตั้งชื่อเอง (btn1, submitBtn) ทำให้ test พังทุกครั้งที่ refactor
ใช้ tidwrightใช้หลักไวยากรณ์เดียว <area>-<element>-<type> เช่น login-submit-button และ lint บังคับใช้
การหา selector ของ QA
ไม่ใช้ tidwrightอ่าน source ของแอปพลิเคชัน หรือถอยไปใช้ CSS, XPath และข้อความ
ใช้ tidwrightอ่านรายการ e2e/TESTIDS.md ที่สร้างให้ และใช้ getByTestId เท่านั้น
การเติม id ทั้งฟีเจอร์
ไม่ใช้ tidwrightเติมด้วยมือทีละ element และไม่เคยเสร็จสมบูรณ์
ใช้ tidwrightเครื่องมือเติมชุดที่ปลอดภัยในรอบเดียว ส่วนที่เหลือ AI ตัดสินผ่าน plan ที่ผ่านการตรวจสอบ ไม่แก้ไฟล์โดยตรง
ความเสี่ยงที่แอปจะพัง
ไม่ใช้ tidwrightต้องอ่าน diff ทุกบรรทัดด้วยตนเอง
ใช้ tidwrightตรวจด้วย parser ของโปรเจกต์ และ typecheck/build ต้องผ่านทั้งก่อนและหลัง มิฉะนั้นไฟล์ทั้งหมดจะถูกคืนสภาพ
id ซ้ำใน DOM
ไม่ใช้ tidwrightพบเมื่อ test เริ่มไม่เสถียร หรือไม่พบเลย
ใช้ tidwrightguard ใน unit test และ E2E ทำให้ test ล้มเหลว พร้อมรายงาน id และจำนวนที่ซ้ำ
spec ใช้ id ที่ source ลบไปแล้ว
ไม่ใช้ tidwrightพบเมื่อการรันล้มเหลว
ใช้ tidwright/tidwright:audit ตรวจพบก่อนรัน พร้อมตรวจ sleep, .only และ credential ใน spec
ผู้รับผิดชอบ selector
ไม่ใช้ tidwrightทีมพัฒนาและ QA โต้แย้งกัน
ใช้ tidwrightกำหนดเป็นข้อตกลงที่เป็นลายลักษณ์อักษร: ทีมพัฒนาเป็นเจ้าของ id, QA เป็นเจ้าของ test และ auditor ตรวจจับความคลาดเคลื่อน

ตัวอย่างก่อนและหลัง

- <button onClick={save}>Save</button>
+ <button data-testid="order-form-save-button" onClick={save}>Save</button>
- <input name="customerName" />
+ <input data-testid="order-form-customer-name-input" name="customerName" />

ผลลัพธ์จริงของ scan --write กับไฟล์ OrderForm.tsx ปุ่ม Save ที่ชื่อมาจากข้อความเท่านั้นจะถูกแสดงเพื่อให้ตรวจสอบ เว้นแต่ระบุ --accept-text

02ขั้นตอนการทำงาน

ขั้นตอนการทำงาน

ห้าขั้นตอน และไม่มีการเขียนไฟล์หากยังไม่ได้รับอนุมัติ

  1. Scanparser ของโปรเจกต์ระบุตำแหน่งของทุก element ที่ test จะใช้ (ปุ่ม ลิงก์ ช่องกรอก ฟอร์ม) และเสนอชื่อมาตรฐาน มีเพียงชุดย่อยที่จำกัดเท่านั้นที่ถูกจัดว่าปลอดภัย ส่วนที่เหลือเป็นคิวตรวจสอบพร้อมเหตุผลกำกับทุกรายการ
  2. เติม idเครื่องมือเขียนชุดที่ปลอดภัย ส่วนที่เหลือ AI เป็นผู้ตัดสินใจผ่าน plan ที่ผ่านการตรวจสอบ (element ใน loop จะได้ ${key} ที่คงที่) และต้องมีผู้อนุมัติก่อนเขียนทุกครั้ง
  3. ตรวจสอบใน transaction เดียวไฟล์ที่แก้ไขถูก parse ซ้ำ typecheck/build ต้องผ่าน และหากระบุ --smoke จะมีการตรวจในเบราว์เซอร์ว่า id ไม่ซ้ำและครบถ้วน หากขั้นตอนใดที่รันล้มเหลว ไฟล์ทั้งหมดจะถูกคืนสภาพ
  4. Catalogไฟล์ e2e/TESTIDS.md ถูกสร้างให้ QA ทุกครั้งที่เขียน โดยระบุวิธีกำหนดของแต่ละ id
  5. QA เขียน testspec ใช้ getByTestId และการ audit ตรวจพบ id ที่ spec ใช้แต่ source ไม่มีอยู่แล้ว
Scan, เติม id ด้วย AI, ตรวจ compile, catalog, QA เขียน test

03ประโยชน์ที่ได้รับ

ประโยชน์ที่ได้รับ

สิ่งที่ทีมได้เพิ่มเติมจากที่ไม่เคยมีมาก่อน

มาตรฐานและ lint

รายการ type แบบปิด (button input select row modal toast page ฯลฯ) ห้ามใช้คำกำกวม เช่น btn div red และห้ามใช้ตัวเลขลอย ให้ใช้ business id แทน

สูตรสำหรับแต่ละ component

recipe modal orders-delete ให้ชุด id ที่กำหนดไว้สำหรับ modal, table, form, tabs และ toast ไม่ต้องออกแบบใหม่ทุกหน้า

Locator helper

modal(page,"orders-delete").confirm และ table(page,"orders").row(id) สอดคล้องกับสูตรที่กำหนด

Guard ตรวจ id ซ้ำ

template สำหรับ vitest/jest และ Playwright fixture ที่ทำให้ test ล้มเหลวเมื่อ data-testid เดียวกันปรากฏใน DOM มากกว่าหนึ่งที่

Auditor

ตรวจพบ sleep, .only, credential ที่เขียนตรงๆ, selector แบบ CSS/XPath/ข้อความ และ id ที่ source ไม่ได้กำหนด

ความปลอดภัยด้าน host

template playwright.config.ts ปฏิเสธ host ที่ไม่ใช่ local เว้นแต่อยู่ใน allow list ป้องกันการรันกับ production โดยไม่ตั้งใจ

รายงานจากผู้พัฒนา (ผู้อื่นไม่สามารถตรวจสอบซ้ำได้): กับแอป React/TSX ขนาดใหญ่ภายในองค์กร guard พบ id ซ้ำ 49 รายการ ซึ่ง typecheck, lint และ unit test ประมาณ 9,000 รายการผ่านไปทั้งหมด

04มาตรฐาน id

มาตรฐาน id

<area>-<element>-<type> · kebab-case ตัวอักษร ASCII · ส่วนท้ายเป็น type จากรายการแบบปิด · แต่ละ id กำหนดได้ครั้งเดียว (รวมถึง id แบบ dynamic)

Component
id (<n> = ชื่อที่ตั้ง)
modal / drawer
<n>-modal · -title-text · -close-button · -confirm-button · -cancel-button · -error-banner
form + field
<n>-form · -submit-button · <form>-<field>-input · …-error
table
<n>-table · -row-${id} · -cell-${id}-${col} · -sort-button-${col} · -empty · -loading · -error
tabs · menu · pagination · toast
<n>-tab-${key} / -panel-${key} · -trigger-button / -item-${key} · -prev-button / -next-button · <action>-success-toast

05ความปลอดภัย

ความปลอดภัยที่ออกแบบไว้

ไม่เขียนไฟล์หากไม่ได้สั่ง

scan อ่านอย่างเดียว การเขียนต้องใช้ --write และขั้นตอนของ AI จะแสดง dry run และขออนุมัติก่อนเสมอ ไฟล์ที่มีการแก้ไขค้างอยู่ใน git จะถูกข้าม

ชุดอัตโนมัติที่จำกัดโดยเจตนา

เติมเฉพาะ native element ที่มีชื่อน่าเชื่อถือ ไม่ซ้ำ ไม่มี spread และแสดงผลจริง ส่วนที่เหลือแสดงเป็นรายการพร้อมเหตุผล

ตำแหน่งมาจาก parser

ใช้ parser ของโปรเจกต์เอง (TypeScript, Vue, Svelte, Angular, parse5) จึงไม่เข้าใจผิดว่า string, regex หรือ comment เป็น element หากไม่มี parser จะแสดงรายการเท่านั้น ไม่เขียน

build ต้องผ่าน มิฉะนั้นคืนไฟล์

--write บังคับ --verify ซึ่งต้องผ่านทั้งก่อนและหลัง หากไม่ได้รันการตรวจในเบราว์เซอร์ รายงานจะระบุว่า NOT run

repo ที่ clone มาสั่งรันคำสั่งเองไม่ได้

คำสั่ง verify ที่มาจากไฟล์ใน repository เท่านั้นจะไม่ถูกรันจนกว่าผู้ใช้จะอนุมัติ

นำไปใช้กับโค้ดเดิมได้

lint --write-baseline ยอมรับปัญหาที่มีอยู่ในปัจจุบัน จากนั้น CI จะล้มเหลวเฉพาะปัญหาใหม่

06หลักฐาน

หลักฐาน

รันซ้ำได้ด้วย node tools/corpus-check.mjs บนแอปโอเพนซอร์ส 9 ตัวที่ระบุ commit ไว้ (RealWorld Conduit ใน Vue / SvelteKit / Angular / React, elk, ngx-admin, shadcn-svelte, excalidraw, vercel/commerce)

9แอปจริง
4,691ไฟล์ source ที่สแกน
431id ที่เติมใน 199 ไฟล์
0การแก้ไขที่ไม่ใช่การแทรก attribute ล้วน
0id ที่เติมแล้วขัดกับมาตรฐาน
0ไฟล์ที่แก้ไขแล้วมี syntax error เพิ่มขึ้น
พิสูจน์แล้ว
  • เครื่องมือรันบนโค้ดจริงได้โดยไม่ล่ม
  • สิ่งที่เขียนเป็นการแทรก attribute ล้วน (เมื่อลบ attribute ที่เติมออกจะได้ไฟล์เดิมทุกไบต์)
  • id ที่เติมเป็นไปตามมาตรฐานและไม่ชนกัน
ยังพิสูจน์ไม่ได้
  • ว่าแอปที่แก้ไขแล้วยัง compile ได้ (ใช้ --verify ในโปรเจกต์ของท่าน)
  • ว่าชื่อที่เสนอเป็นชื่อที่ดีที่สุด
  • ว่า test ที่เขียนบน id เหล่านี้ไม่เสถียรน้อยลง

07ข้อจำกัด

ข้อจำกัด

  • ชื่อมาจาก attribute, i18n key, route และ handler ไม่ได้มาจากความรู้ทางธุรกิจ สิ่งที่ไม่มีชื่อน่าเชื่อถือจะส่งให้ AI หรือผู้ใช้ตัดสิน ควร dry-run ทีละโฟลเดอร์ฟีเจอร์ และอ่าน diff ก่อน --write
  • ต้องมี parser ของโปรเจกต์ หากไม่มี เครื่องมือจะแสดงรายการเท่านั้น และไม่เขียน
  • สิ่งที่ static analysis ไม่สามารถทราบได้ (portal, conditional branch, dynamic component) ต้องอาศัยการตรวจในเบราว์เซอร์และผู้อ่าน diff
  • ยังไม่มี benchmark ที่แสดงว่าดีกว่า skill ต้นแบบทั้งสามตัว หรือว่า test ที่เขียนบน id เหล่านี้ไม่เสถียรน้อยลง
  • ใช้กับ Codex และ Cursor ได้ผ่าน AGENTS.md แต่ยังไม่เคยทดสอบใน Codex หรือ Cursor จริง

08เริ่มต้นใช้งาน

เริ่มต้นใช้งาน

ขั้นตอนฉบับเต็มของแต่ละเอเจนต์อยู่ใน README ของ repository (ขอ URL ของ repository ได้จากทีม)

Claude Code

ติดตั้ง plugin แล้วใช้สามคำสั่งด้านล่าง

Codex

อ่าน AGENTS.md ที่รากของโปรเจกต์ ซึ่งมีขั้นตอนและคำสั่งที่ถูกต้อง

Cursor

คัดลอก .cursor/rules/tidwright.mdc ซึ่งชี้เอเจนต์ไปยัง AGENTS.md

# ติดตั้ง
/plugin install tidwright@tidwright-marketplace

# สำรวจ repo → เขียน profile → scaffold (ต้องอนุมัติ)
/tidwright:init

# เติม id ให้หนึ่งฟีเจอร์ แล้วเผยแพร่ catalog
/tidwright:testid src/features/orders

# ตรวจ spec
/tidwright:audit