limrun-ios-simulator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLimrun iOS Simulator
Limrun iOS模拟器
Interact with an app running on a Limrun cloud iOS simulator, from any
environment (Linux, Windows, macOS, VM, container). This skill is build-agnostic:
it assumes the app was already built and installed by a build skill
( for Bazel, for xcodebuild). Keep build
concerns in those skills; this one is about driving the running simulator.
limrun-xcode-bazellimrun-xcodeNever use local Xcode, local simulators, or local macOS tools.
可从任意环境(Linux、Windows、macOS、虚拟机、容器)与运行在Limrun云iOS模拟器上的应用进行交互。本技能与构建方式无关:它假设应用已由构建技能(Bazel项目使用,xcodebuild项目使用)完成构建并安装。构建相关事宜请交由那些技能处理;本技能专注于操控运行中的模拟器。
limrun-xcode-bazellimrun-xcode切勿使用本地Xcode、本地模拟器或本地macOS工具。
Auth and CLI
认证与CLI
Install if needed: . Auth is or
(it may be set outside the project, so don't ask for it just
because it's missing from or the shell). The CLI is the source of truth:
the commands in this skill are verified, but if a flag errors or you need one
not shown here, check instead of guessing.
npm install --global limlim loginLIM_API_KEY.envlim ios <subcommand> --help若需安装:。认证方式为或设置(该密钥可能在项目外部设置,因此不要仅因或shell中未包含就向用户索要)。CLI是权威来源:本技能中的命令均经过验证,但如果某个标记报错或你需要此处未展示的标记,请查看,而非自行猜测。
npm install --global limlim loginLIM_API_KEY.envlim ios <subcommand> --helpGet a simulator attached
获取已连接的模拟器
A build skill usually attaches the simulator for you (, or
then attach). Check what's already there:
lim xcode rbe --ioslim xcode build .bash
lim xcode get # is a simulator attached to the current build target?
lim ios list # all running iOS instancesIf none is attached, create one. It installs the last build immediately, so you
don't need to rebuild:
bash
lim ios create --attachIf the create (or ) output includes a signed stream URL,
share it with the user as a Markdown link, like
Live simulator. If you have a browser the user can see,
open the URL there and tell them.
lim xcode rbe --ioslim xcode get构建技能通常会自动为你连接模拟器(例如,或执行后进行连接)。检查当前已有的模拟器:
lim xcode rbe --ioslim xcode build .bash
lim xcode get # 当前构建目标是否已连接模拟器?
lim ios list # 所有运行中的iOS实例如果没有已连接的模拟器,请创建一个。它会立即安装最新构建的应用,因此无需重新构建:
bash
lim ios create --attach如果创建(或)的输出包含已签名的流URL,请将其作为Markdown链接分享给用户,例如实时模拟器。如果用户可以看到你的浏览器,可在此打开该URL并告知用户。
lim xcode rbe --ioslim xcode getTargeting the right instance
定位正确的实例
Most commands default to the last created instance and resolve the
"current" one from the git repo / worktree of your cwd. So even when a
simulator is attached and shows it, a command can still
report , because your
cwd isn't the git worktree where the instance was created (or isn't a git repo at
all). This bites most often right after in a fresh project.
lim ioslim xcode getlim iosNo instance ID provided and no recent ios instance foundlim xcode rbe --iosThe reliable recipe when that happens:
bash
lim xcode get # shows the attached simulator's ID
lim ios element-tree --id <that-id> # pass --id to EVERY lim ios commandlim xcode getlim ios list--id <ios-instance-id>lim iosgit init--id大多数命令默认使用最后创建的实例,并根据当前工作目录的git仓库/工作区解析“当前”实例。因此,即使模拟器已连接且显示了它,命令仍可能提示,这是因为你的当前工作目录并非创建该实例的git工作区(或根本不是git仓库)。这种情况在新项目中执行后最常出现。
lim ioslim xcode getlim iosNo instance ID provided and no recent ios instance foundlim xcode rbe --ios遇到这种情况时的可靠解决方法:
bash
lim xcode get # 显示已连接模拟器的ID
lim ios element-tree --id <该ID> # 为所有lim ios命令添加--id参数lim xcode getlim ios listlim ios--id <ios实例ID>git init--idLaunching the app
启动应用
The build skills reinstall and relaunch the app after every successful build,
so you usually don't need to launch it yourself. When the app is closed (a
fresh attach to an old build, or after a terminate), launch it by bundle ID:
bash
lim ios launch-app <bundle-id> # foregrounds it if already running
lim ios launch-app <bundle-id> --mode RelaunchIfRunning # restart for a clean state
lim ios terminate-app <bundle-id> # stop it, e.g. to reset app stateIf you don't know the bundle ID, run .
lim ios list-apps构建技能会在每次构建成功后重新安装并重启应用,因此通常无需手动启动。当应用已关闭(例如连接到旧构建的新模拟器,或应用被终止后),可通过Bundle ID启动:
bash
lim ios launch-app <Bundle ID> # 若应用已运行则将其置于前台
lim ios launch-app <Bundle ID> --mode RelaunchIfRunning # 重启应用以获得干净状态
lim ios terminate-app <Bundle ID> # 停止应用,例如重置应用状态若不知道Bundle ID,请运行。
lim ios list-appsTesting changes
测试变更
When simulator interaction is part of the task, test new or changed
functionality with the interaction commands after each build. Focus on what
changed, plus a quick smoke test of core flows. Start by reading the element
tree to see what's on screen before acting:
bash
lim ios element-tree当任务包含模拟器交互时,每次构建后使用交互命令测试新增或修改的功能。重点关注变更内容,再快速进行核心流程的冒烟测试。操作前先读取元素树,查看当前屏幕显示的内容:
bash
lim ios element-treeInteracting with the app
与应用交互
Prefer tapping by accessibility id, then by label, then coordinates as a last
resort:
bash
lim ios tap-element --ax-unique-id startButton
lim ios tap-element --ax-label "Save"
lim ios tap 201 450Toolbar / nav-bar items usually can't be tapped by id. SwiftUI collapses
toolbar children into a single nav-bar group, and those items report
even when you set (regular
content s do expose it). So finds nothing
for a nav-bar button. Set an /
anyway for documentation, but to actually tap it, read its from the
element tree and tap the center by coordinate:
AXUniqueId: null.accessibilityIdentifier(...)Buttontap-element --ax-unique-id.accessibilityLabel.accessibilityIdentifierAXFramebash
lim ios element-tree --id <id> | grep -i -A6 -B2 moon # find the item's AXFrame
lim ios tap <x> <y> --id <id> # tap the frame's centerFor text input:
bash
lim ios type "hello world"After every interaction, re-run to confirm the UI transitioned.
No sleep is needed between a tap and ; the tap blocks until done.
element-treeelement-treebash
lim ios element-treeChain multiple actions with precise timing via :
performbash
lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World"
lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter
lim ios perform --file ./actions.yamlRun for the full action grammar.
lim ios perform --help优先通过无障碍ID点击,其次是标签,最后才考虑通过坐标点击:
bash
lim ios tap-element --ax-unique-id startButton
lim ios tap-element --ax-label "Save"
lim ios tap 201 450工具栏/导航栏项通常无法通过ID点击。SwiftUI会将工具栏子项折叠为单个导航栏组,即使你设置了,这些项仍会报告(常规内容中的会暴露该ID)。因此无法找到导航栏按钮。无论如何仍需设置 / 用于文档记录,但实际点击时,需从元素树中读取其,然后点击坐标中心:
.accessibilityIdentifier(...)AXUniqueId: nullButtontap-element --ax-unique-id.accessibilityLabel.accessibilityIdentifierAXFramebash
lim ios element-tree --id <ID> | grep -i -A6 -B2 moon # 查找该项的AXFrame
lim ios tap <x> <y> --id <ID> # 点击框架中心文本输入操作:
bash
lim ios type "hello world"每次交互后,重新运行以确认UI已完成过渡。点击和之间无需等待;点击操作会阻塞直到完成。
element-treeelement-treebash
lim ios element-tree通过命令按精准时间链执行多个动作:
performbash
lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World"
lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter
lim ios perform --file ./actions.yaml运行查看完整的动作语法。
lim ios perform --helpScreenshots and video
截图与视频
Screenshot takes a positional path (not ):
-obash
lim ios screenshot screenshot.png
lim ios screenshot screenshot.png --id <ios-instance-id>Use the element tree for functional assertions (element existence, labels, state
changes) and screenshots only for visual properties. For anything involving
motion (animations, gameplay, streaming UI), prefer video:
bash
lim ios record start # non-blocking
lim ios record stop -o /tmp/recording.mp4For UI changes, include a demo video in the pull request so the user can see it.
截图命令使用位置路径(而非参数):
-obash
lim ios screenshot screenshot.png
lim ios screenshot screenshot.png --id <iOS实例ID>使用元素树进行功能断言(元素存在性、标签、状态变化),仅使用截图验证视觉属性。对于涉及动态效果(动画、游戏、流式UI)的场景,优先使用视频:
bash
lim ios record start # 非阻塞式录制
lim ios record stop -o /tmp/recording.mp4对于UI变更,请在拉取请求中包含演示视频,以便用户查看。
Cleanup
清理
When the user is done with the dev session:
bash
lim ios deleteIf they're still iterating in a dev-client / Metro session, leave the simulator
running and tell them it's still available.
当用户完成开发会话后:
bash
lim ios delete如果用户仍在开发客户端/Metro会话中迭代,请保持模拟器运行并告知用户它仍可用。
Gotchas
注意事项
- Instance resolution can miss in a non-git dir. See "Targeting the right
instance" above; pass when in doubt.
--id - can be large. Pipe through
element-tree/grepto extract what you need rather than dumping the whole tree into context.jq - /
typemay not drive SwiftUI (or React Native) state. Automated text injection sets the field's value through accessibility, which does not always fire a SwiftUIperform typeText/@Bindingthe way a real keystroke does. Symptom: the text appears in the field (and inonChange), but reactive UI tied to it doesn't update (a send button stays disabled, a character counter doesn't move) and submit handlers see empty state. A real keyboard on the live stream works. When automating, drive submit through a tappable control (a button, a suggestion chip) rather than relying on text bound to reactive state, or have the app expose a test affordance.element-tree - Toolbar / nav-bar items aren't tappable by id. See "Interacting with the
app" above: read the from
AXFrameand tap by coordinate.element-tree - Bundle ID discovery. If you don't know the bundle ID, run
after a successful install.
lim ios list-apps - Build errors are the build skill's job. If the app isn't installing, the
failure is upstream; go back to /
limrun-xcode-bazel.limrun-xcode
- 在非git目录中实例解析可能失败:请参考上文“定位正确的实例”部分;如有疑问,添加参数。
--id - 输出可能很大:通过
element-tree/grep管道提取所需内容,而非将整个树输出到上下文。jq - /
type可能无法驱动SwiftUI(或React Native)状态:自动化文本注入通过无障碍接口设置字段值,但这并不总是像真实按键那样触发SwiftUI的perform typeText/@Binding。症状:文本显示在字段中(且在onChange中可见),但与之绑定的响应式UI未更新(发送按钮保持禁用状态,字符计数器未变化),提交处理程序会看到空状态。实时流中的真实键盘可正常工作。自动化时,通过可点击控件(按钮、建议芯片)触发提交,而非依赖绑定到响应式状态的文本,或让应用暴露测试接口。element-tree - 工具栏/导航栏项无法通过ID点击:请参考上文“与应用交互”部分:从读取
element-tree并通过坐标点击。AXFrame - Bundle ID查找:若不知道Bundle ID,请在安装成功后运行。
lim ios list-apps - 构建错误由构建技能处理:如果应用无法安装,问题出在构建环节;请回到/
limrun-xcode-bazel处理。limrun-xcode