mcpField
Q
qa-engineer

qa-engineer

github.com/anyproto测试与质量9.0k59 次安装5 天前更新
代码仓库

关于 qa-engineer

qa-engineer 是一项技能,可分析 anytype-ts 的近期改动,并在 `../anytype-desktop-suite` 仓库生成 Playwright 端到端测试。它聚焦于改动涉及的用户可见行为,并遵循现有测试模式、翻译键和选择器约定。

主要功能

  1. 01按改动界定测试范围
  2. 02映射用户可见行为
  3. 03生成 Playwright 端到端测试
  4. 04调研现有覆盖与页面对象
  5. 05翻译键和选择器约定
  6. 06测试计划与页面对象指引

适用场景

  1. 01功能改动后补充测试
  2. 02组件编辑后检查界面行为
  3. 03查找端到端测试覆盖缺口
  4. 04按测试套件约定创建测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anyproto/anytype-ts --skill qa-engineer

安装后在 Claude Code 中输入/qa-engineer确认已加载。

详细介绍

QA 工程师技能

分析 anytype-ts 中最近的代码变更,将其映射到可测试的面向用户行为,并在 ../anytype-desktop-suite 仓库中生成 Playwright E2E 测试。

使用时机

在以下情况启用此技能:

  • 实现新功能或修改现有功能后
  • 编辑器/组件变更影响用户交互后
  • 用户明确要求为近期变更添加测试
  • 完成 CLAUDE.md 的“QA Engineer”部分中提及的任务后

原则

  1. 由变更驱动 — 只测试实际发生变更的内容,不为未修改的代码生成测试
  2. 面向用户 — 关注可观察到的行为,而非实现细节
  3. 兼容 — 严格遵循 anytype-desktop-suite 中现有的测试模式
  4. 精简 — 每个功能领域一个测试文件,不要过度测试
  5. 考虑翻译 — 始终使用翻译键,绝不硬编码 UI 文本

流程

阶段 1:分析变更
  1. 确定变更内容 — 对比基准分支(或近期提交)运行 git diff,查看修改过的文件
  2. 对变更分类 — 判断哪些变更面向用户,哪些属于内部重构
  3. 映射到功能 — 将代码变更关联到可测试的用户流程:
    • 组件变更 → 要验证的 UI 交互
    • Store 变更 → 要测试的状态转换
    • 菜单/弹窗变更 → 打开/关闭/交互流程
    • 编辑器变更 → 块的创建、编辑和选择
    • API 变更 → 数据流和错误处理

跳过不会影响用户体验的纯内部变更(类型重构、工具函数提取、纯样式变更)。

阶段 2:调研现有覆盖范围
  1. 检查现有测试 — 在 ../anytype-desktop-suite/tests/ 中搜索已覆盖变更功能领域的测试
  2. 检查现有页面对象 — 在 ../anytype-desktop-suite/src/pages/ 中搜索与受影响组件交互的页面对象
  3. 检查测试计划 — 在 ../anytype-desktop-suite/specs/ 中搜索覆盖该领域的现有计划
  4. 找出缺口 — 确定尚未覆盖的内容
阶段 3:创建测试计划

按照以下格式,在 ../anytype-desktop-suite/specs/ 中编写测试计划:

# Feature Area — Test Plan

**Source changes:** List of changed files in anytype-ts
**Date:** YYYY-MM-DD

## Prerequisites
- Seed: `tests/seed.spec.ts` (creates account, opens vault)
- Any additional setup needed

### 1. Test Group Name
**Seed:** `tests/seed.spec.ts`

#### 1.1 Scenario Name
**Steps:**
1. Step description
2. Step description
**Expected:** What should happen

#### 1.2 Another Scenario
...
阶段 4:生成测试文件

按照以下严格约定,在 ../anytype-desktop-suite/tests/ 中创建测试文件:

文件结构
// spec: specs/plan-name.md
// seed: tests/seed.spec.ts

import { test, expect } from '../../src/fixtures';
import { restartGrpcServer } from '../../src/helpers/test-server';
// Import relevant page objects
import { SidebarPage } from '../../src/pages/main/sidebar.page';

