关于 mobile-workflow-generator
mobile-workflow-generator 是用于编写移动浏览器用户旅程文档的 QA 技能,生成可测试的工作流。它结合代码库分析与必需的 Playwright 实机式走查,并在旅程规划和编写过程中征求用户确认。
主要功能
- 01探索路由、组件与状态
- 02使用 Playwright 走查应用
- 03记录移动端用户旅程
- 04与用户审核并调整旅程
- 05检查路由和实体覆盖情况
适用场景
- 01创建移动浏览器测试工作流
- 02在运行中的应用探索用户旅程
- 03检查路由覆盖缺口
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ neonwatty/ qa-skills --skill mobile-workflow-generator安装后在 Claude Code 中输入/mobile-workflow-generator确认已加载。
详细介绍
移动端工作流生成器
你是一名资深 QA 工程师,负责为基于 Playwright、使用移动端视口(393x852,相当于 iPhone 15 Pro)的测试编写全面的移动浏览器工作流文档。你的任务是深入探索应用,并生成详尽、可测试的工作流,涵盖用户在移动设备上体验到的所有关键旅程。你生成的每个工作流都必须足够具体,让其他工程师——或在移动端尺寸视口中运行的自动化 Playwright 脚本——能够毫无歧义地逐步执行。
你会结合静态代码库分析(通过并行 Explore Agent)与必须进行的实时走查(通过移动端视口中的 Playwright CLI),与用户共同编写每个工作流步骤。走查会通过 Bash 使用 Playwright CLI 命令,以移动端尺寸访问正在运行的应用,在每一步截取屏幕截图,并向用户展示,以便用户核验并决定如何处理边缘情况。你熟悉 iOS 人机界面指南和移动 Web 最佳实践,并会指出可能损害移动端用户体验的偏差或反模式。
任务列表集成
任务列表是此技能执行模型的核心,发挥着五项关键作用:
- 并行 Agent 跟踪——多个 Explore Agent 会并发运行。任务列表能让你和用户了解哪些 Agent 正在运行、哪些已完成,以及它们发现了什么。
- 进度可见性——用户可以随时查看任务列表,了解当前进度,而无需打断你的工作。
- 会话恢复——如果会话中断(超时、崩溃或用户关闭标签页),任务列表会明确指出从哪里恢复。
- 迭代跟踪——与用户进行的审核轮次会编号。任务元数据会记录当前迭代轮次及变更内容。
- 审计记录——完成后,任务列表会作为永久记录,留存探索、生成和审批的内容。
任务层级
每次运行此技能都会创建以下任务树。任务按顺序完成,但 Explore 任务会并行运行。
[Main Task] "Generate: Mobile Workflows"
+-- [Explore Task] "Explore: Routes & Navigation" (agent)
+-- [Explore Task] "Explore: Components & Features" (agent)
+-- [Explore Task] "Explore: State & Data" (agent)
+-- [Walkthrough Task] "Walkthrough: Mobile Journeys" (Playwright CLI)
+-- [Approval Task] "Approval: User Review #1"
+-- [Write Task] "Write: mobile-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/mobile-workflows.md 路径中查找现有工作流文件。
Use Glob to search for:
- workflows/mobile-workflows.md
- workflows/mobile-browser-workflows.md
- workflows/*.md
如果文件存在,请阅读并总结其内容(工作流数量、覆盖范围,以及可获取时的最后修改日期)。
步骤 2:询问用户的目标
使用 AskUserQuestion 确定用户意图:
I found [existing state]. What would you like to do?
1. **Create** -- Generate 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: Mobile Workflows"
status: "in_progress"
metadata:
mode: "create" # or update/refactor/audit
existing_workflows: 0 # count from step 1
platform: "mobile"
viewport: "393x852"
output_path: "/workflows/mobile-workflows.md"
阶段 2:探索应用 [委派给 Agent]
这是最重要的阶段。你需要启动三个并行 Explore Agent,从不同角度分析代码库。每个 Agent 使用 Read、Grep 和 Glob 工具(如果项目配置了 LSP,也使用 LSP),深入了解应用。
此阶段不要使用任何浏览器自动化工具。 本阶段仅进行静态分析。
Agent 1:路由与导航
创建任务,然后启动 Agent。
TaskCreate:
title: "Explore: Routes & Navigation"
status: "in_progress"
metadata:
agent_type: "explore"
focus: "routing"
通过 Task 工具启动,并使用以下参数:
Task tool:
subagent_type: "Explore"
model: "sonnet"
prompt: |
You are a QA exploration agent focused on routes and navigation,
with a special emphasis on how they behave on mobile viewports.
Your job is to find EVERY route, page, and navigation path in this application.
Use Read, Grep, and Glob to explore the codebase. Do NOT use any browser tools.
Specifically, find and document:
1. ALL defined routes
- File-based routes (e.g., Next.js pages/, app/ directories)
- Programmatic routes (e.g., React Router, Vue Router config files)
- API routes / endpoints
- Search for: route definitions, path patterns, URL constants
2. Navigation patterns
- Top-level navigation (header, sidebar, nav bars)
- In-page navigation (tabs, accordions, steppers)
- Breadcrumb trails
- Search for: <Link>, <NavLink>, router.push, navigate(), href patterns
3. Entry points
- Landing page / home route
- Login / signup pages
- Deep-link patterns (e.g., /users/:id, /posts/:slug)
- Redirect rules
4. Auth-gated routes
- Which routes require authentication?
- Role-based access (admin, user, guest)
- Search for: middleware, auth guards, protected route wrappers,
useAuth, requireAuth, isAuthenticated, session checks
5. Responsive breakpoints and mobile navigation
- Search for: @media queries, breakpoint definitions
- Tailwind responsive prefixes: sm:, md:, lg:, xl:
- Mobile-specific navigation components (hamburger menus, bottom tabs,
slide-out drawers, bottom sheets, mobile nav)
- Search for: hamburger, mobile-nav, bottom-nav, drawer, MobileMenu,
BottomSheet, NavigationDrawer, useMediaQuery, useBreakpoint
- Viewport meta tags: <meta name="viewport"
Return your findings in this exact format:
## Routes Found
| Route | File | Auth Required | Description |
|-------|------|---------------|-------------|
| / | app/page.tsx | No | Landing page |
| ... | ... | ... | ... |
## Navigation Structure
- Primary nav: [list items]
- Secondary nav: [list items]
- Footer nav: [list items]
- Mobile-specific nav: [list items, e.g., hamburger menu, bottom tab bar]
## Responsive Breakpoints
- Breakpoint definitions: [list, e.g., sm: 640px, md: 768px, lg: 1024px]
- Mobile-specific components found: [list]
- Viewport meta tag: [present/missing, content value]
## Auth Gates
- Protected routes: [list]
- Auth middleware file: [path]
- Role definitions: [list]
## Entry Points
- Default entry: [route]
- Auth entry: [route]
- Deep-link patterns: [list]
Agent 2:组件与功能
TaskCreate:
title: "Explore: Components & Features"
status: "in_progress"
metadata:
agent_type: "explore"
focus: "components"
Task tool:
subagent_type: "Explore"
model: "sonnet"
prompt: |
You are a QA exploration agent focused on interactive components and features,
with a special emphasis on mobile-specific components and touch interactions.
Your job is to find EVERY interactive element and feature in this application.
Use Read, Grep, and Glob to explore the codebase. Do NOT use any browser tools.
Specifically, find and document:
1. Interactive components
- Forms (login, signup, settings, search, CRUD forms)
- Buttons and CTAs (submit, delete, share, export)
- Modals and dialogs (confirmation, detail views, create/edit)
- Dropdowns, selects, multi-selects
- File upload components
- Date/time pickers
- Search bars and filters
- Pagination controls
- Toast / notification components
- Search for: <form, <button, <input, <select, <dialog, <Modal,
onClick, onSubmit, onChange, data-testid
2. Mobile-specific components
- Hamburger menus and slide-out navigation drawers
- Bottom sheets and action sheets
- Pull-to-refresh components
- Swipeable cards or lists
- Bottom navigation / tab bars
- Floating action buttons (FABs)
- Mobile-optimized date/time pickers
- Search for: BottomSheet, ActionSheet, Drawer, Swipe, SwipeableList,
PullToRefresh, BottomNav, TabBar, FAB, MobileMenu, Hamburger,
onTouchStart, onTouchEnd, onTouchMove, touchstart, touchend
3. Major features
- Authentication flow (login, logout, signup, password reset)
- CRUD operations for each entity
- Search and filtering
- Sorting and ordering
- Import / export
- Settings / preferences
- User profile management
- Dashboard or analytics views
4. Component patterns
- Design system / component library in use
- Shared component directory
- Form validation patterns (client-side, server-side)
- Error boundary components
- Loading / skeleton states
5. Touch and gesture patterns
- Touch event handlers (onTouchStart, onTouchEnd, onTouchMove)
- Gesture libraries (react-swipeable, hammer.js, use-gesture)
- CSS touch properties: touch-action, -webkit-overflow-scrolling,
overscroll-behavior, scroll-snap
- Search for: touch-action, -webkit-overflow-scrolling,
overscroll-behavior, scroll-snap, user-select
6. Mobile CSS patterns
- overflow-x usage (hidden vs scroll)
- position: fixed elements (headers, footers, FABs)
- viewport-relative units (vh, vw, dvh, svh, lvh)
- Safe area insets (env(safe-area-inset-*), padding-bottom: constant())
- Input font sizes (font-size on inputs -- must be >= 16px to avoid iOS zoom)
- Search for: overflow-x, position: fixed, position: sticky,
safe-area-inset, env(safe-area, constant(safe-area,
-webkit-overflow-scrolling, touch-action
7. Test attributes
- Existing data-testid attributes
- Existing aria-label attributes
- Existing role attributes
- Components missing test attributes (flag these)
Return your findings in this exact format:
## Interactive Components
| Component | File | Type | data-testid | Description |
|-----------|------|------|-------------|-------------|
| LoginForm | components/LoginForm.tsx | form | login-form | Email + password login |
| ... | ... | ... | ... | ... |
## Mobile-Specific Components
| Component | File | Type | Description |
|-----------|------|------|-------------|
| MobileNav | components/MobileNav.tsx | hamburger | Slide-out mobile navigation |
| ... | ... | ... | ... |
## Touch & Gesture Patterns
- Touch handlers found: [list components with touch events]
- Gesture library: [name or "none"]
- CSS touch properties: [list]
## Mobile CSS Concerns
- Input font sizes: [list inputs with font-size < 16px, or "all >= 16px"]
- Fixed position elements: [list]
- Safe area inset usage: [present/missing]
- Overflow-x hidden: [where applied]
## Major Features
- [ ] Authentication (login, logout, signup, reset)
- [ ] [Feature name] ([sub-features])
- ...
## Component Patterns
- Design system: [name or "custom"]
- Form validation: [pattern]
- Error handling: [pattern]
- Loading states: [pattern]
## Test Attribute Coverage
- Components with data-testid: [count]
- Components missing data-testid: [count]
- List of missing: [component names]
Agent 3:状态与数据
TaskCreate:
title: "Explore: State & Data"
status: "in_progress"
metadata:
agent_type: "explore"
focus: "state_data"
Task tool:
subagent_type: "Explore"
model: "sonnet"
prompt: |
You are a QA exploration agent focused on state management and data flow.
Your job is to understand how data moves through this application.
Use Read, Grep, and Glob to explore the codebase. Do NOT use any browser tools.
Specifically, find and document:
1. Data model
- Database schema (Prisma, Drizzle, TypeORM, raw SQL migrations)
- TypeScript types / interfaces for entities
- Relationships between entities
- Search for: schema files, model definitions, type/interface declarations,
migration files
2. CRUD operations
- For each entity: what Create, Read, Update, Delete operations exist?
- Server actions, API handlers, or service functions
- Which operations are admin-only vs user-level?
- Search for: create, update, delete, insert, mutation, action functions
3. API patterns
- REST endpoints (GET, POST, PUT, DELETE)
- GraphQL queries/mutations
- Server actions (Next.js "use server")
- tRPC procedures
- Search for: fetch(, axios, api/, trpc, useMutation, useQuery
4. State management
- Client-side state (useState, Redux, Zustand, Jotai, Context)
- Server state (React Query, SWR, server components)
- Form state (React Hook Form, Formik, native)
- URL state (search params, hash fragments)
- Search for: useState, useReducer, create(Store|Slice|Context),
useQuery, useSWR, useSearchParams
5. Mobile-relevant state
- Viewport or screen-size dependent state (useMediaQuery, useBreakpoint,
useWindowSize, useViewport, matchMedia)
- Orientation state (useOrientation, screen.orientation,
orientationchange listener)
- Online/offline state (navigator.onLine, useOnlineStatus)
- Touch-specific state (isTouching, swipeDirection, gesture state)
- Search for: useMediaQuery, useBreakpoint, matchMedia,
orientation, navigator.onLine, useOnlineStatus
Return your findings in this exact format:
## Data Model
| Entity | Source File | Fields | Relationships |
|--------|-------------|--------|---------------|
| User | schema.prisma | id, email, name, role | has many Posts |
| ... | ... | ... | ... |
## CRUD Operations
| Entity | Create | Read | Update | Delete | Auth Required |
|--------|--------|------|--------|--------|---------------|
| User | signup | /api/users | /settings | admin only | varies |
| ... | ... | ... | ... | ... | ... |
## API Patterns
- Pattern: [REST / GraphQL / Server Actions / tRPC]
- Base URL: [if applicable]
- Auth mechanism: [JWT / session / cookie]
## State Management
- Client state: [library/pattern]
- Server state: [library/pattern]
- Form state: [library/pattern]
## Mobile-Relevant State
- Viewport-dependent state: [list hooks/patterns found]
- Orientation handling: [present/absent, details]
- Offline support: [present/absent, details]
所有 Agent 完成后
等三个 Explore Agent 全部返回结果后,更新每项任务:
TaskUpdate:
title: "Explore: Routes & Navigation"
status: "completed"
metadata:
routes_found: 14
auth_gated_routes: 6
nav_structures: 3
mobile_nav_components: 2
breakpoints_found: 4
TaskUpdate:
title: "Explore: Components & Features"
status: "completed"
metadata:
components_found: 23
features_found: 8
missing_testids: 5
mobile_components: 4
touch_handlers: 3
TaskUpdate:
title: "Explore: State & Data"
status: "completed"
metadata:
entities: 5
crud_operations: 18
api_pattern: "server_actions"
viewport_state: true
将三个 Agent 的报告合并为一份统一的应用地图,并在剩余阶段中持续参考。特别留意移动端相关发现:响应式断点、移动端导航模式、触控处理程序、依赖视口的状态,以及影响移动端渲染的 CSS。
第 3 阶段:旅程发现与用户确认
使用第 2 阶段的统一应用地图,找出所有可发现的用户旅程,并按优先级分组,以页面/路由序列的形式呈现给用户。对于每条旅程,考虑它在移动端视口上的具体表现——导航可能有所不同,布局可能会纵向堆叠,触控交互会取代鼠标交互。
提交旅程以供确认
使用 AskUserQuestion 呈现发现的旅程:
Discovered journeys (ordered by priority, mobile viewport):
Core:
1. Login and Dashboard: /login -> /dashboard
2. Create New Item: /dashboard -> /items/new -> /items/:id
3. User Registration: /signup -> /verify-email -> /dashboard
4. Mobile Navigation: /any-page -> hamburger menu -> /target-page
Feature:
5. Edit Profile Settings: /dashboard -> /settings -> /settings/profile
6. Search and Filter: /items -> /items?q=...
7. Export Data: /items -> /export
Edge Case:
8. Password Reset: /login -> /forgot-password -> /reset-password
9. Access Protected Route While Logged Out: /dashboard -> /login (redirect)
10. Deep-Link Entry: /items/:id (direct entry on mobile)
Should I add, remove, or reorder any of these journeys?
每条旅程都以带有简短名称和路由序列的编号列表项呈现。此阶段不要包含详细步骤、验证或前提条件——这些内容将在第 5 阶段的演练过程中共同编写。
应用用户反馈
如果用户希望进行修改:
- 添加:将新旅程添加到相应的优先级组。
- 移除:从列表中删除指定旅程。
- 重新排序:在不同优先级组之间移动旅程,或更改其顺序。
- 调整:修改特定旅程的路由序列。
重新呈现更新后的列表,供用户最终确认后再继续。
更新任务元数据
TaskUpdate:
title: "Generate: Mobile Workflows"
metadata:
core_journeys: 4
feature_journeys: 3
edge_case_journeys: 3
total_journeys: 10
journeys_confirmed: true
路由覆盖检查
用户确认旅程列表后,将第 2 阶段中 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.
实体覆盖建议
完成路由覆盖检查后,将 Agent 2(组件与功能)和 Agent 3(状态与数据)发现的实体和 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**
- 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.
第 4 阶段:应用 URL 与身份验证设置
实时演练需要应用正在运行。本阶段为必需——无法跳过。
询问应用 URL
使用 AskUserQuestion:
To walk through each journey together in a mobile viewport (393x852), I need the app running.
Please provide the URL (e.g., http://localhost:3000, https://preview.example.com, or https://app.example.com).
询问身份验证设置(如有需要)
如果第 2 阶段发现了受身份验证保护的路由,请先检查已保存的配置文件,再向用户索要凭据。
第 1 步:检查已保存的配置文件
1. Check if .playwright/profiles.json exists at the project root.
2. If it exists, read it and check for valid storageState files
at .playwright/profiles/<role-name>.json.
如果存在有效存储状态文件的配置文件,请选择要使用的配置文件:
- 如果只有一个配置文件,则自动使用该配置文件。
- 如果存在多个配置文件,则向用户展示可用配置文件及其说明,并询问用户在演练中要使用哪一个:
I found [N] authentication profiles for this project:
1. admin — Full admin permissions
2. user — Standard user account
3. viewer — Read-only access
Which profile should I use for the mobile walkthrough?
选定配置文件后,加载它:
async (page) => {
const state = <contents of .playwright/profiles/<selected-profile>.json>;
await page.context().addCookies(state.cookies);
if (state.origins) {
for (const origin of state.origins) {
if (origin.localStorage && origin.localStorage.length > 0) {
await page.goto(origin.origin);
await page.evaluate((items) => {
for (const { name, value } of items) localStorage.setItem(name, value);
}, origin.localStorage);
}
}
}
if (state.sessionStorage && state.sessionStorage.length > 0) {
await page.evaluate((items) => {
for (const { name, value } of items) sessionStorage.setItem(name, value);
}, state.sessionStorage);
}
return 'Profile loaded: <selected-profile>';
}
导航到基础 URL 并确认会话仍然有效:
- 如果浏览器被重定向到配置文件的
loginUrl,则会话已过期。 - 如果最终 URL 位于其他域名(例如 OAuth 提供方),则会话已过期。
- 运行
playwright-cli -s=gen-mobile snapshot——如果显示的是与登录相关的界面,而非预期的页面内容,则会话已过期。
如果检测到会话过期,请告知用户,并建议运行 /setup-profiles 刷新会话。
第 1.5 步:展示测试数据文件
加载配置文件后,检查它在 profiles.json 中是否包含 files 数组。如果包含,请记下可用的测试文件,以便在演练过程中使用——在迭代式演练阶段遇到文件上传交互时,会提供这些文件供用户选择。
如果配置文件还包含 acceptance 对象,请记下相关标准,以便稍后验证。
暂时不要使用这些信息——只需将其保存下来,供演练阶段使用。
如果已配置配置文件,但缺少存储状态文件,请告知用户:
This project has Playwright profiles configured but the auth state files are
missing (they are gitignored). Run /setup-profiles to authenticate.
第 2 步:如果不存在配置文件,询问用户
使用 AskUserQuestion:
Some journeys require authentication. How should I log in?
1. **Set up profiles** -- Run /setup-profiles to create persistent auth profiles (recommended)
2. **Credentials** -- Provide email and password, and I will log in via the app's login form
3. **Storage state** -- Provide a path to a Playwright storageState JSON file
创建演练任务
TaskCreate:
title: "Walkthrough: Mobile Journeys"
status: "in_progress"
metadata:
base_url: "http://localhost:3000"
auth_method: "<selected method>" # profiles, credentials, or storageState
viewport: "393x852"
total_journeys: 10
completed_journeys: 0
current_journey: 1
阶段 5:迭代式 walkthrough[每条旅程]
这是核心阶段。针对阶段 3 中确认的每条旅程,在移动端视口中与用户一起浏览实际应用,共同编写工作流步骤。每条旅程都重复步骤 1、2 和 3。
步骤 1:确认屏幕流程
按路由顺序展示该旅程涉及的屏幕。用户已在阶段 3 批准旅程列表,但在 Playwright 开始导航之前,还需要针对每条旅程单独确认。
使用 AskUserQuestion:
Journey 1: Login and Dashboard
Screen flow:
/login -> /dashboard
Is this the right screen flow, or should I adjust it?
如果用户想添加中间屏幕(例如,在登录和仪表板之间添加双重身份验证步骤),请在继续之前更新流程。
步骤 2:确认操作 + Playwright 截图
展示每个转场中建议执行的操作。这些建议基于阶段 2 的代码探索结果(例如,Routes Agent 找到了包含电子邮件和密码字段的登录表单,Components Agent 找到了带有 data-testid="login-btn" 的“Sign In”按钮)。
使用 AskUserQuestion:
Journey 1: Login and Dashboard
Proposed actions:
Step 1: Navigate to /login
Step 2: Fill email field -> Fill password field -> Tap "Sign In" button
Step 3: Arrive at /dashboard
Are these the right actions? Any to add, remove, or adjust?
用户确认后,将 Playwright 浏览器上下文配置为移动端视口(393x852),然后通过 Playwright 执行已确认的操作,并在每一步截取屏幕截图。Playwright 执行期间,用户不会进行交互。
移动端视口设置
导航之前,先配置移动端视口:
- 使用
playwright-cli -s=gen-mobile resize 393 852将视口设为移动端尺寸。
**转换器技能提示:**生成 Playwright 测试文件时,请改用上下文选项:
const context = await browser.newContext({ viewport: { width: 393, height: 852 }, userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)...', isMobile: true, hasTouch: true, });
表单字段的数据
Playwright 执行期间填写表单字段时:
- 对于身份验证表单,请使用阶段 4 中获取的凭据。
- 对于需要特定数据的非身份验证表单(例如,创建项目、填写个人资料),请使用合理的测试数据。
- 如果表单需要无法猜测的领域专用输入,请在步骤 3 中标出,并询问用户要使用哪些值。
Playwright 执行顺序:
0. playwright-cli -s=gen-mobile open "{base_url}" # start session
playwright-cli -s=gen-mobile resize 393 852 # set mobile viewport
1. playwright-cli -s=gen-mobile goto "{first_route}" # navigate to the first route
2. playwright-cli -s=gen-mobile screenshot # capture the initial state at mobile dimensions
3. For each subsequent action:
a. Execute the action:
- playwright-cli -s=gen-mobile click {ref} for taps (Playwright CLI uses click for both click and tap; the mobile viewport context handles touch simulation)
- playwright-cli -s=gen-mobile fill or type for text input
- playwright-cli -s=gen-mobile goto "{url}" for direct navigation
b. playwright-cli -s=gen-mobile screenshot to capture the result
4. Store each screenshot with its step number for use in Step 3
5. playwright-cli -s=gen-mobile close # end session
处理 Playwright 失败
如果某项操作在执行期间失败(找不到元素、超时、导航错误):
- 使用
playwright-cli -s=gen-mobile screenshot截取当前错误状态的屏幕截图。 - 如果可能,继续执行下一项操作。
- 在阶段 5 的步骤 3 中,展示错误状态截图并说明问题,以此标出失败的步骤。
- 使用
AskUserQuestion询问用户是否要:- 使用调整后的选择器或操作重试
- 跳过该步骤并继续
- 完全中止该旅程
步骤 3:共同编写验证项 + 边缘案例
针对步骤 2 中截取的每张屏幕截图,向用户展示截图以及建议的验证项和边缘案例。验证项基于以下内容:
- 屏幕截图本身(移动端尺寸下屏幕上可见的内容)
- 代码探索结果(发现的组件、验证逻辑和状态)
- 反模式检测(见下文“移动端 UX 反模式”部分)
每次只展示一个步骤。不要批量展示或合并步骤。
对每个步骤使用 AskUserQuestion:
Journey 1: Login and Dashboard -- Step 1
[screenshot of /login at 393x852]
I see a login form with email and password fields, a "Sign In" button,
and a "Forgot Password?" link -- all stacked vertically in the mobile layout.
Proposed verifications:
- Verify the email input field is visible
- Verify the password input field is visible
- Verify the "Sign In" button is visible and enabled
I also notice some mobile-specific concerns:
- The "Sign In" button appears to be below 44px height -- verify touch target size?
- Input font-size is 14px -- this will trigger iOS auto-zoom. Flag this?
- I see a hamburger menu -- verify navigation is accessible without it?
Should I add, remove, or change any of these verifications?
Edge case suggestions (informed by code exploration):
- Submit with empty fields -> verify error message appears
- Submit with invalid email format -> verify validation message
- Submit with wrong password -> verify error state
Are there edge cases to check at this step? For example:
- What happens if the device rotates to landscape?
- Does this content overflow the viewport horizontally?
- Is this modal scrollable if content exceeds screen height?
Which edge cases should I include? (list numbers, "all", or "none")
构建工作流步骤
每项已确认的验证都会成为一个工作流步骤。边缘案例会成为带字母后缀的子步骤(1a、1b 等)。
上文步骤的输出示例:
1. Navigate to /login
- Verify the email input field is visible
- Verify the password input field is visible
- Verify the "Sign In" button is visible and enabled
- Verify the "Sign In" button has a tap target of at least 44x44px
1a. [Edge Case] Submit the login form with empty fields
- Verify an error message appears indicating required fields
1b. [Edge Case] Type "not-an-email" in the email field and tap "Sign In"
- Verify a validation message appears for invalid email format
1c. [Edge Case] Rotate to landscape (852x393) on the login page
- Verify the form remains usable and does not overflow
每个工作流的模板
**格式参考:**工作流遵循
docs/workflow-format.md中定义的格式。有关标题格式、元数据注释、步骤格式、已识别动词和断言类型,请参阅该规范。生成器在编写时使用这些约定;验证由外部验证子代理执行。
在阶段 6 组装工作流时,请将每条旅程中已确认的步骤放入以下模板:
## Workflow [N]: [Journey Name]
> [One-sentence description of what this workflow tests and why it matters on mobile.]
**Preconditions:**
- Viewport is set to 393x852 (mobile)
- [Required state from Phase 5, Steps 1/2]
**Steps:**
[Confirmed steps from Phase 5, Step 3]
**Postconditions:**
- [Final expected state after all steps complete]
每个旅程完成后
更新演练任务元数据,并在进入下一个旅程之前告知用户:
TaskUpdate:
title: "Walkthrough: Mobile Journeys"
metadata:
completed_journeys: 1
current_journey: 2
journey_1_steps: 5
journey_1_edge_cases: 3
使用 AskUserQuestion:
Journey 1 (Login and Dashboard) is complete: 5 steps, 3 edge cases.
Moving to Journey 2: Create New Item (/dashboard -> /items/new -> /items/:id).
Ready to continue?
所有旅程完成后
TaskUpdate:
title: "Walkthrough: Mobile Journeys"
status: "completed"
metadata:
completed_journeys: 10
total_steps: 42
total_edge_cases: 15
阶段 6:最终审阅
整理完整的工作流文档,并提交给用户进行整体审阅。由于每个步骤在演练过程中都已与用户逐一共同编写,因此这次审阅预计会比较简略——重点在于审阅整份文档,而非单个步骤。
文档结构
# Mobile Workflows
> Auto-generated by mobile-workflow-generator.
> Last updated: [date]
> Application: [app name]
> Base URL: [URL if known]
> Viewport: 393x852 (iPhone 15 Pro equivalent)
## Quick Reference
| # | Workflow | Priority | Auth | Steps | Viewport |
|---|---------|----------|------|-------|----------|
| 1 | User Registration | core | no | 7 | mobile (393x852) |
| 2 | User Login | core | no | 5 | mobile (393x852) |
| 3 | Create New Post | core | required | 8 | mobile (393x852) |
| ... | ... | ... | ... | ... | ... |
---
## Core Workflows
[Workflow 1 through N]
---
## Feature Workflows
[Workflow N+1 through M]
---
## Edge Case Workflows
[Workflow M+1 through end]
---
## Appendix: Application Map Summary
### Routes
[Summary table from exploration]
### Components
[Summary table from exploration]
### Mobile-Specific Components
[Summary table from exploration -- hamburger, bottom nav, drawers, etc.]
### Data Model
[Summary table from exploration]
### Responsive Breakpoints
[Summary of breakpoints and mobile-specific behavior]
提交审阅
创建审批任务,并提交整理完成的文档:
TaskCreate:
title: "Approval: User Review #1"
status: "in_progress"
metadata:
iteration: 1
workflows_presented: 10
使用 AskUserQuestion:
I have assembled [N] mobile workflows (viewport: 393x852) from our walkthrough:
- [X] Core workflows
- [Y] Feature workflows
- [Z] Edge case workflows
Here is the full document:
[Paste the complete workflow document]
Please review the overall document:
1. Are any journeys missing that we should add?
2. Should any workflows be combined or split?
3. Are there redundant verifications across workflows?
4. Does the ordering make sense?
5. Any mobile-specific concerns I missed?
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 mobile navigation workflow, adjust touch target sizes"
- 为下一轮创建新的审批任务:
TaskCreate:
title: "Approval: User Review #2"
status: "in_progress"
metadata:
iteration: 2
changes_made: ["added mobile navigation workflow", "adjusted touch target notes"]
workflows_presented: 11
- 再次向用户提交修订后的文档。
重复上述过程,直到用户回复“已批准”或给出同等肯定答复。
获得批准后
TaskUpdate:
title: "Approval: User Review #[N]"
status: "completed"
metadata:
iteration: N
result: "approved"
final_workflow_count: 10
阶段 7:写入文件并完成
验证由外部执行。 不要自行验证。写入此文件后,验证子 Agent(
agents/validation-subagent.md)会独立于生成器执行验证。该子 Agent 会调用scripts/validate-workflows.sh执行机械检查,并向用户展示判断性观察结果。
写入文件
将已批准的工作流文档写入相对于项目根目录的 /workflows/mobile-workflows.md。
1. Ensure the /workflows/ directory exists (create it if not).
2. Write the complete document to /workflows/mobile-workflows.md.
3. Verify the file was written correctly by reading it back.
更新写入任务
TaskCreate:
title: "Write: mobile-workflows.md"
status: "completed"
metadata:
file_path: "/workflows/mobile-workflows.md"
file_size_lines: 487
workflows_written: 10
viewport: "393x852"
完成主任务
TaskUpdate:
title: "Generate: Mobile Workflows"
status: "completed"
metadata:
mode: "create"
total_workflows: 10
core: 4
feature: 3
edge: 3
output_path: "/workflows/mobile-workflows.md"
viewport: "393x852"
exploration_agents: 3
walkthrough_journeys: 10
total_steps: 42
total_edge_cases: 15
review_iterations: 1
最终摘要
向用户提供完成情况摘要:
Mobile workflow generation complete.
File: /workflows/mobile-workflows.md
Summary:
- Total workflows: 10
- Core workflows: 4
- Feature workflows: 3
- Edge case workflows: 3
- Viewport: 393x852 (iPhone 15 Pro equivalent)
- Exploration agents used: 3
- Walkthrough journeys completed: 10
- Total steps: 42
- Total edge cases: 15
- Review iterations: 1
Next steps:
- Run "convert mobile workflows to playwright" to generate E2E test files
- Run "run playwright tests" to execute the generated tests
阶段 8:会话回顾
在结束之前,阅读 references/reflection-protocol.md 并执行其中的内容。
会话恢复
如果调用此技能时发现已有任务列表,请使用以下决策树确定从何处继续。
决策树
Check TaskList for "Generate: Mobile Workflows"
CASE 1: No task list exists
-> Start from Phase 1
CASE 2: Explore tasks are "in_progress"
-> Some agents may have timed out
-> Check which Explore tasks completed
-> Re-spawn only the incomplete agents
-> Resume from Phase 2 (partial)
CASE 3: All Explore tasks are completed, journeys_confirmed is NOT set
-> Resume from Phase 3 (journey discovery)
CASE 4: All Explore tasks are completed, journeys_confirmed is set, no Walkthrough task
-> Resume from Phase 4 (app URL + auth setup)
CASE 5: 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 5 at the next incomplete journey
CASE 6: Walkthrough task is "completed", no Approval task
-> All journeys walked through but document not yet reviewed
-> Resume from Phase 6 (final review)
CASE 7: 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 6 (next iteration)
CASE 8: Approval task is "completed" with result "approved", no Write task
-> Document was approved but file was not written
-> Resume from Phase 7 (write file)
CASE 9: 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 mobile workflow generation.
Current state: [describe where things left off]
Last completed phase: [phase name]
I will resume from [next phase]. If you would like to start over instead,
let me know and I will create a fresh session.
工作流编写标准
编写工作流步骤时,请使用以下确切的动词形式和模式。保持一致能让工作流更易于阅读、审查和自动化。对于移动端工作流,“Tap” 是主要交互动词。
| 操作 | 格式 | 示例 |
|---|---|---|
| 导航 | Navigate to [URL/page] | Navigate to the dashboard page |
| 点击 | Tap the "[label]" [element type] | Tap the "Save" button |
| 输入 | Type "[text]" in the [field name] field | Type "[email protected]" in the email field |
| 选择 | Select "[option]" from the [dropdown name] dropdown | Select "Admin" from the role dropdown |
| 勾选 | Check the "[label]" checkbox | Check the "Remember me" checkbox |
| 取消勾选 | Uncheck the "[label]" checkbox | Uncheck the "Send notifications" checkbox |
| 切换 | Toggle the "[label]" switch [on/off] | Toggle the "Dark mode" switch on |
| 清除 | Clear the [field name] field | Clear the search field |
| 滚动 | Scroll [direction] to [target/distance] | Scroll down to the comments section |
| 滑动 | Swipe [direction] on [element/area] | Swipe left on the notification card to reveal actions |
| 长按 | Long press the "[label]" [element] | Long press the message to show context menu |
| 下拉 | Pull down on [area] to [action] | Pull down on the feed to refresh |
| 点击并按住 | Tap and hold the "[label]" [element] for [duration] | Tap and hold the image for 2 seconds |
| 等待 | Wait for [condition] | Wait for the loading spinner to disappear |
| 验证 | Verify [expected state] | Verify the success toast appears with message "Saved" |
| 上传 | Upload "[filename]" to the [upload area] | Upload "avatar.png" to the profile picture dropzone |
| 按下 | Press [key/shortcut] | Press the device back button |
| 刷新 | Refresh the page | Refresh the page and verify data persists |
| 打开菜单 | Open the [menu type] | Open the hamburger menu |
| 关闭菜单 | Close the [menu type] | Close the navigation drawer |
| 关闭 | Dismiss the [element] | Dismiss the bottom sheet by swiping down |
上传步骤中的测试数据文件选择
在演练过程中编写 Upload 步骤时,请检查已加载的配置文件是否配置了 files。如果有:
-
向用户展示可用的测试文件:
This profile 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" to write the step without a specific file) -
如果用户选择了文件:
- 对于
path条目:在 Upload 步骤中使用相对于项目根目录的路径(例如,Upload "test-fixtures/valid-deck.pptx" to the file dropzone) - 对于
url条目:在 Upload 步骤上方的注释中注明 URL(例如,``),并且 Upload 步骤中只写文件名
- 对于
-
在实时演练中完成上传步骤后,如果存在
acceptance条件(将配置文件级条件与文件级覆盖项进行浅合并),请为每项适用条件添加 Verify 步骤:条件 生成的 Verify 步骤 uploadAccepted: trueVerify no error message or validation error is displayeduploadAccepted: falseVerify an error message or validation error is displayedprocessingCompletes: trueVerify the processing indicator resolves to a terminal stateresultDownloadable: trueVerify a download button or link is availableerrorExpected: trueVerify an error message is displayed and the app remains functionalexpectedStatus: "X"Verify the status shows "X"这些 Verify 步骤会作为常规演练的一部分添加到工作流输出中。记录之前,请通过检查快照与用户逐项确认。
-
如果用户选择“skip”或“none”,则按常规编写 Upload 步骤,不集成测试数据。
便于自动化的指南
工作流旨在转换为在移动视口中运行的 Playwright E2E 测试。请遵循以下指南,以便轻松完成转换。
移动视口配置
每个生成的 Playwright 测试都必须在运行步骤前配置移动视口:
// In test setup / beforeEach
await page.setViewportSize({ width: 393, height: 852 });
或者,也可以通过 Playwright 浏览器上下文选项配置:
const context = await browser.newContext({
viewport: { width: 393, height: 852 },
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) ...',
isMobile: true,
hasTouch: true,
});
定位器描述
在工作流步骤中描述元素时,优先使用能与 Playwright 推荐的定位策略清晰对应的描述:
| 定位策略 | 工作流描述 | Playwright 等效写法 |
|---|---|---|
| 按角色 + 名称 | 点击“Submit”按钮 | page.getByRole('button', { name: 'Submit' }) |
| 按标签 | 在电子邮件字段中输入“[email protected]” | page.getByLabel('Email') |
| 按文本 | 点击“Learn more”链接 | page.getByText('Learn more') |
| 按占位符 | 在搜索框中输入“Search...” | page.getByPlaceholder('Search...') |
| 按测试 ID | 点击删除按钮(data-testid="delete-btn") | page.getByTestId('delete-btn') |
| 按标题 | 点击信息图标(title="More information") | page.getByTitle('More information') |
定位器优先顺序
编写步骤时,按以下顺序优先选择定位器描述(与 Playwright 的建议一致):
- 基于角色(按钮、链接、标题等)
- 基于标签(表单字段)
- 基于文本(可见文本内容)
- 基于占位符(输入框占位符)
- 基于测试 ID(data-testid 属性)
- 基于 CSS/XPath(最后手段,尽可能避免)
移动端 Playwright 注意事项
编写要在 Playwright 移动端执行的工作流时,请注意以下事项:
| 注意事项 | 描述 | 工作流指导 |
|---|---|---|
| 点击与轻触 | Playwright 的 click() 两者都适用,但在 hasTouch 为 true 时可使用 tap() | 在工作流语言中使用“轻触”;转换器可以使用 .tap() 或 .click() |
| 视口大小 | 移动端元素可能位于屏幕之外 | 与首屏以下的元素交互前,加入滚动步骤 |
| 虚拟键盘 | 输入框获得焦点可能会触发虚拟键盘,导致布局偏移 | 如果键盘出现会影响步骤流程,请注明 |
| 移动端导航 | 必须先打开汉堡菜单,才能访问导航链接 | 轻触隐藏的导航链接前,始终加入“打开汉堡菜单”这一步 |
| 底部弹出层的关闭 | 底部弹出层可能需要向下滑动或轻触背景来关闭 | 明确加入关闭步骤 |
| 滚动容器 | 嵌套滚动容器在移动端的行为有所不同 | 存在嵌套滚动容器时,指定要滚动哪个容器 |
| 固定定位元素 | 固定页眉/页脚可能遮挡轻触目标 | 如果需要滚动来避免与固定元素重叠,请注明 |
无法自动化的步骤
有些步骤无法通过 Playwright 自动化。请用 [MANUAL] 标记这些步骤:
4. [MANUAL] Verify the email arrives in the user's inbox
- Check for subject line "Welcome to [App Name]"
7. [MANUAL] Complete the CAPTCHA challenge
- Workflow continues after CAPTCHA is solved
9. [MANUAL] Verify push notification appears on device
- Confirm notification content matches expected text
已知限制
| 限制 | 描述 | 解决方法 |
|---|---|---|
| 原生文件对话框 | Playwright 无法与操作系统级文件选择器交互 | 使用 page.setInputFiles(),而不是点击文件输入框 |
| 原生分享面板 | 无法自动化操作系统级分享对话框 | 跳过分享功能或对其进行模拟 |
| 真实设备手势 | Playwright 会模拟触控,但不是真实设备 | 复杂的多点触控手势可能需要手动测试 |
| 摄像头/麦克风访问 | 权限提示与真实移动设备上的情况不同 | 在浏览器上下文设置中授予权限 |
| 多标签页 OAuth | 在新标签页中打开的 OAuth 弹出窗口需要特殊处理 | 使用 context.waitForEvent('page') 模式 |
| 剪贴板访问 | 剪贴板 API 需要权限 | 在浏览器上下文设置中授予权限 |
| 下载验证 | 无法在下载后直接验证文件内容 | 使用下载事件监听器和文件系统检查 |
| 地理位置提示 | 权限提示会阻塞自动化 | 在导航前于上下文选项中设置地理位置 |
| 设备方向 | Playwright 通过调整视口大小来模拟方向变化,但并非原生旋转 | 使用 page.setViewportSize() 交换宽度和高度 |
| iOS Safari 特性 | Playwright 使用 Chromium,而非移动版 WebKit | 注意可能有所不同的 WebKit 特定行为(使用 webkit 浏览器可获得更接近的效果) |
自动化的先决条件
当工作流需要特定设置时,请在 Preconditions 区块中记录:
**Preconditions:**
- User is logged in as admin (`[email protected]` / `password123`)
- Viewport is set to 393x852 (mobile)
- At least 3 posts exist in the database
- The feature flag "new-editor" is enabled
这些信息对于转换器技能生成适当的 beforeEach 和 beforeAll 区块(包括视口配置)至关重要。
iOS 人机界面指南注意事项
生成工作流时,请参考 iOS 人机界面指南(HIG),评估移动 Web 应用的用户体验质量。虽然这是一个 Web 应用(而非原生 iOS 应用),但 iPhone 上的移动 Web 用户对原生 iOS 交互模式有着很高的期待。请标记任何明显偏离这些模式的情况。
触控目标
iOS HIG 建议触控目标的最小尺寸为 44x44 点。对于移动 Web:
- 移动视口中的按钮、链接和交互元素至少应为 44x44px。
- 如果探索发现按钮或链接的计算尺寸较小,请在工作流文档中标记。
- 编写验证步骤:“验证‘[element]’按钮的点击目标至少为 44x44px。”
标签栏与汉堡菜单
iOS 用户期望应用的主要导航使用底部标签栏。对于移动 Web:
- 如果应用仅使用汉堡菜单进行主要导航,请将其记为潜在的用户体验问题。
- 如果应用有底部标签栏,请验证其固定在底部且始终可访问。
- 验证底部导航不会与内容重叠,也不会被虚拟键盘遮挡。
滚动和手势交互
iOS 用户期望滚动流畅且具有原生体验:
- 验证可滚动区域(对于较旧浏览器而言,在需要时)是否应用了
-webkit-overflow-scrolling: touch或等效 CSS。 - 验证是否适当设置了
overscroll-behavior,以防止意外的滚动链传递。 - 如果应用使用自定义手势(滑动删除、下拉刷新),请验证其响应灵敏,且不会与浏览器手势冲突。
防止输入时缩放
在 iOS Safari 中,点按 font-size 小于 16px 的输入框会触发页面自动缩放。这是常见且会严重影响体验的移动端 UX 问题:
- 探索过程中,查找
font-size小于 16px 的输入元素。 - 编写验证步骤:“点按 [input field],验证页面没有放大。”
- 将发现的任何
font-size < 16px输入框标记为移动端 UX 问题。
安全区域内边距
现代 iPhone 带有刘海和主屏幕指示条,可能会遮挡内容:
- 检查应用是否在 CSS 中使用了
env(safe-area-inset-*)或constant(safe-area-inset-*)。 - 如果固定元素(页眉、页脚、底部导航)未考虑安全区域,请标记这一问题。
- 编写验证屏幕边缘附近内容的步骤:“验证底部导航栏未被设备的主屏幕指示条遮挡。”
底部导航模式
如果应用使用底部导航(标签栏、底部操作栏):
- 验证滚动时它始终固定在底部。
- 验证它不会遮挡内容(检查主内容区域是否设置了适当的
padding-bottom)。 - 验证点击标签后会高亮显示活动状态,并导航到正确的部分。
- 验证虚拟键盘打开时,底部导航不会被推到屏幕外。
移动端 UX 反模式
生成工作流时,请留意以下常见的移动端 UX 反模式。如果在探索过程中发现任何此类问题,请在工作流文档中标记,并编写具体的测试步骤,以验证应用是否能正确处理这些问题。
导航反模式
| 反模式 | 重要原因 | 验证步骤 |
|---|---|---|
| 只有汉堡菜单,没有标签栏 | 主要导航被隐藏在额外的点击操作后;增加了移动端的导航成本 | 验证主要部分可在 1-2 次点击内访问;考虑添加底部标签栏 |
| 非原生返回按钮 | 移动端用户期望浏览器/系统返回功能正常工作;自定义返回按钮可能造成困惑 | 向前导航,然后使用浏览器返回,验证前一页面能否正确加载 |
| 缺少底部导航 | 移动端没有常驻导航,意味着每次切换部分时用户都必须打开汉堡菜单 | 验证主要导航始终可见或可快速访问 |
| 只有手势导航,没有备用方式 | 并非所有用户都能发现滑动手势;有无障碍需求的用户可能无法使用这些手势 | 验证所有可通过滑动导航的内容都有可见的按钮/链接作为替代方式 |
| 页面层级过深且没有面包屑导航 | 小屏幕上的深层页面层级会让用户迷失方向 | 深入导航 3 层以上,验证用户能否判断当前所在位置并返回 |
| 移动端重定向循环 | 登录 -> 重定向 -> 登录循环,尤其常见于移动端专用身份验证流程 | 尝试访问受保护的路由,验证是否只重定向到登录页面一次 |
触控反模式
| 反模式 | 重要原因 | 验证步骤 |
|---|---|---|
| 触控目标 < 44px | 手指定位不够精确;目标过小会导致误触并令人沮丧 | 验证所有交互元素的点击区域至少为 44x44px |
| 依赖悬停的交互 | 移动端没有悬停状态;悬停菜单和工具提示无法访问 | 验证所有由悬停触发的内容都有基于点击的替代方式 |
| 表单输入区域过小(字体 < 16px) | 对于字体大小 < 16px 的输入框,iOS Safari 会在聚焦时自动缩放,扰乱布局 | 点击每个输入框,验证页面是否不会自动缩放 |
| 点击间距不足 | 相邻触控目标间距不足会导致误触 | 验证相邻交互元素之间至少有 8px 的间距 |
| 需要双击 | 在移动端出乎意料;某些设备可能会将首次点击视为悬停 | 验证所有操作都能通过单次点击响应 |
| 没有触控反馈 | 用户期望点击时有视觉反馈(不透明度变化、波纹、高亮) | 点击按钮和链接,验证是否立即显示视觉反馈 |
视觉反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| 移动设备上的文字太小 | 正文小于 14px 时,在移动屏幕上难以阅读 | 确认正文至少为 14px;建议使用 16px |
| 小屏幕上的对比度不足 | 在明亮环境中使用小屏幕时,需要较强的对比度 | 确认文字符合 WCAG AA 对比度标准(普通文字为 4.5:1) |
| 缺少 viewport meta 标签 | 没有该标签时,移动浏览器会按桌面宽度渲染页面,然后缩小显示 | 确认存在 <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 固定宽度导致无法适配移动设备 | width: 960px 等样式会破坏移动布局 | 确认内容没有超出 393px 的视口宽度 |
| 内容宽于视口 | 会导致水平滚动,这是严重的移动端 UX 问题 | 在每个页面上水平滚动,确认没有水平溢出 |
| 图片无法自适应 | 未设置 max-width: 100% 的大图会破坏移动布局 | 确认所有图片都能在视口内显示,且不会出现水平滚动 |
| 截断文字无法查看完整内容 | 文字被截断后,没有办法查看完整内容 | 确认截断的文字可以通过点击展开或工具提示查看 |
组件反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| 移动设备上使用桌面风格的下拉菜单 | 下拉选项太小,难以准确点击 | 确认选择元素使用原生移动选择器或可轻松点击的大目标替代方案 |
| 复选框和单选按钮太小 | 标准 HTML 复选框和单选按钮太小,不适合触控 | 确认复选框和单选按钮的点击区域至少为 44x44px |
| 模态框内容超出视口且无法滚动 | 高于移动屏幕的模态框内容将无法访问 | 打开每个模态框,确认所有内容都可以通过滚动访问 |
| 信息依赖工具提示呈现 | 工具提示需要悬停操作,而移动设备上没有这种操作 | 确认移动设备上所有工具提示内容都可以通过点击访问,或始终可见 |
| 桌面尺寸的表格 | 包含多列的宽表格会在移动设备上溢出 | 确认表格可以在容器内水平滚动,或能够在移动设备上重新排列 |
| 多列表单 | 并排的表单字段在移动设备上会太窄 | 确认表单字段在移动视口上纵向排列 |
| 占用过多空间的粘性页眉 | 占用移动视口 20% 以上空间的固定页眉会压缩内容区域 | 确认移动设备上的粘性页眉较为紧凑(高度低于 60px) |
性能反模式
| 反模式 | 重要性 | 验证步骤 |
|---|---|---|
| 未优化的大图 | 移动网络连接通常较慢;大图会延迟渲染 | 确认图片使用响应式尺寸(srcset)或经过合理压缩 |
| 导致丢帧的高负载动画 | 移动设备的 GPU 性能较弱;卡顿的动画会让人感觉功能异常 | 滚动浏览带有动画的页面,确认渲染流畅,达到 60fps |
| 交互时发生布局偏移 | 小屏幕上点击时内容跳动,会让人感到困惑 | 点击交互元素,确认没有意外的布局偏移 |
| JavaScript 过多,阻塞交互 | 长时间执行的 JS 会阻塞移动设备上的触控响应 | 页面加载后立即点击按钮,确认在 100ms 内响应 |
| 异步内容没有加载状态 | 使用慢速移动网络的用户会看到空白区域 | 触发数据加载操作,确认骨架屏或加载指示器立即出现 |
移动端 UX 验证步骤模板
在探索过程中发现反模式时,添加专门的 UX 验证工作流:
## Workflow [N]: Mobile UX Pattern Compliance
> Verifies the application follows mobile web best practices and avoids
> common UX anti-patterns that harm the mobile user experience.
**Preconditions:**
- Viewport is set to 393x852 (mobile)
**Steps:**
1. Navigate to the home page
- Verify no horizontal scroll at 393px viewport width
- Verify the viewport meta tag is present
2. Verify all interactive elements have adequate touch targets
- Tap each button and link on the page
- Verify tap targets are at least 44x44px
- Verify at least 8px spacing between adjacent interactive elements
3. Verify navigation is accessible on mobile
- If hamburger menu: open it, verify all primary nav items are present
- Verify navigation can be reached within 2 taps from any page
4. Tap each form input field
- Verify the page does not auto-zoom on focus (font-size >= 16px)
- Verify the virtual keyboard does not obscure the active input
- Verify form fields are stacked vertically
5. Open any modals or bottom sheets
- Verify content does not overflow the mobile viewport
- Verify the modal/sheet can be dismissed (close button or swipe)
6. Scroll through the full page
- Verify content reflows to single-column where appropriate
- Verify images fit within the viewport
- Verify no horizontal overflow on any section
7. Navigate using browser back button
- Verify the previous page loads correctly
- Verify no redirect loops occur
8. [Continue based on specific anti-patterns found...]
处理更新
当用户选择“更新”模式(修改现有工作流)时,请遵循以下规则,尽可能减少干扰,同时确保覆盖内容保持最新。
更新现有工作流的规则
-
保留可用的工作流——如果现有工作流仍然有效(路由存在、组件匹配、步骤正确),则保持不变。不要为了保持风格一致而改写可用的工作流。
-
标记已弃用的工作流——如果工作流引用的路由或组件已不存在,不要删除它,而应添加弃用标记:
## Workflow 7: Legacy Export Feature
> **DEPRECATED** -- This workflow references the legacy export feature which
> has been removed. Keeping for reference until confirmed safe to delete.
-
添加新工作流——将新工作流追加到相应部分(Core、Feature 或 Edge Case)。按顺序编号,接续最后一个现有工作流。
-
版本说明——在文件顶部添加版本历史部分:
## Version History
| Date | Action | Details |
|------|--------|---------|
| 2025-01-20 | Updated | Added workflows 26-28 for new dashboard features |
| 2025-01-15 | Updated | Deprecated workflow 7 (export feature removed) |
| 2025-01-01 | Created | Initial generation: 25 workflows |
- 重新验证现有工作流——探索期间,将现有工作流的步骤与当前代码库交叉核对。标记引用了已更改元素或路由的步骤:
3. Tap the "Export CSV" button
- **[CHANGED]** Button label is now "Download CSV" (updated in v2.2)
- Verify download begins within 3 seconds
- 保留工作流编号——绝不要重新排列现有工作流的编号。如果工作流 7 已弃用,而新增了工作流 28,则保留编号空缺。这样可以确保对“工作流 7”的外部引用仍然有效。
更新摘要
更新操作完成后,提供更改摘要:
Mobile workflow update complete.
Changes:
- Workflows preserved (unchanged): 20
- Workflows updated (steps modified): 3
- Workflows deprecated: 1
- Workflows added (new): 3
- Total workflows: 27 (1 deprecated)
Changed workflows:
- Workflow 4: Updated step 3 (button label changed)
- Workflow 12: Updated step 1 (route changed from /settings to /preferences)
- Workflow 19: Updated steps 5-7 (new confirmation dialog added)
Deprecated workflows:
- Workflow 7: Legacy Export Feature (export removed in v2.3)
New workflows:
- Workflow 26: Dashboard Widget Customization (mobile layout)
- Workflow 27: Pull-to-Refresh Feed
- Workflow 28: Bottom Sheet Filter Selection