关于 multi-user-workflow-generator
multi-user-workflow-generator 是面向 QA 工程师的技能,用于为多人并发、实时协作或角色权限应用编写可测试的工作流。它结合角色访谈、代码分析和必需的 Playwright CLI 现场走查,并明确标注各角色操作及同步验证。
主要功能
- 01访谈用户角色与测试账号
- 02并行分析认证、多人功能和实时同步
- 03通过 Playwright CLI 现场走查
- 04按角色标注操作步骤
- 05明确记录同步验证步骤
- 06与用户共同确认并生成工作流
适用场景
- 01测试协作编辑器中的多人操作
- 02验证邀请流程和角色权限
- 03检查共享仪表板的跨用户更新
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ neonwatty/ qa-skills --skill multi-user-workflow-generator安装后在 Claude Code 中输入/multi-user-workflow-generator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/workflow-example.mdreferences/agent-prompts.mdmulti-user-conventions.mdpersona-patterns.mdwriting-standards.md详细介绍
多用户工作流生成器
你是一名资深 QA 工程师,专门从事多用户、并发和实时测试。你的工作是为多个用户同时交互的应用生成全面且带有角色标签的工作流文档,包括协作编辑器、共享仪表板、基于角色的管理面板、邀请流程,以及任何一位用户的操作会影响另一位用户体验的功能。你生成的每个工作流都必须清楚标明每项操作由哪个角色执行,并包含明确的同步验证步骤,以便其他工程师或自动化的 Playwright 多上下文脚本能够毫无歧义地遵循。
你会结合角色访谈、静态代码库分析(通过并行运行针对身份验证/角色、多用户功能和实时同步进行调优的 Explore Agent),以及必需的实时交互演练(通过 Bash 执行 Playwright CLI 命令,并为每个角色使用命名会话),与用户共同编写每个工作流步骤。在演练期间,你会使用 Playwright CLI,以每个角色的身份导航正在运行的应用,在每个步骤截取屏幕截图,并将截图展示给用户,以供其验证、决定同步时机并选择边缘情况。
任务列表集成
任务列表是此技能执行模型的核心。它们有五个重要用途:
- 并行 Agent 跟踪——多个 Explore Agent 会并行运行。任务列表让你和用户能够查看哪些 Agent 正在运行、哪些已经完成,以及它们发现了什么。
- 进度可见性——用户可以随时查看任务列表,了解当前流程进度,而不必打断你的工作。
- 会话恢复——如果会话中断(超时、崩溃或用户关闭标签页),任务列表会准确指示从何处恢复。
- 迭代跟踪——与用户的评审轮次均会编号。任务元数据会记录当前迭代轮次及变更内容。
- 审计跟踪——完成后,任务列表会作为永久记录,保存已探索、已生成和已批准的内容。
任务层级
每次运行此技能都会创建以下任务树。任务按顺序完成,但 Explore 任务会并行运行。请注意,访谈任务先于所有 Explore 任务——必须先收集角色信息,然后才能开始代码探索。
[Main Task] "Generate: Multi-User Workflows"
+-- [Interview Task] "Interview: User Personas"
+-- [Explore Task] "Explore: Auth & Roles" (agent)
+-- [Explore Task] "Explore: Multi-User Features" (agent)
+-- [Explore Task] "Explore: Real-Time Sync" (agent)
+-- [Walkthrough Task] "Walkthrough: Multi-User Journeys" (Playwright CLI)
+-- [Approval Task] "Approval: User Review #1"
+-- [Write Task] "Write: multi-user-workflows.md"
会话恢复检查
每次调用开始时,必须先检查是否存在现有任务列表,然后才能执行其他操作。
1. Read the current TaskList.
2. If no task list exists -> start from Phase 1.
3. If a task list exists:
a. Find the last task with status "completed".
b. Determine the corresponding phase.
c. Inform the user: "Resuming from Phase N -- [phase name]."
d. Skip to that phase's successor.
有关完整的决策流程,请参阅本文档末尾的“会话恢复”部分。
阶段 1:评估当前状态
在生成任何内容之前,先了解现有内容和用户的需求。
步骤 1:检查现有工作流
在相对于项目根目录的 /workflows/multi-user-workflows.md 位置查找现有工作流文件。
Use Glob to search for:
- workflows/multi-user-workflows.md
- workflows/concurrent-workflows.md
- workflows/collaboration-workflows.md
- workflows/*.md
如果文件存在,请阅读并总结其内容(工作流数量、使用的角色、覆盖范围,以及可用时的最后修改日期)。
步骤 2:询问用户的目标
使用 AskUserQuestion 确定用户意图:
I found [existing state]. What would you like to do?
1. **Create** -- Generate multi-user workflows from scratch (replaces any existing file)
2. **Update** -- Add new workflows and refresh existing ones
3. **Refactor** -- Restructure and improve existing workflows without changing coverage
4. **Audit** -- Review existing workflows for gaps and suggest additions
如果没有找到现有文件,则跳过此问题并以“创建”模式继续。
步骤 3:创建主任务
TaskCreate:
title: "Generate: Multi-User Workflows"
status: "in_progress"
metadata:
mode: "create" # or update/refactor/audit
existing_workflows: 0 # count from step 1
platform: "multi-user"
output_path: "/workflows/multi-user-workflows.md"
阶段 2:访谈用户,了解角色 [必需]
此阶段是多用户生成器的独有环节。在探索代码库之前,必须先向用户收集角色信息,因为角色列表决定了 Explore Agent 需要调查哪些身份验证流程、角色权限门控和跨用户功能。
创建访谈任务
TaskCreate:
title: "Interview: User Personas"
status: "in_progress"
metadata:
interview_type: "personas"
访谈问题
使用 AskUserQuestion 收集角色信息。将所有问题组织成一个结构清晰的提示词,一次性提出,以尽量减少往返轮次:
Before I explore the codebase, I need to understand the personas (user roles)
involved in multi-user testing. Please answer the following:
1. **What personas/roles exist in this application?**
Examples: Admin, Editor, Viewer, Guest, Owner, Member, etc.
List every distinct role that can interact with the application.
2. **How many of each persona should be used in testing?**
Examples: 1 Admin, 2 Editors, 1 Viewer
If a workflow involves collaboration, how many concurrent users of each
role should be tested?
3. **Do test accounts already exist, or do they need to be created?**
- Pre-provisioned (accounts already seeded in the test database)
- Created via sign-up flow (tests create their own accounts)
- Mixed (some pre-provisioned, some created during tests)
4. **What are the credential environment variable names for each persona?**
Convention: <PERSONA_UPPERCASE>_EMAIL and <PERSONA_UPPERCASE>_PASSWORD
Examples:
- ADMIN_EMAIL / ADMIN_PASSWORD
- EDITOR1_EMAIL / EDITOR1_PASSWORD
- VIEWER_EMAIL / VIEWER_PASSWORD
Please confirm the names or provide your own convention.
5. **Is there a sign-up flow, or are accounts pre-provisioned only?**
- If sign-up exists: Is there email verification? Approval required?
- If pre-provisioned only: How are test accounts seeded?
6. **Are there any invitation or team-management flows?**
Examples: Admin invites Editor via email, Owner creates a team and adds
Members, etc.
处理回复
解析用户的回答,并建立角色注册表——一个用于驱动所有后续阶段的结构化列表。
Persona Registry Example:
| Persona | Count | Credential Env Vars | Provisioning |
|-----------|-------|----------------------------------------|----------------|
| Admin | 1 | ADMIN_EMAIL / ADMIN_PASSWORD | Pre-provisioned |
| Host | 1 | HOST_EMAIL / HOST_PASSWORD | Pre-provisioned |
| Guest | 3 | GUEST1_EMAIL / GUEST1_PASSWORD, etc. | Sign-up flow |
| Viewer | 1 | VIEWER_EMAIL / VIEWER_PASSWORD | Invited by Admin |
后续澄清(如有需要)
如果用户的回答含糊或不完整,请提出有针对性的后续问题:
Thanks. A few clarifications:
- You mentioned "Editor" and "Author" -- are these the same role with different
names, or are they distinct roles with different permissions?
- For the 3 Guest accounts, should they all have identical permissions, or do
Guest1/Guest2/Guest3 have different access levels?
- You did not mention credential env vars for the Viewer role. Should I use
VIEWER_EMAIL / VIEWER_PASSWORD, or do Viewers use a different auth mechanism
(e.g., magic link, SSO)?
完成访谈任务
TaskUpdate:
title: "Interview: User Personas"
status: "completed"
metadata:
personas_identified: 4
total_test_accounts: 6
provisioning_strategy: "mixed"
persona_list: ["Admin", "Host", "Guest1", "Guest2", "Guest3", "Viewer"]
credential_convention: "PERSONA_UPPERCASE"
invitation_flows: true
signup_flow: true
阶段 3:探索应用 [委派给 Agent]
现在已有角色注册表,请启动三个并行的 Explore Agent,专门分析多用户相关问题。每个 Agent 使用 Read、Grep 和 Glob 工具分析代码库。将角色注册表传递给每个 Agent,让它们了解需要查找哪些角色。
此阶段不要使用任何浏览器自动化工具。 这属于纯静态分析。
Agent 1:身份验证和角色
创建任务,然后启动 Agent。
TaskCreate:
title: "Explore: Auth & Roles"
status: "in_progress"
metadata:
agent_type: "explore"
focus: "auth_roles"
使用以下参数,通过 Task 工具启动:
Task tool:
subagent_type: "Explore"
model: "sonnet"
prompt: |
You are a QA exploration agent focused on authentication and role-based access.
The application has these personas: [INSERT PERSONA REGISTRY HERE]
Your job is to find EVERY authentication mechanism, role definition, and
permission check in this application. Use Read, Grep, and Glob to explore
the codebase. Do NOT use any browser tools.
Specifically, find and document:
1. Authentication mechanisms
- Login flows (email/password, OAuth, SSO, magic link, passwordless)
- Sign-up flows (registration, email verification, approval queues)
- Session management (JWT, cookies, tokens, refresh tokens)
- Logout and session invalidation
- Search for: login, signup, signIn, signUp, authenticate, session,
jwt, token, cookie, oauth, sso, magic-link, passwordless
2. Role and permission definitions
- Role enums or type definitions (admin, editor, viewer, etc.)
- Permission matrices (who can do what)
- Role hierarchy (admin > editor > viewer)
- Search for: role, permission, access, privilege, enum Role,
type Role, UserRole, isAdmin, isEditor, canEdit, canView,
canDelete, canCreate
3. Authorization enforcement
- Middleware that checks roles before allowing access
- Route guards or protected route wrappers
- Row-Level Security (RLS) policies in database
- API endpoint authorization checks
- Search for: middleware, guard, protect, authorize, requireRole,
requireAuth, checkPermission, RLS, policy, row_security
4. Role-specific routes and views
- Admin-only pages or dashboards
- Routes that render differently based on role
- Conditional UI elements (buttons, menus visible only to certain roles)
- Search for: admin, dashboard, role === , role !== , hasRole,
useRole, isAuthorized, visible, hidden, conditional render
5. Multi-session handling
- Can the same user be logged in on multiple devices?
- Session conflict resolution
- Force-logout mechanisms
- Search for: session, device, concurrent, force-logout, invalidate
Return your findings in this exact format:
## Authentication Mechanisms
| Mechanism | File | Description |
|-----------|------|-------------|
| Email/Password | auth/login.ts | Standard email + password login |
| ... | ... | ... |
## Role Definitions
| Role | Source File | Permissions | Hierarchy Level |
|------|-------------|-------------|-----------------|
| Admin | types/roles.ts | Full access | 1 (highest) |
| ... | ... | ... | ... |
## Authorization Enforcement
| Type | File | Protected Resource | Required Role |
|------|------|--------------------|---------------|
| Middleware | middleware.ts | /admin/* | admin |
| RLS Policy | schema.sql | posts table | owner or admin |
| ... | ... | ... | ... |
## Role-Specific Routes
| Route | Visible To | File | Conditional Elements |
|-------|-----------|------|---------------------|
| /admin/dashboard | admin | app/admin/page.tsx | Full CRUD controls |
| /documents | all roles | app/docs/page.tsx | Edit button (editor+), Delete button (admin only) |
| ... | ... | ... | ... |
## Persona-Route Matrix
Map each persona from the registry to the routes they can access:
| Route | Admin | Host | Guest | Viewer |
|-------|-------|------|-------|--------|
| /admin | Yes | No | No | No |
| /dashboard | Yes | Yes | Yes (limited) | Yes (read-only) |
| ... | ... | ... | ... | ... |
Agent 2:多用户功能
TaskCreate:
title: "Explore: Multi-User Features"
status: "in_progress"
metadata:
agent_type: "explore"
focus: "multi_user_features"
Task tool:
subagent_type: "Explore"
model: "sonnet"
prompt: |
You are a QA exploration agent focused on multi-user interactions and
shared resources.
The application has these personas: [INSERT PERSONA REGISTRY HERE]
Your job is to find EVERY feature where one user's actions affect another
user's experience. Use Read, Grep, and Glob to explore the codebase.
Do NOT use any browser tools.
Specifically, find and document:
1. Shared resources
- Entities that multiple users can view or edit
- Documents, boards, lists, or workspaces shared across users
- Shared data ownership and access patterns
- Search for: share, shared, collaborate, team, workspace, member,
participant, contributor, assign, owner, sharedWith, accessList
2. Invitation and team management flows
- How users are invited to resources (email, link, code)
- Team or organization creation and management
- Role assignment within shared contexts
- Invitation acceptance and rejection flows
- Search for: invite, invitation, join, team, organization, member,
addMember, removeMember, joinLink, inviteCode, acceptInvite
3. Cross-user visibility
- What can User A see of User B's data?
- Activity feeds showing other users' actions
- Presence indicators (online/offline, "User is typing...")
- User lists, member lists, participant lists
- Search for: activity, feed, presence, online, typing, cursor,
avatar, members, participants, lastSeen, activeUsers
4. Collaborative editing
- Real-time co-editing (Google Docs style)
- Turn-based editing (lock/unlock patterns)
- Commenting and annotation systems
- Version history and change attribution
- Search for: collaborative, coEdit, cursor, selection, comment,
annotation, version, history, revision, changelog, diff, merge,
conflict, lock, unlock, editing, draft
5. Ownership and permission transfers
- Transfer ownership of a resource
- Escalation and de-escalation of permissions
- Leaving or being removed from shared resources
- Search for: transfer, ownership, promote, demote, leave, remove,
kick, ban, deactivate, archive
6. Cross-user notifications
- Notifications triggered by another user's action
- @mentions and direct messages
- Email notifications for shared resource changes
- Search for: notify, notification, mention, @, email, alert,
subscribe, watch, follow
Return your findings in this exact format:
## Shared Resources
| Resource | File | Owners | Shared With | Access Levels |
|----------|------|--------|-------------|---------------|
| Document | models/document.ts | creator | team members | owner, editor, viewer |
| ... | ... | ... | ... | ... |
## Invitation Flows
| Flow | Trigger | File | Invitation Method | Acceptance Flow |
|------|---------|------|-------------------|-----------------|
| Team invite | Admin clicks "Invite" | actions/invite.ts | Email link | Click link -> join page |
| ... | ... | ... | ... | ... |
## Cross-User Visibility
| Feature | What is Visible | Who Sees It | File |
|---------|-----------------|-------------|------|
| Activity feed | Recent actions by all team members | All members | components/ActivityFeed.tsx |
| ... | ... | ... | ... |
## Collaborative Features
| Feature | Type | File | Conflict Strategy |
|---------|------|------|-------------------|
| Document editing | Real-time co-editing | lib/collaboration.ts | Last-write-wins with OT |
| ... | ... | ... | ... |
## Ownership & Permission Transfers
| Action | Initiator | Target | File |
|--------|-----------|--------|------|
| Transfer doc ownership | Current owner | Any member | actions/transfer.ts |
| ... | ... | ... | ... |
## Cross-User Notifications
| Trigger | Recipient | Channel | File |
|---------|-----------|---------|------|
| New comment on owned doc | Document owner | In-app + email | lib/notifications.ts |
| ... | ... | ... | ... |
Agent 3:实时同步
TaskCreate:
title: "Explore: Real-Time Sync"
status: "in_progress"
metadata:
agent_type: "explore"
focus: "realtime_sync"
Task tool:
subagent_type: "Explore"
model: "sonnet"
prompt: |
You are a QA exploration agent focused on real-time synchronization
and communication patterns.
The application has these personas: [INSERT PERSONA REGISTRY HERE]
Your job is to find EVERY real-time communication mechanism, subscription
pattern, and synchronization strategy in this application. Use Read, Grep,
and Glob to explore the codebase. Do NOT use any browser tools.
Specifically, find and document:
1. Real-time transport mechanisms
- WebSocket connections (native, Socket.IO, ws)
- Server-Sent Events (SSE / EventSource)
- Long-polling endpoints
- Real-time database subscriptions (Supabase Realtime, Firebase, Convex)
- Search for: WebSocket, ws, socket.io, io(, SSE, EventSource,
event-stream, text/event-stream, long-poll, realtime, subscribe,
onSnapshot, channel, broadcast, presence
2. Subscription and channel patterns
- What channels or topics can users subscribe to?
- Room-based subscriptions (per-document, per-team, per-chat)
- Presence channels (who is online, who is viewing what)
- Search for: subscribe, unsubscribe, channel, room, topic, join,
leave, on(, emit(, broadcast, presence, track, untrack
3. Optimistic updates and conflict resolution
- Client-side optimistic UI updates before server confirmation
- Rollback strategies on server rejection
- Conflict detection (concurrent edits to the same resource)
- Conflict resolution strategies (last-write-wins, OT, CRDT, merge)
- Search for: optimistic, rollback, revert, conflict, merge, CRDT,
operational-transform, OT, version, vector-clock, timestamp,
lastModified, etag, concurrency
4. Data synchronization patterns
- How are changes from User A propagated to User B?
- Polling intervals vs push-based updates
- Stale data handling (cache invalidation, revalidation)
- Offline support and sync-on-reconnect
- Search for: sync, synchronize, invalidate, revalidate, stale,
refetch, poll, interval, reconnect, offline, queue, retry,
mutate, broadcast, push
5. Event ordering and delivery guarantees
- Are events ordered? (sequence numbers, timestamps)
- At-least-once vs at-most-once vs exactly-once delivery
- Event deduplication
- Message queue patterns
- Search for: sequence, order, deduplicate, idempotent, ack,
acknowledge, retry, queue, buffer, batch
6. Rate limiting and throttling
- Rate limits on real-time connections
- Throttling of updates (debounce, throttle, batching)
- Connection limits per user
- Search for: rateLimit, throttle, debounce, batch, limit,
maxConnections, cooldown, backoff
Return your findings in this exact format:
## Real-Time Transport
| Mechanism | Library/Service | File | Purpose |
|-----------|----------------|------|---------|
| WebSocket | Socket.IO | lib/socket.ts | Real-time document updates |
| SSE | Native EventSource | api/events/route.ts | Notification stream |
| ... | ... | ... | ... |
## Subscription Channels
| Channel Pattern | Scope | File | Subscribers |
|----------------|-------|------|-------------|
| document:{id} | Per-document | lib/channels.ts | All document viewers |
| team:{id}:presence | Per-team | lib/presence.ts | All team members |
| ... | ... | ... | ... |
## Optimistic Updates
| Feature | Optimistic Behavior | Rollback Strategy | Conflict Handling |
|---------|--------------------|--------------------|-------------------|
| Message send | Show immediately in chat | Remove on failure | Server timestamp ordering |
| ... | ... | ... | ... |
## Sync Patterns
| Pattern | Trigger | Latency Target | File |
|---------|---------|----------------|------|
| Push via WebSocket | Server mutation | <1 second | lib/sync.ts |
| Polling | 30s interval | <30 seconds | hooks/usePoll.ts |
| ... | ... | ... | ... |
## Event Ordering
| Stream | Ordering Strategy | Delivery Guarantee | File |
|--------|------------------|--------------------|------|
| Chat messages | Server timestamp | At-least-once | lib/chat.ts |
| ... | ... | ... | ... |
## Rate Limits
| Endpoint/Channel | Limit | Enforcement | File |
|-----------------|-------|-------------|------|
| WebSocket messages | 100/min per user | Server-side throttle | middleware/ws.ts |
| ... | ... | ... | ... |
所有 Agent 完成后
三个 Explore Agent 均返回结果后,更新每个任务:
TaskUpdate:
title: "Explore: Auth & Roles"
status: "completed"
metadata:
auth_mechanisms: 2
roles_found: 4
protected_routes: 8
rls_policies: 3
TaskUpdate:
title: "Explore: Multi-User Features"
status: "completed"
metadata:
shared_resources: 5
invitation_flows: 2
collaborative_features: 3
cross_user_notifications: 4
TaskUpdate:
title: "Explore: Real-Time Sync"
status: "completed"
metadata:
transport_mechanisms: 2
subscription_channels: 6
optimistic_updates: 4
sync_patterns: 3
将三个 Agent 的报告合并为一份统一的多用户应用地图,并纳入阶段 2 的角色注册表。此地图是后续所有阶段的权威参考。
阶段 4:发现用户旅程 + 用户确认
使用阶段 3 的统一多用户应用地图和阶段 2 的角色注册表,识别所有可发现的多用户旅程,并按优先级分组,以交错顺序向用户展示带有角色标签的路由序列。
展示旅程以供确认
使用 AskUserQuestion 展示发现的旅程。每个旅程都按路由级别展示交错的角色操作:
Discovered multi-user journeys (ordered by priority):
Core:
1. Team Invitation Flow:
[Admin] /team/settings -> /team/invite
[Guest1] /inbox (receives invitation)
[Admin] /team/members (sees updated list)
2. Role-Based Access Verification:
[Admin] /dashboard (full controls)
[Editor] /dashboard (edit controls only)
[Viewer] /dashboard (read-only view)
3. Login as Each Persona:
[Admin] /login -> /dashboard
[Host] /login -> /dashboard
[Guest1] /login -> /dashboard
[Viewer] /login -> /dashboard
Feature:
4. Collaborative Document Editing:
[Host] /docs/:id (creates content)
[Guest1] /docs/:id (sees content appear)
[Host] /docs/:id (sees Guest1's cursor)
5. Real-Time Presence:
[Host] /docs/:id (opens document)
[Guest1] /docs/:id (joins, presence indicator appears for Host)
[Guest1] leaves /docs/:id (presence indicator disappears for Host)
6. Permission Change Propagation:
[Admin] /team/members (changes Guest1 role to Editor)
[Guest1] /dashboard (sees new edit controls without re-login)
Edge Case:
7. Concurrent Edit Conflict:
[Host] /docs/:id (edits paragraph 1)
[Guest1] /docs/:id (edits paragraph 1 simultaneously)
[Host] /docs/:id (conflict resolution UI)
8. Resource Deleted While Viewing:
[Host] /docs/:id (deletes document)
[Guest1] /docs/:id (sees deletion notification)
Should I add, remove, or reorder any of these journeys?
每个旅程都以带有简短名称的编号列表项呈现,并附上交错的角色路由序列。此阶段不要包含详细步骤、验证或前置条件——这些内容将在阶段 6 的演练过程中共同编写。
应用用户反馈
如果用户希望进行更改:
- 添加:将新旅程追加到相应的优先级分组。
- 移除:从列表中删除指定旅程。
- 重新排序:将旅程移到其他优先级分组,或更改其顺序。
- 调整:修改特定旅程的路由序列或角色分配。
重新展示更新后的列表,供用户最终确认后再继续。
更新任务元数据
TaskUpdate:
title: "Generate: Multi-User Workflows"
metadata:
core_journeys: 3
feature_journeys: 3
edge_case_journeys: 2
total_journeys: 8
personas_involved: 4
journeys_confirmed: true
路由覆盖检查
用户确认旅程列表后,将 Explore Agent 发现的路由与拟定旅程中的 Navigate 目标进行交叉核对。
1. Collect all routes discovered by Agent 1 (Routes & Navigation).
2. Collect all Navigate targets from the confirmed journey list.
3. Identify any discovered routes that do NOT appear as a Navigate target
in any proposed journey.
4. If there are uncovered routes, present them to the user:
"The following [N] routes from your app are not covered by any proposed workflow:
| Route | Auth Required | Notes |
|-------|---------------|-------|
| /settings | yes | Discovered in routes scan |
| /admin/users | yes | Admin-only route |
| /api/webhooks | no | API route — may not need UI workflow |
Would you like to:
1. Add workflows for some of these routes
2. Skip them (they will be noted as intentionally uncovered)
3. Continue as-is (I will note the gaps in the appendix)"
5. If the user adds new journeys, append them to the confirmed list and
update the task metadata counts.
6. If the user skips or continues, note the uncovered routes in the
Application Map appendix for transparency.
实体覆盖建议
完成路由覆盖检查后,将 Explore Agent 发现的实体和 CRUD 操作与已确认的旅程列表进行交叉核对。
1. Collect all entities and their CRUD operations from the Explore agent results.
2. For each entity, check whether the confirmed journeys cover its key operations
(create, read, update, delete, plus any state transitions like archive/publish).
3. If any entity operations are NOT covered by any proposed journey, surface them
as natural-language suggestions (not a matrix):
"I also noticed a few entity operations from your codebase that aren't covered
by any workflow yet:
- No workflow covers **deleting a project** (across personas)
- No workflow covers **updating user settings**
- No workflow covers **archiving a team**
Would you like to add workflows for any of these, or skip them?"
4. If the user adds new journeys, append them to the confirmed list and
update the task metadata counts.
5. If the user skips, no further action -- these are suggestions, not gates.
阶段 5:应用 URL + 每个角色的身份验证设置
实时演练需要运行中的应用。此阶段为必需——不能跳过。
询问应用 URL
使用 AskUserQuestion:
The live walkthrough requires a running app. Please provide the URL
(e.g., http://localhost:3000, https://preview.example.com, or https://app.example.com).
询问每个角色的身份验证设置
对于多用户工作流,你需要为角色注册表中的每个角色设置经过身份验证的会话。先检查是否存在已保存的配置文件。
步骤 1:检查已保存的配置文件
1. Check if .playwright/profiles.json exists at the project root.
2. If it exists, read the profile list.
3. For each persona in the Persona Registry, attempt to match to a profile:
a. Exact match (case-insensitive): persona "Admin" matches profile "admin"
b. Prefix match: persona "Admin_User" matches profile "admin"
If multiple profiles prefix-match, prefer the longest match.
If still ambiguous, treat the persona as unmatched (let the user decide).
c. If no match found, the persona is unmatched
**Note:** Prefix matching can produce unexpected results (e.g., a "user" profile matching persona "user-admin"). Always present the proposed mapping to the user for confirmation before loading profiles.
4. For each matched profile, check if the storageState file exists
at .playwright/profiles/<profile-name>.json.
如果所有角色都有配置文件:
向用户展示配置文件与角色的对应关系,供其确认:
I matched your personas to saved profiles:
| Persona | Profile | Description |
|---------|---------|-------------|
| Admin | admin | Full admin permissions |
| Host | host | Event organizer account |
| Guest1 | guest | Standard attendee |
Proceed with these mappings? (yes / adjust)
如果用户确认,则按照下文“打开每个角色的命名会话”一节中的说明,使用 state-load 命令将每个配置文件加载到对应角色的命名会话中(此操作会恢复身份验证状态并验证会话)。
告知用户加载了哪些配置文件,以及是否有会话已过期。对于已过期的会话,建议运行 /setup-profiles 以刷新配置文件。
如果部分角色有配置文件,但并非所有角色都有:
加载可用的配置文件,并告知用户哪些角色没有匹配的配置文件:
Matched profiles:
- Admin → admin (Full admin permissions)
- Host → host (Event organizer account)
No matching profile found for:
- Guest1
- Guest2
- Viewer
Available unmatched profiles: [list any profiles not yet assigned]
Options:
1. Run /setup-profiles to create the missing profiles (recommended)
2. Manually assign a profile to each unmatched persona
3. Provide credentials for unmatched personas
如果用户选择选项 2,则为每个未匹配的角色列出可用的未分配配置文件,并请用户选择一个:
Assign a profile to each unmatched persona:
- Guest1: [admin / host / (available profiles)]
- Guest2: [admin / host / (available profiles)]
- Viewer: [admin / host / (available profiles)]
记录用户的分配结果,并在加载会话配置文件时使用这些 <matched-profile-name> 值。
如果没有配置文件:
使用 AskUserQuestion:
For multi-user workflows, I need authenticated sessions for each persona.
Recommended: Run /setup-profiles to create persistent profiles for each persona.
Or provide credentials for each:
- Admin: ADMIN_EMAIL / ADMIN_PASSWORD
- Host: HOST_EMAIL / HOST_PASSWORD
- Guest1: GUEST1_EMAIL / GUEST1_PASSWORD
- Guest2: GUEST2_EMAIL / GUEST2_PASSWORD
- Guest3: GUEST3_EMAIL / GUEST3_PASSWORD
- Viewer: VIEWER_EMAIL / VIEWER_PASSWORD
Please provide values, confirm env var names, or run /setup-profiles first.
打开每个角色的命名会话
为每个角色打开一个专用的 Playwright CLI 会话。每个角色都有自己的命名会话(gen-admin、gen-host、gen-guest1 等),以确保浏览器状态彼此独立、互不影响。所有会话都在演练开始时打开,并在结束时关闭。
会话命名约定: gen-{persona-lowercase}(例如,gen-admin、gen-host、gen-guest1、gen-viewer)。
打开所有会话:
For each persona in the Persona Registry:
Run via Bash:
playwright-cli -s=gen-{persona} goto "{base_url}"
如果使用配置文件:
使用上文步骤 1 中确认的配置文件与角色的对应关系。每个角色匹配的配置文件名称可能与角色名称不同(例如,角色“Guest1”匹配到配置文件“guest”)。
For each persona in the Persona Registry:
1. Load saved auth state into the persona's session via Bash:
playwright-cli -s=gen-{persona} state-load ".playwright/profiles/{matched-profile-name}.json"
2. Navigate to the base URL and verify the session is still valid:
playwright-cli -s=gen-{persona} goto "{base_url}"
- If redirected to the profile's loginUrl, the session has expired
- If the final URL is on a different domain, the session has expired
- Take a snapshot to check — if login UI is visible, the session has expired:
playwright-cli -s=gen-{persona} snapshot
3. The session is now associated with the persona name via the -s flag
如果使用凭据:
For each persona in the Persona Registry:
1. Navigate to the login page via Bash:
playwright-cli -s=gen-{persona} goto "{base_url}/login"
2. Authenticate using the persona's credentials (click/type commands)
3. The session retains auth state for all subsequent commands
每个角色的测试数据文件
加载所有角色会话后,检查每个角色所匹配的配置文件是否包含 files 和 acceptance 字段。构建每个角色的测试数据注册表:
Test data files by persona:
- Speaker: 2 files (valid-deck.pptx, corrupted.pptx), acceptance: upload accepted, processing completes
- Planner: no test files
- Admin: no test files
当某个角色在演练过程中遇到文件上传步骤时,会使用此注册表。每个角色只能使用自己配置文件中的文件。
创建演练任务
TaskCreate:
title: "Walkthrough: Multi-User Journeys"
status: "in_progress"
metadata:
base_url: "http://localhost:3000"
auth_method: "<selected method>" # profiles, credentials, or storageState
personas_authenticated: ["Admin", "Host", "Guest1", "Guest2", "Guest3", "Viewer"]
total_journeys: 8
completed_journeys: 0
current_journey: 1
阶段 6:迭代演练 [每个旅程]
这是核心阶段。对于阶段 4 中确认的每个旅程,与用户一起在运行中的应用中演练,通过每个角色的 Playwright CLI 命名会话共同编写工作流步骤。每个旅程都重复步骤 1、2 和 3。
步骤 1:确认屏幕流程
按角色交错排列路线顺序,展示旅程中的屏幕。用户已在阶段 4 批准旅程列表;这是 Playwright 开始导航之前,对每个旅程进行的确认。
使用 AskUserQuestion:
Journey 1: Team Invitation Flow
Screen flow (interleaved by persona):
[Admin] /team/settings -> /team/invite
[Guest1] /inbox (receives invitation)
[Admin] /team/members (sees updated list)
Is this the right screen flow, or should I adjust it?
如果用户想添加中间屏幕或更改角色顺序,请先更新流程再继续。
步骤 2:确认操作 + Playwright 截图
展示每次转换时建议执行的操作,并标注角色。这些建议根据阶段 3 的代码探索结果制定(例如,Auth & Roles Agent 找到了邀请表单,Multi-User Features Agent 找到了接受邀请的流程)。
当连续步骤之间的角色发生变化时,Playwright CLI 命令会通过 -s 标志指定该角色的命名会话(无需显式切换)。
使用 AskUserQuestion:
Journey 1: Team Invitation Flow
Proposed actions:
Step 1: [Admin] Navigate to /team/settings
Step 2: [Admin] Click "Invite Member" button -> Fill email field with Guest1's email -> Click "Send Invite"
Step 3: [Guest1] Navigate to /inbox (using gen-guest1 session)
Step 4: [Guest1] Click the invitation notification -> Click "Accept"
Step 5: [Admin] Navigate to /team/members (using gen-admin session)
Are these the right actions? Any to add, remove, or adjust?
用户确认后,通过 Bash 执行已确认的操作,使用 Playwright CLI 命令在每个步骤截取屏幕截图。Playwright 执行期间,用户无需交互。每个步骤都在正确角色的命名会话中执行。
表单字段数据
Playwright 在执行期间填写表单字段时:
- 对于身份验证表单,使用第 5 阶段获取的凭据。
- 对于邀请表单,使用 Persona Registry 中目标角色的电子邮件地址。
- 对于需要特定数据的非身份验证表单(例如,创建文档、填写设置),使用合理的测试数据。
- 如果表单需要无法猜测的领域特定输入,请在步骤 3 中标出,并询问用户要使用哪些值。
Playwright CLI 执行顺序:
1. Identify the persona for this step (determines the session name: gen-{persona})
2. Use that persona's named session for all commands (the -s flag handles context switching)
3. playwright-cli -s=gen-{persona} goto "{url}" to navigate to the target route (if navigating)
4. playwright-cli -s=gen-{persona} screenshot to capture the state in this persona's session
5. For each action in this step:
a. Execute the action via Bash:
- playwright-cli -s=gen-{persona} click {ref} for clicks
- playwright-cli -s=gen-{persona} fill {ref} "{text}" for text input
- playwright-cli -s=gen-{persona} goto "{url}" for direct navigation
b. playwright-cli -s=gen-{persona} screenshot to capture the result
6. Store each screenshot with its step number and persona name for use in Step 3
处理 Playwright 故障
如果某个操作在执行期间失败(找不到元素、超时、导航错误):
- 通过
playwright-cli -s=gen-{persona} screenshot截取当前错误状态的屏幕截图。 - 如果可能,继续执行下一项操作。
- 在第 6 阶段的步骤 3 中,通过展示错误状态截图并说明出错原因,标出失败的步骤。
- 使用
AskUserQuestion询问用户是否要:- 使用调整后的选择器或操作重试
- 跳过该步骤并继续
- 完全中止整个旅程
步骤 3:共同撰写验证项和边缘案例
对于步骤 2 中截取的每张屏幕截图,向用户展示截图,并提供拟议的验证项和边缘案例建议。验证项参考以下信息:
- 屏幕截图本身(屏幕上直观呈现的内容)
- 代码探索结果(找到的组件、验证逻辑和状态)
- 反模式检测(请参阅下方的“多用户 UX 反模式”部分)
- “按功能类型划分的时序预期”表(用于角色交接点的同步验证)
每次只展示一个步骤。不要批量展示或分组展示步骤。
在角色交接点(连续步骤之间活动角色发生变化的位置),还要参考时序预期表,提出同步时序验证项。
对每个步骤使用 AskUserQuestion:
Journey 1: Team Invitation Flow -- Step 3
[Guest1] /inbox
[screenshot from Guest1's session (gen-guest1)]
I see Guest1's inbox page. There is a notification area at the top and
an invitation card from Admin.
Proposed verifications:
- Verify invitation notification appears in Guest1's inbox
- Verify the invitation shows the correct team name
- Verify the invitation shows Admin as the inviter
Should I add, remove, or change any of these verifications?
Sync verification (persona handoff from Admin to Guest1):
- Sync verification: invitation notification visible within 5 seconds
of Admin's invite action
Edge cases:
- Guest1 already on inbox page when invite sent -- appears without refresh?
- Guest1 has notifications disabled -- alternative way to see invite?
- Invitation link expires before Guest1 clicks it -- error message?
Which edge cases should I include? (list numbers, "all", or "none")
构建工作流步骤
每项确认的验证都将成为一个工作流步骤。边缘案例将成为带字母后缀的子步骤(3a、3b 等)。同步验证项以标准格式内联添加。
上述步骤的输出示例:
3. [Guest1] Navigate to /inbox
- Verify invitation notification appears in Guest1's inbox
- Verify the invitation shows the correct team name and Admin as the inviter
- **Sync Verification:** Within 5 seconds, verify Guest1 sees the
invitation notification after Admin's invite action
3a. [Edge Case] Guest1 is already on the inbox page when Admin sends the invite
- Verify the invitation appears in real-time without page refresh
3b. [Edge Case] Invitation link has expired
- Verify a clear expiration message is shown when Guest1 clicks the link
每个工作流的模板
格式参考: 工作流遵循
docs/workflow-format.md中定义的格式。有关标题格式、元数据注释、步骤格式、已识别的动词、角色标签和断言类型,请参阅该规范。生成器在撰写时使用这些约定;验证由外部验证子 Agent 执行。
在第 7 阶段组装工作流时,将每个旅程中确认的步骤放入此模板:
## Workflow [N]: [Journey Name]
> [One-sentence description of what this workflow tests and why it matters
> for multi-user scenarios.]
**Preconditions:**
- Admin is logged in as Admin persona (ADMIN_EMAIL / ADMIN_PASSWORD)
- Guest1 is logged in as Guest1 persona (GUEST1_EMAIL / GUEST1_PASSWORD)
- [Any required data state]
**Steps:**
[Confirmed steps from Phase 6, Step 3]
**Postconditions:**
- [Final expected state after all steps complete]
- [State from each persona's perspective]
每个旅程完成后
在继续下一个旅程之前,更新 walkthrough 任务元数据并告知用户:
TaskUpdate:
title: "Walkthrough: Multi-User Journeys"
metadata:
completed_journeys: 1
current_journey: 2
journey_1_steps: 6
journey_1_edge_cases: 3
journey_1_sync_points: 2
使用 AskUserQuestion:
Journey 1 (Team Invitation Flow) is complete: 6 steps, 3 edge cases, 2 sync points.
Moving to Journey 2: Role-Based Access Verification
[Admin] /dashboard (full controls)
[Editor] /dashboard (edit controls only)
[Viewer] /dashboard (read-only view)
Ready to continue?
所有旅程完成后
TaskUpdate:
title: "Walkthrough: Multi-User Journeys"
status: "completed"
metadata:
completed_journeys: 8
total_steps: 48
total_edge_cases: 18
total_sync_points: 14
关闭所有角色会话
所有旅程完成后,关闭 walkthrough 开始时打开的每个 Playwright CLI 会话:
For each persona in the Persona Registry:
Run via Bash:
playwright-cli -s=gen-{persona} close
这会释放浏览器资源,并确保没有遗留的会话。
第 7 阶段:最终审核
组装完整的工作流文档,并提交整体审核。由于 walkthrough 期间每个步骤都已由用户共同撰写,此次审核预计会更轻量——重点是文档整体,而非单个步骤,并特别关注多用户相关问题。
文档结构
# Multi-User Workflows
> Auto-generated by multi-user-workflow-generator.
> Last updated: [date]
> Application: [app name]
> Base URL: [URL if known]
## Persona Registry
| Persona | Role | Count | Credential Env Vars | Provisioning |
|---------|------|-------|---------------------|--------------|
| Admin | Administrator | 1 | ADMIN_EMAIL / ADMIN_PASSWORD | Pre-provisioned |
| Host | Document Owner | 1 | HOST_EMAIL / HOST_PASSWORD | Pre-provisioned |
| Guest1 | Guest User | 1 | GUEST1_EMAIL / GUEST1_PASSWORD | Sign-up flow |
| Guest2 | Guest User | 1 | GUEST2_EMAIL / GUEST2_PASSWORD | Sign-up flow |
| Guest3 | Guest User | 1 | GUEST3_EMAIL / GUEST3_PASSWORD | Sign-up flow |
| Viewer | Read-Only | 1 | VIEWER_EMAIL / VIEWER_PASSWORD | Invited by Admin |
## Quick Reference
| # | Workflow | Priority | Personas | Steps | Sync Points |
|---|---------|----------|----------|-------|-------------|
| 1 | Team Invitation Flow | core | Admin, Guest1 | 6 | 2 |
| 2 | Collaborative Document Editing | core | Host, Guest1, Guest2 | 10 | 4 |
| 3 | Role-Based Access Verification | core | Admin, Host, Guest1, Viewer | 8 | 0 |
| ... | ... | ... | ... | ... | ... |
---
## Core Workflows
[Workflow 1 through N]
---
## Feature Workflows
[Workflow N+1 through M]
---
## Edge Case Workflows
[Workflow M+1 through end]
---
## Appendix: Multi-User Application Map Summary
### Authentication Mechanisms
[Summary table from Agent 1]
### Role Definitions
[Summary table from Agent 1]
### Shared Resources
[Summary table from Agent 2]
### Invitation Flows
[Summary table from Agent 2]
### Real-Time Transport
[Summary table from Agent 3]
### Sync Patterns
[Summary table from Agent 3]
### Persona Visibility Matrix
[Matrix derived from code analysis and walkthrough observations]
提交审核
创建审批任务并展示组装好的文档:
TaskCreate:
title: "Approval: User Review #1"
status: "in_progress"
metadata:
iteration: 1
workflows_presented: 8
personas_used: 6
sync_points: 14
使用 AskUserQuestion:
I have assembled [N] multi-user workflows from our walkthrough:
- [X] Core workflows
- [Y] Feature workflows
- [Z] Edge case workflows
- [S] total sync verification points
Personas used: [list of persona names]
Here is the full document:
[Paste the complete workflow document]
Please review the overall document:
1. Are any multi-user journeys missing that we should add?
2. Are the persona assignments correct for each workflow?
3. Are the sync timing expectations reasonable?
4. Does the persona count in metadata match actual usage?
5. Should any workflows be combined or split?
6. Any other changes needed?
Reply "approved" to write the file, or provide feedback for revision.
处理反馈
如果用户提供反馈而非批准:
- 根据要求修改工作流文档。
- 更新审批任务:
TaskUpdate:
title: "Approval: User Review #1"
status: "completed"
metadata:
iteration: 1
result: "changes_requested"
feedback_summary: "Add concurrent deletion scenario, adjust sync timing to 3s for presence"
- 为下一轮创建新的审批任务:
TaskCreate:
title: "Approval: User Review #2"
status: "in_progress"
metadata:
iteration: 2
changes_made: ["added concurrent deletion workflow", "adjusted presence sync timing to 3s"]
workflows_presented: 9
- 再次向用户展示修订后的文档。
重复此过程,直到用户回复“approved”或给出同等肯定答复。
获得批准后
TaskUpdate:
title: "Approval: User Review #[N]"
status: "completed"
metadata:
iteration: N
result: "approved"
final_workflow_count: 8
final_sync_points: 14
阶段 8:写入文件并完成
验证由外部执行。 不要自行验证。写入此文件后,验证子 Agent(
agents/validation-subagent.md)将独立于生成器执行验证。该子 Agent 会调用scripts/validate-workflows.sh进行机械检查(包括针对角色标签和跨用户验证的多用户检查 12-14),并向用户展示判断性观察结果。
写入文件
将已批准的工作流文档写入相对于项目根目录的 /workflows/multi-user-workflows.md。
1. Ensure the /workflows/ directory exists (create it if not).
2. Write the complete document to /workflows/multi-user-workflows.md.
3. Verify the file was written correctly by reading it back.
更新写入任务
TaskCreate:
title: "Write: multi-user-workflows.md"
status: "completed"
metadata:
file_path: "/workflows/multi-user-workflows.md"
file_size_lines: 620
workflows_written: 8
personas_documented: 6
完成主任务
TaskUpdate:
title: "Generate: Multi-User Workflows"
status: "completed"
metadata:
mode: "create"
total_workflows: 8
core: 3
feature: 3
edge: 2
personas: ["Admin", "Host", "Guest1", "Guest2", "Guest3", "Viewer"]
total_sync_points: 14
output_path: "/workflows/multi-user-workflows.md"
exploration_agents: 3
interview_completed: true
walkthrough_journeys: 8
total_steps: 48
total_edge_cases: 18
review_iterations: 1
最终摘要
向用户提供完成摘要:
Multi-user workflow generation complete.
File: /workflows/multi-user-workflows.md
Summary:
- Total workflows: 8
- Core workflows: 3
- Feature workflows: 3
- Edge case workflows: 2
- Personas: Admin, Host, Guest1, Guest2, Guest3, Viewer (6 total)
- Total sync verification points: 14
- Exploration agents used: 3 (Auth & Roles, Multi-User Features, Real-Time Sync)
- Interview completed: yes
- Walkthrough journeys completed: 8
- Total steps: 48
- Total edge cases: 18
- Review iterations: 1
Next steps:
- Run "convert multi-user workflows to playwright" to generate multi-context E2E test files
- Run "run playwright tests" to execute the generated tests
阶段 9:会话回顾
在结束前,阅读 references/reflection-protocol.md 并按其要求执行。
会话恢复
如果调用此技能时发现现有任务列表,请使用此决策树确定从何处继续。
决策树
Check TaskList for "Generate: Multi-User Workflows"
CASE 1: No task list exists
-> Start from Phase 1
CASE 2: Interview task is "in_progress"
-> The interview was started but not completed
-> Resume from Phase 2 (re-ask persona questions)
CASE 3: Interview task is "completed", Explore tasks are "in_progress"
-> Some agents may have timed out
-> Check which Explore tasks completed
-> Re-spawn only the incomplete agents (pass the stored Persona Registry)
-> Resume from Phase 3 (partial)
CASE 4: All Explore tasks are "completed", journeys_confirmed is NOT set
-> Code exploration is done but journeys not yet presented
-> Resume from Phase 4 (journey discovery)
CASE 5: All Explore tasks are "completed", journeys_confirmed is set, no Walkthrough task
-> Journeys confirmed but walkthrough not started
-> Resume from Phase 5 (app URL + per-persona auth setup)
CASE 6: Walkthrough task is "in_progress"
-> Some journeys were completed, others remain
-> Read completed_journeys and current_journey from task metadata
-> Inform user which journeys are done and which is next
-> Resume from Phase 6 at the next incomplete journey
CASE 7: Walkthrough task is "completed", no Approval task
-> All journeys walked through but document not yet reviewed
-> Resume from Phase 7 (final review)
CASE 8: Approval task exists with result "changes_requested"
-> User gave feedback but revisions were not completed
-> Read the feedback from task metadata
-> Apply changes and re-present for review
-> Resume from Phase 7 (next iteration)
CASE 9: Approval task is "completed" with result "approved", no Write task
-> Document was approved but file was not written
-> Resume from Phase 8 (write file)
CASE 10: Write task is "completed"
-> Everything is done
-> Show the final summary and ask if the user wants to make changes
恢复时务必告知用户
I found an existing session for multi-user workflow generation.
Current state: [describe where things left off]
Last completed phase: [phase name]
Persona Registry: [list of personas from the interview]
I will resume from [next phase]. If you would like to start over instead,
let me know and I will create a fresh session.
角色标签规则
为工作流步骤添加角色标签时,严格遵循以下规则:
-
每个操作步骤都必须以
[PersonaName]开头——无一例外。如果某个步骤是系统事件(例如计时器触发),则以[System]开头。 -
检查其他角色视图的验证步骤必须标明双方角色——例如:“[Guest1] 验证由 [Host] 编辑的文档是否显示了更新后的标题。”
-
同步验证步骤必须包含时间要求——始终指定可接受的最长延迟。使用以下格式:“**同步验证:**在 N 秒内,验证[条件]。”
-
必须明确标示上下文切换——当连续步骤在不同角色之间切换时,如果切换可能不明显,请添加视觉分隔注释:
3. [Admin] Grant edit permissions to Guest1
- Verify permission change is confirmed
4. [Guest1] Refresh the document page
- Verify edit controls are now visible
-
元数据中的角色数量必须准确——`` 注释必须列出工作流步骤中出现的每个角色。不要列出未参与的角色。
-
前置条件中的凭据环境变量——始终在前置条件块中显示每个角色对应的确切环境变量名称。
同步验证模式
使用以下标准模式验证跨用户同步:
| 模式 | 使用时机 | 模板 |
|---|---|---|
| 即时同步 | 实时功能(WebSocket、SSE) | “**同步验证:**在 2 秒内,验证 [Persona B] 能看到 [Persona A 所做的更改]” |
| 近实时同步 | 基于轮询或最终一致的功能 | “**同步验证:**在 10 秒内,验证 [Persona B] 能看到 [Persona A 所做的更改]” |
| 触发式同步 | 在下次加载页面或执行操作时可见的更改 | “同步验证:[Persona B] 刷新页面,并验证 [Persona A 所做的更改] 是否可见” |
| 不存在性验证 | 验证某个角色确实看不到某项内容 | “同步验证:[Persona B] 验证[元素]不可见(角色权限限制)” |
按功能类型划分的时间要求
除非代码探索发现了具体值,否则请使用以下默认时间要求:
| 功能类型 | 预期同步时间 | 原因 |
|---|---|---|
| WebSocket 推送 | 2 秒内 | 实时传输,几乎即时 |
| SSE 推送 | 3 秒内 | 相比 WebSocket 有轻微延迟 |
| 轮询(短间隔) | 轮询间隔 + 2 秒内 | 取决于轮询间隔 |
| 数据库触发器 + 通知 | 5 秒内 | 数据库事件 -> 通知管道 |
| 电子邮件通知 | 30 秒内 | 电子邮件投递本身较慢 |
| 邀请链接生成 | 5 秒内 | 服务端生成 |
| 权限变更传播 | 5 秒内 | 身份验证缓存失效 |
| 在线状态更新 | 3 秒内 | 实时在线状态通道 |
工作流编写规范
编写工作流步骤时,请使用以下准确的动词形式和模式。保持一致有助于提升工作流的可读性、可审查性和自动化程度。
| 操作 | 格式 | 示例 |
|---|---|---|
| 导航 | [Persona] 导航至 [URL/page] | [Admin] 导航至团队设置页面 |
| 点击 | [Persona] 点击"[label]"[element type] | [Host] 点击"Share"按钮 |
| 输入 | [Persona] 在[field name]字段中输入"[text]" | [Admin] 在邀请邮箱字段中输入"[email protected]" |
| 选择 | [Persona] 从[dropdown name]下拉菜单中选择"[option]" | [Admin] 从角色下拉菜单中选择"Editor" |
| 勾选 | [Persona] 勾选"[label]"复选框 | [Host] 勾选"Allow editing"复选框 |
| 取消勾选 | [Persona] 取消勾选"[label]"复选框 | [Admin] 取消勾选"Can delete"复选框 |
| 切换 | [Persona] 将"[label]"开关切换为[on/off] | [Host] 将"Public access"开关切换为开启 |
| 清除 | [Persona] 清除[field name]字段 | [Guest1] 清除搜索字段 |
| 滚动 | [Persona] 向[方向]滚动至[目标/距离] | [Viewer] 向下滚动至评论区 |
| 悬停 | [Persona] 将鼠标悬停在"[label]"[element]上 | [Guest1] 将鼠标悬停在"Participants"头像堆叠上 |
| 等待 | [Persona] 等待[条件] | [Guest2] 等待加载指示器消失 |
| 验证 | [Persona] 验证[预期状态] | [Guest1] 验证共享文档标题显示为"Project Plan" |
| 同步验证 | **同步验证:**在 N 秒内,验证[条件] | **同步验证:**在 5 秒内,验证[Guest1]看到由[Host]更新的文档 |
| 上传 | [Persona] 将"[filename]"上传至[upload area] | [Host] 将"report.pdf"上传至共享文件拖放区 |
| 拖动 | [Persona] 将"[source]"拖至"[target]" | [Editor] 将"Task A"拖至"Done"列 |
| 按键 | [Persona] 按下[key/shortcut] | [Host] 按下 Escape 关闭共享对话框 |
| 刷新 | [Persona] 刷新页面 | [Guest1] 刷新页面,并验证[Host]的数据仍然存在 |
上传步骤中按每个角色选择测试数据文件
在编写演练中的 Upload 步骤时,检查当前角色的配置文件是否设置了 files。如果已设置:
-
列出该角色可用的测试文件:
[Speaker] has test data files available: 1. valid-deck.pptx — Clean deck, passes all checks 2. corrupted.pptx — Error case, should reject Which file should we use for this upload step? (number, "skip" to use a different file, or "none") -
如果用户选择了文件:
- 对于
path条目:在 Upload 步骤中使用相对于项目根目录的路径 - 对于
url条目:在 Upload 步骤上方的注释中注明该 URL,并在 Upload 步骤中只填写文件名 - 按照惯例为步骤添加角色标签(例如,
[Speaker] Upload "test-fixtures/valid-deck.pptx" to the file dropzone)
- 对于
-
上传步骤完成后,如果存在
acceptance标准(将配置文件级标准与文件级覆盖项进行浅合并),添加带角色标签的 Verify 步骤:标准 生成的 Verify 步骤 uploadAccepted: true[Speaker] Verify no error message or validation error is displayeduploadAccepted: false[Speaker] Verify an error message or validation error is displayedprocessingCompletes: true[Speaker] Verify the processing indicator resolves to a terminal stateresultDownloadable: true[Speaker] Verify a download button or link is availableerrorExpected: true[Speaker] Verify an error message is displayed and the app remains functionalexpectedStatus: "X"[Speaker] Verify the status shows "X"记录前通过检查快照与用户确认每项标准。
-
如果用户选择“skip”或“none”,则像往常一样编写 Upload 步骤,不集成测试数据。
**跨角色验证:**如果一个角色上传文件,而另一个角色预期会看到结果(例如,演讲者上传,规划者审核),则验收标准适用于上传角色的步骤。下游角色视图的验证应作为单独的 Verify 步骤记录,并标记该角色。
便于自动化的指南
多用户工作流旨在转换为 Playwright 多上下文 E2E 测试。遵循以下指南可简化转换过程。
多上下文模式
每个角色映射到一个独立的 Playwright BrowserContext(或在需要完全隔离时使用独立的 Browser 实例)。转换器将创建:
- 1 BrowserContext per persona
- 1 Page per context
- Shared test fixtures for persona credentials
- Helper functions to switch between persona contexts
编写工作流时,请牢记这种映射。每个 [PersonaName] 前缀都会告知转换器该步骤应使用哪个上下文。
定位器描述
描述工作流步骤中的元素时,优先使用能清晰映射到 Playwright 推荐定位策略的描述:
| 定位策略 | 工作流描述 | Playwright 等效写法 |
|---|---|---|
| 按角色 + 名称 | [Admin] 点击“Submit”按钮 | adminPage.getByRole('button', { name: 'Submit' }) |
| 按标签 | [Host] 在电子邮件字段中输入“[email protected]” | hostPage.getByLabel('Email') |
| 按文本 | [Guest1] 点击“Learn more”链接 | guest1Page.getByText('Learn more') |
| 按占位符 | [Guest2] 在搜索框中输入“Search...” | guest2Page.getByPlaceholder('Search...') |
| 按测试 ID | [Admin] 点击删除按钮(data-testid="delete-btn") | adminPage.getByTestId('delete-btn') |
| 按标题 | [Viewer] 将鼠标悬停在信息图标上(title="More information") | viewerPage.getByTitle('More information') |
定位器优先顺序
编写步骤时,按以下顺序优先描述定位器(与 Playwright 的建议一致):
- 基于角色(按钮、链接、标题等)
- 基于标签(表单字段)
- 基于文本(可见文本内容)
- 基于占位符(输入占位符)
- 基于测试 ID(data-testid 属性)
- 基于 CSS/XPath(最后选择,尽可能避免)
无法自动化的步骤
有些步骤无法使用 Playwright 自动化。请用 [MANUAL] 标记:
4. [Guest1] [MANUAL] Verify the invitation email arrives in the inbox
- Check for subject line "You've been invited to [Team Name]"
7. [Admin] [MANUAL] Complete the CAPTCHA challenge
- Workflow continues after CAPTCHA is solved
多用户测试的已知限制
| 限制 | 描述 | 解决方法 |
|---|---|---|
| 真正的并发 | Playwright 上下文在单个测试中按顺序运行 | 使用 Promise.all() 并行执行操作,或接受顺序执行并进行同步验证 |
| WebSocket 状态观察 | 无法直接观察来自其他上下文的 WebSocket 消息 | 通过轮询/重试验证 UI 状态变化 |
| 时序敏感 | 实时同步测试本质上对时序敏感 | 使用较长的超时时间并重试断言(例如,expect(...).toPass({ timeout: 10000 })) |
| 共享数据库状态 | 所有上下文共享同一个数据库 | 在前置条件中明确说明所需的数据状态;每次测试运行使用唯一标识符 |
| 浏览器资源限制 | 每个上下文都会占用内存和 CPU | 每个测试最多限制为 4-5 个同时运行的角色;较大的群组拆分到多个测试中 |
| 每个角色的 OAuth | 每个角色可能需要单独的 OAuth 流程 | 预先配置身份验证令牌,或使用 API 级登录,跳过其他角色的 OAuth UI |
| 电子邮件验证 | 无法自动检查电子邮件收件箱 | 使用测试邮件服务(Mailhog、Ethereal),或在测试环境中跳过验证 |
自动化前置条件
当多用户工作流需要特定设置时,请在前置条件块中记录:
**Preconditions:**
- Admin is logged in as Admin persona (ADMIN_EMAIL / ADMIN_PASSWORD)
- Host is logged in as Host persona (HOST_EMAIL / HOST_PASSWORD)
- Guest1 is logged in as Guest1 persona (GUEST1_EMAIL / GUEST1_PASSWORD)
- A shared workspace named "Test Workspace" exists (created by Admin)
- Host has "Editor" role in "Test Workspace"
- Guest1 has "Viewer" role in "Test Workspace"
- The feature flag "real-time-collaboration" is enabled
这些信息对于 converter 技能至关重要,可帮助其生成适当的 beforeAll 设置块,以创建上下文、登录每个角色并建立所需的数据状态。
多用户 UX 反模式
生成工作流时,请留意这些常见的多用户 UX 反模式。如果在探索过程中发现任何此类问题,请在工作流文档中标记,并编写具体的测试步骤,以验证应用是否能正确处理这些问题。
同步反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| 静默丢失数据 | 用户 B 覆盖用户 A 的更改,却没有任何警告 | [用户 A] 和 [用户 B] 编辑同一字段;验证是否出现冲突解决或合并 UI |
| 读取到过期数据 | 其他用户更新后,用户仍看到旧数据 | [用户 B] 验证在 [用户 A] 更改数据后,数据是否在预期的同步时间内更新 |
| 幻影删除 | 资源从某个用户的视图中消失,却没有说明 | [用户 A] 删除资源;[用户 B] 验证是否显示明确的“已删除”或“未找到”消息(而不是空白屏幕) |
| 没有离线指示 | 用户不知道自己正在使用过期数据 | 断开网络;验证是否显示离线横幅或数据过期警告 |
| 乐观更新后未回滚 | 服务端操作失败后,客户端仍处于无效状态 | [用户 A] 执行一个会在服务端失败的操作;验证 UI 是否回滚到先前状态 |
权限反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| UI 显示禁止执行的操作 | 用户看到了自己无法使用的按钮 | [查看者] 验证编辑/删除按钮不可见(而不只是被禁用) |
| 执行获准操作时出错 | 用户有权限,却遇到错误 | [编辑者] 执行获准的操作;验证是否成功(没有 403/未授权错误) |
| 权限变更延迟生效 | 角色变更要到重新登录后才生效 | [管理员] 更改 [Guest1] 的角色;[Guest1] 验证无需重新登录即可获得新权限 |
| 权限模型不一致 | 同一操作可通过 UI 执行,却被 API 阻止,反之亦然 | [Guest1] 通过 UI 执行操作;验证 API 是否也允许该操作 |
| 权限变更没有审计记录 | 无法追踪是谁更改了谁的访问权限 | [管理员] 更改 [Guest1] 的角色;验证是否创建了审计日志条目 |
协作反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| 没有在线状态指示 | 用户不知道还有谁在查看或编辑 | [Host] 和 [Guest1] 打开同一文档;验证是否显示在线状态头像或“有 N 位用户正在查看”指示 |
| 不共享光标或选区 | 用户无法看到其他人正在何处编辑 | [Host] 将光标放在文档中;[Guest1] 验证是否能看到远程光标 |
| 没有冲突通知 | 并发编辑会被静默合并或丢失 | [Host] 和 [Guest1] 编辑同一段落;验证是否显示冲突通知或合并界面 |
| 锁定没有超时 | 用户锁定资源后离线,导致其他人无法操作 | [Host] 开始编辑;断开 Host 的连接;[Guest1] 验证锁定是否过期或可被覆盖 |
| 没有正在输入指示 | 用户在不知情的情况下互相覆盖输入内容 | [Host] 开始输入;[Guest1] 验证是否显示“Host 正在输入……”指示 |
通知反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| 缺少通知 | 重要事件不会触发通知 | [Host] 执行值得注意的操作;[Guest1] 验证是否在预期时间内收到通知 |
| 通知泛滥 | 每个细微操作都会发送通知 | [Host] 快速执行 10 次操作;[Guest1] 验证通知是否经过合并或限流 |
| 自我通知 | 用户会收到自己操作的通知 | [Host] 执行操作;验证 [Host] 不会收到自己操作的通知 |
| 没有通知偏好设置 | 用户无法控制通知数量 | 验证是否存在通知设置页面,并提供按渠道控制的选项 |
| 通知链接失效 | 点击通知会进入 404 页面或错误状态 | [Admin] 删除资源;[Guest1] 点击关于该资源的通知;验证是否能妥善处理错误 |
多用户验证步骤模板
如果探索过程中检测到反模式,请添加专门的多用户验证工作流:
## Workflow [N]: Multi-User UX Compliance
> Verifies the application follows multi-user UX best practices and avoids
> common collaboration, synchronization, and permission anti-patterns.
**Preconditions:**
- All personas are logged in
- A shared workspace exists with all personas as members
**Steps:**
1. [Host] and [Guest1] Open the same shared document simultaneously
- **Sync Verification:** Within 3 seconds, verify both see presence
indicators showing the other user
2. [Host] Begin typing in the document
- **Sync Verification:** Within 2 seconds, verify [Guest1] sees
[Host]'s cursor or a "Host is typing..." indicator
3. [Admin] Change [Guest1]'s role from "Editor" to "Viewer"
- **Sync Verification:** Within 5 seconds, verify [Guest1]'s edit
controls disappear without requiring re-login
4. [Viewer] Attempt to access the edit page for the shared document
- Verify a clear "permission denied" or redirect occurs (not a 500 error)
5. [Host] Delete the shared document
- **Sync Verification:** Within 5 seconds, verify [Guest1] sees a
"document deleted" message (not a blank screen)
- **Sync Verification:** Within 5 seconds, verify [Viewer] is
redirected or shown a "not found" message
6. [Guest1] Click a stale notification referencing the deleted document
- Verify a graceful "document not found" message appears (not a crash)
处理更新
当用户选择“更新”模式(修改现有工作流)时,请遵循以下规则,以尽量减少干扰,同时确保覆盖内容保持最新。
更新现有工作流的规则
-
保留可用的工作流——如果现有工作流仍然有效(路由存在、组件匹配、角色设定正确、同步时间准确),则保持不变。不要为了风格统一而重写可用的工作流。
-
标记已弃用的工作流——如果某个工作流引用的功能、路由或角色已不存在,不要删除它,而应添加弃用标记:
## Workflow 9: Legacy Shared Calendar
> **DEPRECATED** -- This workflow references the shared calendar feature which
> has been removed. Keeping for reference until confirmed safe to delete.
-
添加新工作流——将新工作流追加到相应部分(核心、功能或边缘情况),并按顺序从最后一个现有工作流之后开始编号。
-
更新角色注册表——如果角色发生变化(添加新角色、重命名角色或删除角色),请更新文档顶部的角色注册表,并标记所有引用已弃用角色的工作流。
-
版本说明——在文件顶部添加版本历史部分:
## Version History
| Date | Action | Details |
|------|--------|---------|
| 2025-02-20 | Updated | Added workflows 26-28 for new real-time chat feature; added "Moderator" persona |
| 2025-02-15 | Updated | Deprecated workflow 9 (calendar removed); updated sync timings in workflows 3, 7, 12 |
| 2025-02-01 | Created | Initial generation: 24 workflows, 6 personas |
- 重新验证现有工作流——探索期间,将现有工作流步骤与当前代码库进行交叉核对。标记所有引用已更改元素、路由或角色的步骤:
3. [Admin] Click the "Invite User" button
- **[CHANGED]** Button label is now "Add Team Member" (updated in v2.5)
- Verify the invitation dialog opens
-
保留工作流编号——绝不要重新编排现有工作流的编号。如果工作流 9 已弃用,而新增了工作流 28,则保留编号空缺。这样可确保对“工作流 9”的外部引用仍然有效。
-
更新同步时间——如果实时基础架构发生变化(例如从轮询迁移到 WebSocket),请更新所有相关同步验证的时间预期。
更新摘要
完成更新操作后,请提供变更摘要:
Multi-user workflow update complete.
Changes:
- Workflows preserved (unchanged): 18
- Workflows updated (steps modified): 4
- Workflows deprecated: 1
- Workflows added (new): 3
- Total workflows: 27 (1 deprecated)
- Personas added: 1 (Moderator)
- Personas deprecated: 0
- Sync timings updated: 6 steps across 3 workflows
Changed workflows:
- Workflow 3: Updated sync timing from 10s to 3s (WebSocket migration)
- Workflow 7: Updated step 4 (new share dialog UI)
- Workflow 12: Updated sync timing from 10s to 3s (WebSocket migration)
- Workflow 15: Updated step 2 ([Admin] button label changed to "Add Team Member")
Deprecated workflows:
- Workflow 9: Legacy Shared Calendar (calendar removed in v3.0)
New workflows:
- Workflow 26: Real-Time Chat Message Delivery
- Workflow 27: Chat Presence Indicators
- Workflow 28: Moderator Content Moderation Flow
New personas:
- Moderator (MODERATOR_EMAIL / MODERATOR_PASSWORD, pre-provisioned)