解析自然語言選擇器
.demo 腳本會以自然語言描述其意圖:
selectors:
composer = ask "the message box at the bottom of the chat"
您的工作是找出這個元素在實際 DOM 中的位置,並將其寫入
scripts/<name>.selectors.json,如此 script.mjs 才能將其編譯為一般的選擇器,
而 driver.mjs 才能錄製出確定的拍攝內容。
您是解析器。 流水線中沒有任何部分會呼叫模型 — script.mjs
會讀取側車檔案,若沒有該檔案則拒絕編譯。解析在這裡執行,
且僅執行一次,在錄製之前進行,因為拍攝的時機就是影片的時間軸,
如果在執行過程中進行模型往返,會導致完成的影片中出現靜默時間。
開始之前
- 應用程式必須可連線,且如果需要登入,必須已在使用者的 Chrome 中登入。 這就是使用擴充功能的重點:它能夠存取真實的會話,因此不需要 SSO 流程, 也不需要填寫電子郵件驗證碼。
- 請先閱讀腳本。您需要
app:/target:標頭來取得 URL, 以及各個節拍,因為選擇器必須依照流程順序解析(詳見下文)。
程序
-
取得工作清單。
cd pipeline node script.mjs ../scripts/<name>.demo --intentsstdout 會輸出 JSON:每個
ask選擇器、其意圖及其目前的解析結果 (若未解析則為null)。解析那些null。僅在使用者表示流程已損壞時, 才重新解析其餘部分。 -
在單一次 ToolSearch 呼叫中載入瀏覽器工具,然後在執行任何其他操作之前 先呼叫
tabs_context_mcp。除非使用者指定了現有的分頁,否則使用tabs_create_mcp建立一個新的分頁。 -
按照節拍順序逐步執行流程。 這是最容易出錯的部分: 許多選擇器在登陸頁面上並不存在。結果表格只會在送出問題後出現; 「停止」控制項只在有內容生成時存在。因此,請依照腳本的節拍逐步執行, 在每個
ask的元素出現在畫面上的那一刻進行解析。即時資料。在任何會建立、修改、傳送或刪除任何內容的步驟之前, 請暫停並詢問使用者。
feature.demo會向真實的 Salesmessage 帳戶傳送四則訊息。 如果只需要定位某個東西,請使用懸停而非點擊,且絕對不要點擊破壞性控制項來「看看它是什麼」。 -
找到元素並選擇最耐用的控制代碼。 偏好順序如下:
偏好 原因 [data-testid=...]、data-test、data-qa專為被選取而設計;能經得起重新設計 穩定的 id良好,除非看起來是自動產生的( :r3a:、id-1a2b)按精確可存取名稱的按鈕/連結 → btn:Name驅動程式的 btn:會比對文字、aria-label和內部的img[alt][aria-label=...]、[role=...]穩定,且通常具有語義 語義結構( main table、nav a[href="/teams"])能經得起樣式更迭 絕對不要使用:
nth-child鏈、自動產生的類別名稱(css-1a2b3c、 很長的 Tailwind 堆疊),或任何以產生的內容為鍵值的東西。 最後一項正是此功能存在所要避免的陷阱 — 模型的答案每次執行措辭都不同, 因此與其文字相符的選擇器就如同擲硬幣。請改為定位容器或完成訊號。 -
在寫入之前先驗證。 針對每個候選項,使用
javascript_tool確認它 比對到恰好一個元素,且該元素是可見的:const q = 'div[data-testid="chat-input"]'; const n = document.querySelectorAll(q); console.log(JSON.stringify({ q, count: n.length, visible: n[0] ? !!(n[0].offsetWidth || n[0].offsetHeight) : false, tag: n[0]?.tagName, editable: n[0]?.isContentEditable, }));使用
read_console_messages讀回結果。如果比對到超過一個,或零個, 則表示需要繼續尋找 — 請勿寫入您尚未看到實際比對的選擇器。 -
寫入側車檔案
scripts/<name>.selectors.json:{ "resolvedAgainst": "https://claude.ai/new", "resolvedAt": "2026-08-10T09:00:00Z", "resolvedBy": "claude-in-chrome", "selectors": { "the message box at the bottom of the chat": { "spec": "div[data-testid=\"chat-input\"]", "evidence": "contenteditable tiptap div, aria-label 'Write a message', 1 match, visible" } } }以意圖文字為鍵值,必須與腳本中的完全相同 — 重新命名選擇器 或重新排序區塊不得使解析結果孤立。
spec是驅動程式可接受的任何格式: 原始 puppeteer 選擇器、btn:Text|Alt、或::-p-text(substring)。evidence是您實際觀察到的內容;請寫下來, 以便其他人可以判斷此選擇器是否仍然有效。 -
確認並交回。
node script.mjs ../scripts/<name>.demo --intents # 期望 0 個未解析 node script.mjs ../scripts/<name>.demo --print # 編譯報告您解析了哪些內容、您在哪些部分必須做出猜測,以及任何 因為需要破壞性步驟而跳過的項目。
當您無法解析時
請直接說明並停止;請不要虛構一個選擇器。未解析的意圖在 Chrome 啟動之前 就會產生乾淨的編譯錯誤。錯誤的選擇器則會在拍攝中途失敗,也就是在錄製 開始之後 — 這是最昂貴的失敗點。如果兩個元素同樣符合描述,請詢問使用者 他們指的是哪一個,而不是自行選擇。
注意事項
| 症狀 | 原因 / 修正 |
|---|---|
| 元素不在頁面上 | 它會在流程的後續階段出現。請依序逐步執行節拍;在元素實際出現在畫面上時,再解析每個意圖 |
| 兩個元素相符 | 描述不夠明確。請先與使用者確認,然後也修改腳本中的 ask,使下一次解析不會有歧義 |
| 選擇器現在可用,下次執行卻壞了 | 它是以產生的內容或產生的類別為鍵值。請重新定位到 testid、role 或容器上 |
wait ... gone 錨點 | 這些本質上是暫時性的(例如生成時的停止按鈕)。請在元素顯示於畫面上時解析,並優先使用 aria-label — 它比文字更不容易改變 |
| 重新設計後解析結果偏移 | 請只刪除側車檔案中的該鍵值並重新執行。.demo 不會改變;這就是重點 |
| 對話框封鎖了擴充功能 | 請不要點擊會開啟 confirm/alert 的東西。模態對話框會凍結擴充功能,直到手動關閉 |