e2e 集成 EAS Simulators:@e2e-dev/eas 的版本演进与 easSimulators() 实战指南

发布时间:2026/10/9 6:31:35
e2e 集成 EAS Simulators:@e2e-dev/eas 的版本演进与 easSimulators() 实战指南 测试测试智能体人工智能浏览器控制CLI【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址https://gitcode.com/GitHub_Trending/e2e6/e2e点击查看免费下载e2e-dev/eas是 e2e 测试框架的 EAS Simulators 集成包通过easSimulators()设备提供方让mobile引擎把移动目标跑在 Expo 托管的 iOS 模拟器和 Android 模拟器上运行机上无需 Mac、Xcode 或 Android SDK。本文以 packages/eas/CHANGELOG.md 记录的 0.1.0–0.3.0 四个版本演进为主线结合 provider 源码 与 集成文档讲清该包的鉴权、项目解析、配置参数、会话生命周期与清理机制读完后可独立完成 CI 中的云模拟器 E2E 接入。版本演进总览CHANGELOG 记录了e2e-dev/eas的全部四个版本每个版本对应一次有明确主题的能力演进版本主题关键变化0.1.0首次发布easSimulators()上线每 worker 槽位一个托管模拟器buildId/applicationArchiveUrl安装应用未知选项以INVALID_CONFIG拒绝并提示最接近的选项名如buildID→buildId0.1.1发布元数据e2e包带上仓库 README各包补充可被搜索到的关键词见 package.json 的 keywords0.2.0鉴权与项目解析增强支持读取eas login保存的会话projectId缺省时从 app config 自动解析0.2.1瘦身e2e安装依赖从 117 个包降到 29 个、体积约 31MBe2e mcp换用拆分后的 MCP SDK构建产物不再附带指向未发布的src/的 sourcemap0.3.0运行时门槛与 TypeScript 加载器所有e2e-dev包要求 Node.js^22.22.3 \|\| 24.8.0e2e改用基于 oxc 的自研加载器替代 tsx版本 0.3.0 还明确了 peer 依赖与引擎门槛e2e-dev/mobile 0.8.0 1、e2e 0.15.0 1package.json 的engines.node即^22.22.3 || 24.8.0。0.3.0Node.js 版本门槛与自研 TypeScript 加载器0.3.0 是 Minor 变更但带破坏性影响e2e及每个e2e-dev包需要 Node.js 22 系的 22.22.3或 24 系的 24.8.0Node.js 22.12–22.22.2、23、24.0–24.7 不再受支持CLI 在这些版本上会拒绝启动并指明应升级到的版本。原因是这些版本在 CommonJS 文件通过新加载器的module.registerHooks引入 TypeScript 时会失败上游在 22.22.3 与 24.8.0 修复。同一版本中e2e用基于 oxc 的自研加载器替换 tsx 编译 TypeScript替换的直接动因是 tsx 携带的 esbuild 有 postinstall 脚本导致 pnpm 11 上每次pnpm install都报ERR_PNPM_IGNORED_BUILDS换成自研加载器后安装e2e的任何包都不再执行 install 脚本。对使用者可见的行为包括配置与测试的加载能力保持兼容ESM/./x.js解析到x.ts、./x.jsx到x.tsx、目录 index 导入、tsconfigpaths与baseUrl、工作区内导出.ts源码的包、.tsx/.jsx中的 JSX、enum、namespace、experimentalDecorators、带 source map 的堆栈无with { type: json }的 JSON 导入依然可用文件名含%、#或空格的测试文件现在能带着源码位置被收集而不是报 URI malformed每个文件读取其最近邻的tsconfig.json而不是工作目录里的那份变化点.cts文件中的import语句不再被编译为require需写import x require()未开启experimentalDecorators的标准装饰器、auto-accessors、.cts中的 ES moduleimport与值export会被拒绝并在错误中给出行号CLI 拒绝 Bunbun --bun与 Deno 运行时在emitDecoratorMetadata下、被装饰成员类型以非import type方式导入且保留在产物中的类型会导致加载失败错误信息会点名该导入被 CommonJS 文件require的.ts文件按 ES module 运行用module.exports写的需改.cts后缀JavaScript 文件里的导入按 Node.js 规则解析不享受 TypeScript 扩展名规则与 tsconfigpaths已安装包内部的 TypeScript 编译不使用项目的tsconfig.json。对使用e2e-dev/eas的实际影响运行e2e run的机器本地或 CI runner必须落在受支持的 Node.js 版本区间内。安装与基本用法npm install --save-dev e2e-dev/ease2e.config.ts 配置示例同时给出pnpm add -D e2e-dev/eas与bun add -d e2e-dev/eas两种等价安装方式import type { E2EConfig } from e2e; import { mobile } from e2e-dev/mobile; import { easSimulators } from e2e-dev/eas; export default { targets: [ { engine: mobile({ platform: ios, device: easSimulators({ buildId: process.env.EAS_BUILD_ID }), videoTouches: false, // EAS iOS 模拟器录屏时必须关闭触摸指示 }), app: { bundleId: com.example.app }, }, ], workers: 2, } satisfies E2EConfig;注意 EAS Simulators 处于有限开放limited access阶段可用npx eas-clilatest simulator:availability检查自己的账号权限。该包用fetch直接调用 Expo API没有需要额外安装的 SDK其唯一依赖面是 peer 依赖的e2e-dev/mobile引擎侧与e2e配置校验侧。鉴权EXPO_TOKEN 与 eas-cli 登录0.2.0PR 记录见 CHANGELOG引入了与 eas-cli 完全一致的鉴权顺序实现位于 credentials.tsEXPO_TOKEN运行环境中的 Expo access token以Authorization: Bearer头发送。CI 上应作为 secret 设置当机器上同时存在 eas-cli 个人登录时设置EXPO_TOKEN可让会话以机器人账号而非个人账号启动。eas-cli 登录会话EXPO_TOKEN未设置时读取eas login写入的~/.expo/state.jsonWindows 为USERPROFILE下取auth.sessionSecret并以expo-session头发送——与 eas-cli 的行为一致。因此已登录 eas-cli 的机器无需任何 token。两者皆无时租约在任何 EAS 请求发出前失败错误信息为EXPO_TOKEN is not set and eas-cli is not logged in。从源码可确认的几个实现细节EXPO_TOKEN与 eas-cli 登录同时存在时EXPO_TOKEN优先只读取生产登录会话 API 固定为api.expo.deveas-cli 的 staging 与 local 登录EXPO_STAGING、EXPO_LOCAL不会被读取每次easSimulators()实例会为每个凭据维护一个 GraphQL 客户端会话以创建它的账号关闭即使运行期间登录发生变化provider.ts 中leaseClients按会话 id 记录了创建时的客户端读取的 home 取运行环境中的HOMEWindows 为USERPROFILE解析不到时回退到os.homedir()state.json存在但不是合法 JSON 时错误会提示重新eas login或设置EXPO_TOKEN且错误信息刻意不包含文件内容避免把 secret 引进日志。CI 建议在 runner 或共享机器上显式设置EXPO_TOKEN。否则 runner home 里残留的他人登录会以该账号启动计费会话。projectId 解析显式传入或从 app config 自动读取0.2.0 的另一项变化是projectId变为可选。会话必须归属某个 Expo 项目easSimulators()缺省projectId时project.ts 从e2e.config.ts所在项目根目录的 app config 中读取extra.eas.projectId即eas init写入的 id规则与 Expo 自身解析一致静态配置app.config.json优先于app.json见源码中STATIC_CONFIGS的顺序按 JSON 读取若文件顶层有expo键则从expo下取否则取整个文件动态配置按 Expo 的顺序app.config.ts、.mts、.cts、.mjs、.cjs、.js任一命中即优先于静态配置用项目自己的expo config --json --type public在运行环境中求值因为配置里可以计算 id。与 eas-cli 一致不加载.env文件源码中显式设置EXPO_NO_DOTENV1配置读取的变量必须在e2e run启动时的环境里此路径要求项目安装了expoCLI 从projectRoot及父目录的node_modules中定位不走NODE_PATH或全局目录。解析时机与缓存每个 run 只读一次在第一个会话启动之前同一 run 内按runId projectRoot缓存两个 target 共享一次读取读取失败不缓存下次重试。找不到 app config、或配置未关联项目时租约在任何会话启动前失败错误指明具体文件名并提示pass projectId to easSimulators(), or run eas init to link the app to an EAS project。两个前提限制值得注意该能力依赖会向设备提供方传递projectRoot的e2e-dev/mobile更老的版本会在租约失败信息中要求升级或显式传projectIdprovider.ts 中的projectIdFor当e2e.config.ts不在应用目录、或 app config 未关联项目时直接以projectId传入传项目 id不是 slug。配置参数全解easSimulators(options)接受的全部选项定义在 provider.ts 的EasSimulatorsOptions与 集成文档的选项表 对应选项默认值含义projectId来自 app config会话归属的 Expo 项目 id。缺省时从extra.eas.projectId解析见上文buildId无指定一次 EAS Buildsimulator 构建eas.json中ios: { simulator: true }或 APKEAS 在每个模拟器就绪前安装并启动它搭配 target 的app.bundleId不要设置app.appPathapplicationArchiveUrl无应用归档 URLEAS 下载并安装效果等价于 build与buildId互斥deviceEAS 自选iOS 设备名或 UDID如iPhone 17 Pro或 Android AVD 硬件 profile如pixel_9maxIdleTimeMinutes10无 agent-device 命令多久后 EAS 停止会话是运行意外终止后释放会话的兜底。EAS 要求它低于maxDurationMinutes因此当传入的时长更短时默认值自动降为maxDurationMinutes - 1maxDurationMinutes账号上限会话就绪后最多运行分钟数EAS 上限为 40 分钟高优先级计划为 115 分钟agentDeviceVersion引擎版本EAS 启动会话 daemon 的 agent-device 版本默认取e2e-dev/mobile钉住的版本保证远端 daemon 按引擎客户端的预期应答不传时 EAS 启动最新版tags[]附加到每个会话的标签与运行自身标签并存EAS 以小写存储配置期校验在easSimulators()调用时立即执行未知选项报INVALID_CONFIG若拼写接近某个已知选项如buildIDvsbuildId错误会点名最接近的那个否则列出全部合法选项。这一行为自 0.1.0 起取代了静默丢弃拼错的选项的旧行为buildId与applicationArchiveUrl同时传入INVALID_CONFIG二选一maxIdleTimeMinutes maxDurationMinutes两者都传入时INVALID_CONFIG错误说明 EAS requires 前者低于后者maxIdleTimeMinutes计算结果小于 1按无空闲上限处理undefined因为 EAS 不接受零值——会话会一直运行到其时长上限buildId/applicationArchiveUrl与 target 的app.appPath冲突acquire阶段报错 EAS installs the app frombuildIdorapplicationArchiveUrl; leave the targetsapp.appPathout。会话生命周期与源码常量一个 worker 槽位对应一个会话。会话状态机在 client.ts 中被建模为四个 phasequeued等待账号并发容量、starting启动/安装中、readydaemon 可达携带daemonUrl与daemonToken、endedSTOPPED/ERRORED或 job 进入终止态。ready()轮询逻辑由一组 provider.ts 中的源码常量 精确刻画常量值语义POLL_INTERVAL_MS5000状态轮询间隔源码注释说明一个模拟器从排队、启动到安装 build 大约需要 3 分钟QUEUE_NOTICE_MS120000排队满 2 分钟记一条日志still queued at EAS after two minutes; tests start once every worker has a simulator每个会话都会有短暂排队STARTUP_TIMEOUT_MS900000离开队列后 15 分钟仍未就绪视为卡死与 eas-cli 的放弃点一致租约失败且会话被停止POLL_FAILURES_TOLERATED3允许连续 3 次状态轮询失败api.expo.dev的短暂抖动超过才放弃其他生命周期行为均可在 provider.ts 中对应到代码会话以e2e target n of total命名并自动加标签e2e、e2e-run:run id、e2e-target:target因此可用eas simulator:list --tag e2e-run:run id找回某次运行的全部会话创建会话使用独立的 60 秒超时不受请求取消信号约束——取消若发生在创建之后会话已经存在且计费必须显式停止否则成为无人知晓的计费会话某会话仍在排队、而同运行的另一会话已就绪并达到其maxIdleTimeMinutes空闲上限时排队会话的租约直接失败EAS 正要停掉那个空闲会话错误提示lower workers or raise maxIdleTimeMinutes会话创建后到ready之间的任何失败错误、取消、卡死都会调用stop回滚stop还会在 job 仍排队时取消该 jobclient.ts 的CANCEL_JOBmutation——否则 EAS 稍后仍会启动它并占用账号并发额度EAS 从会话启动即计费而引擎只持有acquire成功返回的租约因此上述回滚是避免计费泄漏的关键路径运行结束时的release用创建该会话时的凭据客户端停止它并清理 run 级缓存projectIds、idleDeadlines停止一个 EAS 已不认识的会话按成功处理NOT_FOUND_ERROR被吞掉。并发规模上每个 target 启动至多workers个会话--workers可覆盖测试文件更少时更少全部就绪后测试才开始3 分钟的准备期在运行计时开始之前、且各槽位并行。一次运行必须装进单个会话的寿命就绪后 40/115 分钟更长的套件应拆分到更多 worker 或更多 CI job。应用安装方式与日志观测三种应用安装方式集成文档 Install the app 一节// 方式一EAS 从 buildId 安装构建不离开 EAS { engine: mobile({ platform: ios, device: easSimulators({ buildId }) }), app: { bundleId: com.example.app } } // 方式二applicationArchiveUrl 同理EAS 下载归档并安装 // 方式三本地构建fixture 调用 device.installApp() 通过 daemon 上传 { engine: mobile({ platform: ios, device: easSimulators() }), app: { bundleId: com.example.app, appPath: build/App.app } }运行中的日志形态集成文档 给出的样例ℹ leasing 2 ios device(s) from eas-simulators ℹ eas-simulators (1 of 2): simulator session 01a0…, https://expo.dev/accounts/acme/projects/shop/simulator-sessions/01a0… ℹ eas-simulators: leased 01a0…每个会话创建时记录其 expo.dev 页面若浏览器预览无需 token 即可打开也会以watch at url记录需要 token 的预览不记录——token 出现在 CI 日志里等于把模拟器控制权交给任何能读日志的人。录屏注意事项录屏通过模拟器上的 agent-device 进行与本地一致产物存为 attempt 工件目录下的video/video.mp4。但必须像上面的示例那样设置 mobile 引擎的videoTouches: falseagent-device 在录制停止时才把触摸指示画进录像而该操作在 EAS iOS 模拟器上耗时数分钟导致每个录屏 attempt 都在cleanupTimeout中停录、最终拿不到文件关闭指示后停止录屏约 2 秒。这是 README 与 0.1.0 以来的持续建议示例配置中已体现。单元测试如何验证这套行为包的测试 eas.test.ts 用vi.stubGlobal(fetch, ...)伪造了https://api.expo.dev/graphql的 GraphQL 端点按查询文本区分create/state/stop/cancel四类操作并记录每次调用的Authorization/expo-session头与变量覆盖创建入参含appId、platform、deviceIdentifier按平台键写入轮询到ready的全过程与排队提示释放与启动失败/取消后停止的回滚路径EXPO_TOKEN与 eas-cli 登录两条凭据路径断言请求头分别是 Bearer 与expo-session从 app config 解析projectId的各分支含通过expo config求值动态配置连续 502 抖动下最多容忍 3 次失败轮询stateOutages机制target 携带app.appPath时的冲突报错。结合 stub 的node:timers/promises轮询即时返回整条创建 → 轮询 → 就绪 → 停止状态机在单测中可确定性地重放。小结e2e-dev/eas从 0.1.0 的能跑托管模拟器演进到 0.3.0 的生产就绪0.2.0 补齐了与 eas-cli 对齐的免 token 鉴权和projectId自动解析0.2.1 完成依赖与发布产物瘦身0.3.0 随整个框架确立了 Node.js 22.22.3/24.8.0 的运行时门槛与 oxc 自研 TypeScript 加载器。对使用者而言接入成本极低——一个device: easSimulators(...)的配置、一个EXPO_TOKEN或本地eas login、以及按账号上限规划好单会话 40 分钟高优先级 115 分钟的套件时长包内部以明确的INVALID_CONFIG校验、失败即回滚的会话清理、排队/卡死判定和标签化命名把云模拟器的计费与并发风险收敛在可控范围内。更多细节可延伸阅读 EAS Simulators 集成文档、mobile 引擎文档 与 EAS Workflows CI 文档。赞分享测试测试智能体人工智能浏览器控制CLI【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址https://gitcode.com/GitHub_Trending/e2e6/e2e点击查看免费下载相关推荐e2e 集成 EAS Simulators用 e2e-dev/eas 在 Expo 托管模拟器上运行移动端 E2E 测试e2e 集成 EAS Simulators用 e2e dev/eas 在 Expo 托管模拟器上运行移动端 E2E 测试 本文基于当前仓库的 package测试测试智能体人工智能浏览器控制CLIPinchTab E2E 测试套件完全指南从 ./dev e2e 到 Go Runner 的架构与实战PinchTab E2E 测试套件完全指南从 ./dev e2e 到 Go Runner 的架构与实战 PinchTab 的端到端测试套件位于 tests/eexpo-eas-client 演进与实现解析EAS 稳定客户端标识符的跨平台设计与 SDK 对齐之路expo eas client 演进与实现解析EAS 稳定客户端标识符的跨平台设计与 SDK 对齐之路 本文以 Expo 仓库中 packages/expo移动开发前端跨平台原生移动上一篇Qwen-Edit-2509-Multiple-anglesAI图像编辑领域的镜头控制革新下一篇MassTransit代码分析使用Analyzers提升代码质量创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询