appshots-accessibility-ids
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAccessibility Identifiers for Screenshot Automation
用于截图自动化的可访问性标识符
Before any automation tool (Maestro or AXe) can reliably tap elements in your app, those elements need stable accessibility identifiers. This skill teaches you how to add them across frameworks.
在任何自动化工具(如 Maestro 或 AXe)能够可靠地点击应用中的元素之前,这些元素需要稳定的可访问性标识符。本文将教你如何在不同框架中添加这类标识符。
Why Accessibility Identifiers?
为什么需要可访问性标识符?
| Without identifiers | With identifiers |
|---|---|
| Tap by coordinates → breaks on different screens | Tap by |
| Tap by text → breaks across locales | Identifiers are locale-independent |
| Need trial-and-error | Predictable, documented targets |
| 无标识符情况 | 有标识符情况 |
|---|---|
| 通过坐标点击 → 在不同屏幕上会失效 | 通过 |
| 通过文本点击 → 多语言环境下会失效 | 标识符不受语言环境影响 |
| 需要反复试错 | 目标可预测且有文档记录 |
Framework Reference
框架参考
Flutter (3.19+)
Flutter (3.19+)
dart
Semantics(
identifier: 'settings_button', // ← stable, locale-independent
child: ElevatedButton(
onPressed: () => openSettings(),
child: Text(context.l10n.settings), // ← localized, changes per locale
),
)was contributed by the Maestro team in Flutter 3.19.Semantics.identifier
dart
Semantics(
identifier: 'settings_button', // ← 稳定且独立于语言环境
child: ElevatedButton(
onPressed: () => openSettings(),
child: Text(context.l10n.settings), // ← 本地化文本,随语言环境变化
),
)是由 Maestro 团队在 Flutter 3.19 版本中贡献的特性。Semantics.identifier
SwiftUI
SwiftUI
swift
Button("Settings") {
openSettings()
}
.accessibilityIdentifier("settings_button")swift
Button("Settings") {
openSettings()
}
.accessibilityIdentifier("settings_button")UIKit
UIKit
swift
button.accessibilityIdentifier = "settings_button"swift
button.accessibilityIdentifier = "settings_button"Jetpack Compose
Jetpack Compose
kotlin
Button(
onClick = { openSettings() },
modifier = Modifier.semantics { testTag = "settings_button" }
) {
Text(stringResource(R.string.settings))
}In Compose, useinsidetestTag— Maestro matches this asModifier.semantics { }.id:
kotlin
Button(
onClick = { openSettings() },
modifier = Modifier.semantics { testTag = "settings_button" }
) {
Text(stringResource(R.string.settings))
}在 Compose 中,需在内使用Modifier.semantics { }—— Maestro 会将其识别为testTag选择器。id:
Android XML Views
Android XML 视图
xml
<Button
android:id="@+id/settings_button"
android:contentDescription="@string/settings"
android:tag="settings_button" />Maestro usesas theandroid:tagselector for XML views.id:alone is not enough.android:id
xml
<Button
android:id="@+id/settings_button"
android:contentDescription="@string/settings"
android:tag="settings_button" />Maestro 会将 XML 视图的作为android:tag选择器。仅使用id:是不够的。android:id
React Native
React Native
jsx
<TouchableOpacity
testID="settings_button"
accessibilityLabel="Settings"
onPress={openSettings}
>
<Text>{t('settings')}</Text>
</TouchableOpacity>React Native useswhich maps directly to Maestro'stestIDselector.id:
jsx
<TouchableOpacity
testID="settings_button"
accessibilityLabel="Settings"
onPress={openSettings}
>
<Text>{t('settings')}</Text>
</TouchableOpacity>React Native 使用,它直接对应 Maestro 的testID选择器。id:
Naming Conventions
命名规范
Use a consistent pattern across all frameworks:
context_elementundefined在所有框架中统一使用的命名模式:
context_elementundefinedNavigation
导航组件
tab_home
tab_search
tab_profile
tab_settings
tab_home
tab_search
tab_profile
tab_settings
Feature cards / buttons
功能卡片/按钮
feature_camera
feature_scan
feature_create
feature_camera
feature_scan
feature_create
List items (indexed)
列表项(带索引)
list_item_0
list_item_1
search_result_0
list_item_0
list_item_1
search_result_0
In-screen actions
屏幕内操作按钮
login_submit_button
onboarding_next_button
dialog_confirm_button
undefinedlogin_submit_button
onboarding_next_button
dialog_confirm_button
undefinedRules
规则
- Always lowercase with underscores — , not
settings_buttonSettingsButton - Prefix with screen/context — Prevents collisions across screens
- Use indices for lists — ,
list_item_0search_result_0 - Avoid localized text — Never use translated strings as identifiers
- Keep them short but descriptive — , not
tab_homebottom_navigation_bar_home_tab_button
- 始终使用小写字母加下划线 — 例如,而非
settings_buttonSettingsButton - 以屏幕/上下文作为前缀 — 避免跨屏幕的标识符冲突
- 列表项使用索引 — 如、
list_item_0search_result_0 - 避免使用本地化文本 — 切勿将翻译后的字符串用作标识符
- 保持简短且具有描述性 — 如,而非
tab_homebottom_navigation_bar_home_tab_button
Verification
验证方法
Using Maestro Studio (All Frameworks)
使用 Maestro Studio(所有框架)
bash
maestro studioOpens a browser UI where you can click elements and see their identifiers.
bash
maestro studio打开浏览器界面,你可以点击元素并查看其标识符。
Using AXe CLI (iOS Only)
使用 AXe CLI(仅 iOS)
bash
axe describe-ui --udid <SIMULATOR_UDID>
axe describe-ui --udid <SIMULATOR_UDID> | grep "settings_button"bash
axe describe-ui --udid <SIMULATOR_UDID>
axe describe-ui --udid <SIMULATOR_UDID> | grep "settings_button"Framework-Specific Debuggers
框架专属调试工具
| Framework | Debug tool |
|---|---|
| Flutter | |
| SwiftUI/UIKit | Xcode Accessibility Inspector |
| Android | Layout Inspector → Accessibility pane |
| React Native | Appium Inspector or |
| 框架 | 调试工具 |
|---|---|
| Flutter | 在 |
| SwiftUI/UIKit | Xcode 可访问性检查器 |
| Android | 布局检查器 → 可访问性面板 |
| React Native | Appium Inspector 或 |
Minimum Identifiers Checklist
最低标识符检查清单
Before running any capture flow, ensure these element types have identifiers:
- Navigation tabs — every tab bar item
- Feature cards / CTAs on home screen — primary actions
- Scrollable content items — cards, list items that need tapping
- Key action buttons — Play, Start, Submit, Confirm
- Modal/popup triggers — elements that open detail views
在运行任何截图捕获流程前,确保以下类型的元素已添加标识符:
- 导航标签 — 每个标签栏项
- 首页功能卡片/CTA按钮 — 主要操作按钮
- 可滚动内容项 — 需要点击的卡片、列表项
- 关键操作按钮 — 播放、开始、提交、确认按钮
- 弹窗/模态框触发元素 — 打开详情页的元素
Agent Guidelines
Agent 操作指南
Thinking Process
思考流程
When asked to "prepare an app for screenshot automation":
- Identify the framework — Flutter, SwiftUI, UIKit, Compose, XML Android, or React Native
- Identify screens to capture — List the screenshots needed
- Map navigation paths — What taps/swipes reach each screen?
- Find missing identifiers — Check which tappable elements lack identifiers
- Add identifiers — Use the correct API for the framework (see table above)
- Rebuild and verify — Build the app, then run or
maestro studioaxe describe-ui
当被要求“为截图自动化准备应用”时:
- 确定框架类型 — Flutter、SwiftUI、UIKit、Compose、XML Android 或 React Native
- 确定需要捕获的屏幕 — 列出需要截图的页面
- 梳理导航路径 — 点击/滑动操作如何到达每个屏幕
- 找出缺失的标识符 — 检查哪些可点击元素缺少标识符
- 添加标识符 — 使用对应框架的正确 API(见上方表格)
- 重新构建并验证 — 构建应用,然后运行或
maestro studio进行验证axe describe-ui
Common Mistakes to Avoid
需避免的常见错误
- ❌ Adding identifiers to non-interactive widgets (labels, dividers)
- ❌ Using localized strings as identifiers
- ❌ Forgetting to rebuild after adding identifiers
- ❌ Using the same identifier on multiple elements on the same screen
- ❌ Using without
android:idfor XML Android viewsandroid:tag
- ❌ 为非交互组件(标签、分隔符)添加标识符
- ❌ 使用本地化字符串作为标识符
- ❌ 添加标识符后忘记重新构建应用
- ❌ 在同一屏幕的多个元素上使用相同的标识符
- ❌ 对于 XML Android 视图,仅使用而未添加
android:idandroid:tag