From zenbu-powers
當在 React IT Gherkin 測試中驗證「頁面顯示內容」時,「只能」使用此指令。 使用 screen.getByText/getByRole 等 Testing Library queries 驗證 rendered content。
npx claudepluginhub zenbuapps/zenbu-powers --plugin zenbu-powersThis skill uses the workspace's default tool permissions.
Then 語句驗證 **Query 操作後頁面顯示的內容**。
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Share bugs, ideas, or general feedback.
Then 語句驗證 Query 操作後頁面顯示的內容。
識別規則:
通用判斷:如果 Then 是驗證 Query 操作後頁面顯示的資料內容,就使用此 Handler。
使用 Testing Library 的 screen queries → Assert DOM 上的文字、數值、元素。
| readmodel-then | aggregate-then | |
|---|---|---|
| 抽象角色 | Result Verifier (資料) | States Verify |
| 資料來源 | 畫面 DOM(screen queries) | MSW 攔截的 request payload |
| 前提操作 | Query(render + 資料載入) | Command(user interaction + API call) |
| 驗證層級 | 表示層(使用者看到什麼) | 資料層(前端送出什麼) |
不重新 render — 使用 Query handler 步驟中已 render 的 Component 畫面。
screen.getByText(), screen.getByRole() 等查詢 DOMWhen 用戶 "Alice" 查詢課程 1 的進度
Then 操作成功
And 查詢結果應包含進度 80,狀態為 "進行中"
import { screen } from '@testing-library/react';
// 畫面已由 query handler render 完成
expect(screen.getByText('80%')).toBeInTheDocument();
expect(screen.getByText('進行中')).toBeInTheDocument();
// 或更精確地限定範圍:
// const progressSection = screen.getByTestId('progress-info');
// expect(within(progressSection).getByText('80%')).toBeInTheDocument();
Then 查詢結果應包含 2 個商品
import { screen, within } from '@testing-library/react';
const list = screen.getByRole('list');
const items = within(list).getAllByRole('listitem');
expect(items).toHaveLength(2);
And 第一個商品的 ID 應為 "PROD-001",數量為 2
const list = screen.getByRole('list');
const items = within(list).getAllByRole('listitem');
expect(within(items[0]).getByText('PROD-001')).toBeInTheDocument();
expect(within(items[0]).getByText('2')).toBeInTheDocument();
Then 查詢結果應包含以下課程:
| lessonId | name | progress |
| 1 | 物件導向基礎 | 80 |
| 2 | 設計模式 | 50 |
const table = screen.getByRole('table');
const rows = within(table).getAllByRole('row');
// rows[0] is header, data starts at rows[1]
expect(rows).toHaveLength(3); // header + 2 data rows
expect(within(rows[1]).getByText('物件導向基礎')).toBeInTheDocument();
expect(within(rows[1]).getByText('80')).toBeInTheDocument();
expect(within(rows[2]).getByText('設計模式')).toBeInTheDocument();
expect(within(rows[2]).getByText('50')).toBeInTheDocument();
Then 查詢結果應為空
expect(screen.getByText(/沒有資料|暫無|找不到/i)).toBeInTheDocument();
// 或
const list = screen.queryByRole('list');
if (list) {
expect(within(list).queryAllByRole('listitem')).toHaveLength(0);
}
// 驗證特定區塊內的內容
const card = screen.getByTestId('lesson-progress-card');
expect(within(card).getByText('80%')).toBeInTheDocument();
expect(within(card).getByText('進行中')).toBeInTheDocument();
UI 上顯示的是中文(如「進行中」),不需要做 enum 反向映射。直接用 screen.getByText('進行中') 驗證。
只有在 Gherkin 使用引號包裝的值(如 "進行中")需要確認 UI 確實顯示該中文文字。
getByRole → 語意化查詢(table, list, listitem, heading, button)
getByText → 文字內容查詢
within() → 限定搜尋範圍
getAllByRole → 批量查詢(列表、表格行)
queryByText → 預期可能不存在時使用(回傳 null 而非拋錯)
getByRole > getByText > getByTestId