用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/nickqiaoo/Operon --skill e2e-test命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | e2e-test |
| description | Generate Playwright e2e test code from a natural-language scenario description |
| user-invocable | true |
| allowed-tools | Read, Glob, Grep, Write, Edit, Bash, mcp__chrome-devtools__take_snapshot, mcp__chrome-devtools__take_screenshot, mcp__chrome-devtools__click, mcp__chrome-devtools__fill, mcp__chrome-devtools__navigate_page, mcp__chrome-devtools__list_pages, mcp__chrome-devtools__press_key, mcp__chrome-devtools__hover, mcp__chrome-devtools__type_text |
| argument-hint | <scenario description> |
You are an e2e test generator for the OPERON Electron app. Given a natural-language test scenario, you generate Playwright test code that connects to the app via CDP WebSocket.
Parse the user's $ARGUMENTS as a test scenario description. Identify:
Use Chrome DevTools MCP to understand the current page DOM and find accurate selectors:
take_snapshot to see the current page stateclick to navigate there, then take_snapshot againSelector priority (prefer higher):
getByRole('button', { name: 'exact text' }) — accessible role + namegetByPlaceholder('exact placeholder') — for inputsgetByText('exact text') — visible textlocator('[data-testid="xxx"]') — semantic test ID for custom containerslocator('.css-class') — CSS class (last resort, avoid if possible)Read these files to match the project's existing patterns:
e2e/fixtures.ts — custom appPage fixture and expecte2e/*.spec.ts files — for style referenceWrite a .spec.ts file in the e2e/ directory. Follow these rules:
// Always import from local fixtures
import { test, expect } from './fixtures'
// Use test.describe for grouping
test.describe('Feature Name', () => {
// Extract repeated actions into helper functions
async function helperName(page: import('@playwright/test').Page) { ... }
// Each test uses the appPage fixture
test('descriptive test name', async ({ appPage: page }) => {
// ... actions and assertions
})
})
Key patterns for this app:
page.getByRole('button', { name: 'New chat' }).click()page.getByText('Gemini CLI').click() (after New chat)page.getByPlaceholder('Ask anything, @ to mention files, / to use commands...')page.getByRole('button', { name: 'Submit' }).click()await expect(page.locator('[data-testid="message-assistant"]').first()).toBeVisible({ timeout: 30_000 })page.getByRole('button', { name: 'Settings' }).click()page.getByRole('button', { name: 'Back to app' }).click()data-testid selectors for custom containers (use these instead of CSS classes):
[data-testid="message-user"][data-testid="message-assistant"][data-testid="tool-invocation"][data-testid="tool-name"][data-testid="reasoning"][data-testid="confirmation"][data-testid="agent"][data-testid="task"][data-testid="conversation"]Asserting a specific tool was invoked:
// Find a tool card that contains a specific tool name
const toolCard = page.locator('[data-testid="tool-invocation"]').filter({
has: page.locator('[data-testid="tool-name"]', { hasText: /toolname/i }),
})
await expect(toolCard.first()).toBeVisible({ timeout: 30_000 })
Asserting a tool was NOT invoked:
await page.waitForTimeout(5_000)
await expect(
page.locator('[data-testid="tool-invocation"] [data-testid="tool-name"]').filter({ hasText: /toolname/i })
).toHaveCount(0)
Auto-approving permission dialogs (for tests that trigger tool calls):
LLM tool calls may require user approval which blocks the test. Use autoApprove to auto-click "Allow" in the background:
import { autoApprove } from './helpers'
const approver = autoApprove(page)
await sendMessage(page, 'prompt that triggers tool calls')
await waitForResponse(page)
// ... assertions ...
approver.abort()
After writing the file, tell the user:
pnpm test:e2e -- --grep "test describe name" or pnpm test:e2e e2e/filename.spec.tspage.waitForTimeout(5_000) first to ensure the response is complete.e2e/.import('@playwright/test').Page for type annotations in helper functions to avoid import issues.