test.describe('Feature Area', () => {
  test.describe.configure({ mode: 'serial' });

  test.beforeAll(async () => {
    await restartGrpcServer();
  });

  test('should do the expected behavior', async ({ page, translations }) => {
    const sidebar = new SidebarPage(page, translations);
    await sidebar.waitForReady();

    // Step: Description of what we're doing
    await page.getByText(translations.someTranslationKey).click();

    // Verify: Expected outcome
    await expect(page.locator('#some-element')).toBeVisible();
  });
});
规则
  1. 翻译 — UI 文本始终使用 translations.keyName。在 ../anytype-ts/dist/lib/json/lang/en-US.json 或 ../anytype-ts/src/json/text.json 中查找键
  2. 页面对象 — 使用 ../anytype-desktop-suite/src/pages/ 中现有的页面对象。仅在需要时创建新的页面对象
  3. 等待 — 使用 await expect(locator).toBeVisible() 或 waitFor({ state: 'visible' })。绝不使用 setTimeout、networkidle 或固定延迟
  4. 选择器 — 优先使用基于角色的选择器,其次是测试 ID、文本和 CSS 选择器
  5. 隔离 — 每个测试文件都在 beforeAll 中重启 gRPC 服务器。同一文件中的测试可在 serial 模式下共享状态
  6. 命名 — 文件名使用 kebab-case,并与功能相匹配:feature-name.spec.ts
  7. 目录 — 放入与功能领域相匹配的子目录:tests/editor/、tests/blocks/ 等
阶段 5:创建页面对象(如有需要)

如果变更的功能需要现有页面对象尚未覆盖的新页面交互,请创建新的页面对象:

import { BasePage } from '../base.page';

export class FeaturePage extends BasePage {
  // Locators
  get someButton() {
    return this.page.locator('#some-button');
  }

  get someText() {
    return this.page.getByText(this.t('translationKey'));
  }

  // Actions
  async waitForReady() {
    await this.someButton.waitFor({ state: 'visible' });
  }

  async doSomething() {
    await this.someButton.click();
    await expect(this.someText).toBeVisible();
  }
}

页面对象应放在 ../anytype-desktop-suite/src/pages/ 下合适的子目录中。

阶段 6:输出摘要

生成测试后,提供摘要:

## QA Engineer Summary

### Changes Analyzed
- file1.tsx — description of change
- file2.tsx — description of change

### Tests Generated
- `tests/feature/scenario-name.spec.ts` — what it tests
- `specs/feature-plan.md` — test plan

### New Page Objects
- `src/pages/main/feature.page.ts` — (if created)

### Coverage Notes
- What's covered by new tests
- What's NOT covered and why (e.g., requires manual testing, backend-only change)

### Run Tests
```bash
cd ../anytype-desktop-suite && npm test -- tests/feature/scenario-name.spec.ts

## Finding Translation Keys

To map UI text to translation keys:

1. Search `../anytype-ts/src/json/text.json` for the English text
2. The key is the JSON property name (e.g., `"authSelectSignup": "Create new vault"` → use `translations.authSelectSignup`)
3. For dynamic text with parameters, check how the component calls `translate()` with substitution params

## Finding Selectors

To find stable selectors for elements:

1. Search the component source in `../anytype-ts/src/ts/component/` for `id=`, `data-`, `className`
2. Check for block IDs: blocks typically have `#block-{id}` selectors
3. Check for menu IDs: menus use `#menu{Type}` pattern
4. Check for popup IDs: popups use `#popup{Type}` pattern
5. The sidebar uses `#sidebarPage{Section}` pattern

## Test Areas Mapping

| anytype-ts Area | Test Directory | Page Objects |
|---|---|---|
| `component/block/text.tsx` | `tests/editor/` | `pages/main/editor.page.ts` |
| `component/block/dataview.tsx` | `tests/dataview/` | `pages/main/dataview.page.ts` |
| `component/menu/` | `tests/menus/` | (inline or new page object) |
| `component/popup/` | `tests/popups/` | `pages/components/modal.component.ts` |
| `component/sidebar/` | `tests/sidebar/` | `pages/main/sidebar.page.ts` |
| `component/widget/` | `tests/widgets/` | `pages/main/widget.page.ts` |
| `component/page/main/graph.tsx` | `tests/graph/` | (new page object) |
| `component/page/auth/` | `tests/auth/` | `pages/auth/*.page.ts` |
| `store/` | (test via UI) | (use existing page objects) |

## What NOT to Test

- Pure TypeScript type changes
- Internal utility refactors with no UI impact
- CSS-only changes (unless they affect element visibility/layout)
- Backend (anytype-heart) changes — those have their own tests
- Build/config changes

评论

支持 Markdown