@e2e-dev/mobile

中文文档
0.12.7发布于 2026/11/13Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 48.4万

用于e2e代理端到端测试的移动引擎(iOS和Android),以代理端到端设备为基础

中文使用文档
文档目录8 节
  1. 安装
  2. 引擎声明什么
  3. 重放缓存
  4. 这个 device 固定图
  5. 代理工具
  6. 带有原始驱动程序的自定义工具
  7. 秘诀
  8. 文档

@e2e-dev/移动

用于 e2e,在 代理设备:iOS模拟器, Android 模拟器,和连接的电话通过相同的 e2e/engine 订约浏览器引擎 执行。 一个测试写到 screen, (中文(简体) ), expect, (中文(简体) ), app,以及 agent 运行 设备目标不变;无 e2e 核心知道此软件包存在.

安装

运行 npx e2e init 选择 移动(iOS/Android) 设置 以可选的 AI 测试为例。 在macOS和Android上默认使用iOS 其它位置; 更改平台 e2e.config.ts 需要的时候. 或将软件包添加到已有工程中 :

npm install --save-dev e2e @e2e-dev/mobile

agent-device 需要使用 iOS 模拟器运行时间的 Xcode, 或 Android SDK 与一个模范。 电话需要开发者模式和运行者在iOS上签名,或 Android上授权的USB调试(参见 物理装置) (中文(简体) ). 运行 npx e2e doctor 以检查设置 一个跑步.

import type { E2EConfig } from 'e2e';
import { mobile } from '@e2e-dev/mobile';
import { mobileTools } from '@e2e-dev/mobile/tools';
import { gateway } from 'ai';

const iphone = mobile({ platform: 'ios' });
const pixel = mobile({ platform: 'android' });

export default {
  targets: [
    { name: 'iphone', engine: iphone, app: { bundleId: 'Settings' } },
    { name: 'pixel', engine: pixel, app: { bundleId: 'com.android.settings' } },
  ],
  workers: 1,
  agents: {
    default: {
      model: gateway('openai/gpt-6-luna-fast'),
      tools: mobileTools(iphone, pixel),
    },
  },
} satisfies E2EConfig;

一个测试写到 agent, (中文(简体) ), app, (中文(简体) ), screen,以及 device 运行在两个 目标不变。 只有名为平台标签的检查( Q)General 在iOS上, Network & internet (Android)的需要 platforms: ['ios'] 或者说 platforms: ['android'] 在测试.

测试中的应用程序是目标 app;引擎只驱动它. A 类 设备目标需求 bundleId 或者说 appPath数字 :

密钥含义
bundleId软件包、软件包或显示名称 app.open(), (中文(简体) ), app.restart(),以及 app.clearState() 发射新鲜; 尝试没有自行发射.
appPath一个iOS .app 捆绑或安卓 .apk,根据项目根解决。 引擎没有安装它: 套房呼叫 device.installApp() (没有路径,这个构建)每个设备一次,除非设备提供者已经安装了它. 无 bundleId,已安装的捆绑 id 或包是应用程序 app.open() 发射.
launchArguments争辩每一次新推出被绑起的应用程序载体(app.open(), (中文(简体) ), app.restart(), (中文(简体) ), app.clearState():iOS上的流程参数, am start android上的论点。 热身没有通过.
permissions允许每一次新发射 都有固定的应用, { camera: 'grant', location: 'deny', notifications: 'reset' },设置在应用程序开始前,然后放回去 app.clearState() 重置他们.

app.url 尚未在设备目标上支持,并且 mobile({ app }) 财务报告和审定财务报表 其他旧的应用程序选项是 INVALID_CONFIG 在其密钥下命名 app。 。 。 .

mobile() 选项:

选项含义
platform'ios' 或者说 'android'。 。 。 .
device模拟器或模拟器名称或UDID,或连接的手机名称. 名单是池子:每个入口一个工人,一个工人档位 n 开车 nth. Ocondition,平台上每个被启动的装置都是"池",所跑道有槽的也一样多.
session代理设备会话名称, 工人槽前: 槽 n 驱动设备在 <session>-<n>, (中文(简体) ), e2e-<target name>-<n> 默认。 每届1跑.
snapshot'full' (默认,包括静态文本)或 'interactive' (只有可行动节点).
settle在代理方再次观察前, UI 必须在代理方行动后仍然持有毫秒, 默认值 150· ; false 跳过等待。 测试步骤不能解决,除非 device.back()· ; expect 核实结果.
transition对于一个测试的步骤: 毫秒的控件会随着最后一个动作出现或移动, 在操作前到达, 默认 500。只有当键盘可见度不变时,才立即对未移动的控件采取行动。 打开或关闭键盘也使用所余预算. 测试中的屏幕刷新在滚动前等待剩余预算.
videoTouches用于录制移动引擎(不是设备提供者自己录制的), 视频是否绘制代理设备的触摸指示器, 默认 true。 。 。 . false 记录平面屏幕, 并跳过在录音停止后绘制指示器, 在主机守护进程上可以超过 cleanupTimeout。 。 。 .

每个可选 mobile() 值也接受 undefined,所以一个配置通过 device: process.env.E2E_DEVICE 直接通过,没有条件 展开.

引擎声明什么

  • 意见: 无障碍树, 投放到角色词汇中 (监督厅) Button 变成 button, (中文(简体) ), TextField 变成 textbox, (中文(简体) ), Cell 变成 listitem; 机器人 android.widget.TextView 变成 text, (中文(简体) ), EditText 变成 textbox, (中文(简体) ), Switch 变成 switch),带有矩形,取景口,以及 请求时将所有安全字段涂上像素 。 元素标识符 (单位:千美元)ABOUT, (中文(简体) ), android:id/title)是节点的 testId,怎样 getByTestId 火柴。 比赛.
  • 行动:自拍、双自拍、长按、填充、清空、检查/不检查(何时) 树会像两个平台的开关一样暴露检查状态, 注重可编辑字段, Enter,单字符键,在节点内切换,拖动. selectOption, (中文(简体) ), setInputFiles, (中文(简体) ), scrollIntoView, (中文(简体) ), secondaryTap, (中文(简体) ), modifiers 打开 tap 或者说 doubleTap,聚焦于控件,而其他密钥失败 UNSUPPORTED_CAPABILITY。 。 。 .
  • 地点: 每一个 screen 查询,加上代理设备选择器 device.locator('role=navigation-bar id=General')。 。 。 .
  • 视图口切换, (中文(简体) ), app.back(), (中文(简体) ), app.restart(), (中文(简体) ), app.clearState(),以及 尝试文物目录下的已编辑截图: 在保存文件前,每个安全字段被漆成黑色,并且 a 不能编辑的截图不会被写入 。 没有 state 能力:a 模拟器没有便携式会话快照 .
  • App 类型: 目标与 app.bundleId 或者说 app.appPath 是一个 native-app 因此,一个便携式套房可以 requires: ['native-app']。 。 。 .

重放缓存

跑步缓存 agent.act 并有一个设备 没有地址栏。 这个引擎报告一个反正: <bundle id> / <screen title>,标题读取了 iOS 上的导航栏和崩溃 工具栏。 应用程序身份是位置的一部分,所以两个应用程序与 a"General"屏幕从不共享主播. 记录的一步 com.apple.Preferences / General 只在应用程序在上面时重放 屏幕,并保留在水龙头、键入和滚动回放中的流程 零型号呼叫。 声明 app.bundleId 打电话 app.open() 首先,步骤开始 同样的屏幕,和 宁可使用语法而不是 open_app 步骤中的工具:工具调用是 重放间隙.

这个 device 固定图

决定性设备管理,记录为 device.<method> 步骤。 导入 test 从此软件包中输入.

import { test } from '@e2e-dev/mobile';
import { expect } from 'e2e';

test('shows the version in dark mode', async ({ agent, device, screen }) => {
  await device.setAppearance('dark');
  await agent.act('go to General, then About');
  await expect(screen.getByRole('button', /^iOS Version/)).toBeVisible();
  await expect(device.locator('role=navigation-bar id=About')).toBeVisible();
});

方法: setNetwork, (中文(简体) ), setAirplaneMode, (中文(简体) ), setPermission, (中文(简体) ), setLocation, (中文(简体) ), clearLocation, (中文(简体) ), setAppearance, (中文(简体) ), setOrientation, (中文(简体) ), fold, (中文(简体) ), setBiometrics, (中文(简体) ), enrollBiometrics, (中文(简体) ), installApp, (中文(简体) ), openApp, (中文(简体) ), openLink, (中文(简体) ), closeApp, (中文(简体) ), clearKeychain, (中文(简体) ), foregroundApp, (中文(简体) ), home, (中文(简体) ), back, (中文(简体) ), alert, (中文(简体) ), dismissKeyboard, (中文(简体) ), clipboard, (中文(简体) ), setClipboard,则 locator 访问者.

device.unstable_raw 是原始驱动进程,因为方法没有 掩护 内容 client 电话不是步骤:报告并追踪, 缓存不会重放它们,它们的论点会到达驱动程序未编辑的, 没有什么等待 屏幕解决。 工后再读 处理会话 INVALID_STATE。它可以在任何释放中改变 (单位:千美元)参考文献) (中文(简体) ).

setNetwork('offline') 财务报告和审定财务报表 setAirplaneMode(true) 仅是Android。 一个iOS 模拟器共享Mac的网络,模拟器只能改变其状态 栏,因此在iOS上都失败了 UNSUPPORTED_CAPABILITY; 返回在线 在那里什么都没有做, 所以共享清理钩通过。 关于Android, setNetwork('offline') 单独关闭Wi-Fi, 这样应用程序就可以在线 过细胞; setAirplaneMode(true) (Android 11 或以后)拿它来 离线.

installApp(appPath, { app, reinstall }) 在设备上加一个构件 测试,用于升级和新安装路径 app.appPath 无法 运算. 平面安装取代二进制并保存其数据; reinstall: true 删除名为 app (默认:被绑定的app)首先. 它决心 捆绑的id或软件包 openApp 建筑由, 否则 app 传入; 未报告身份和身份 app失败 ENGINE_FAILURE。 。 。 . openApp 使用一个应用id, 永远没有联系; openLink 在导航规则下打开一个.

代理工具

@e2e-dev/mobile/tools 出口 mobileTools(...engines)数字 : open_app, (中文(简体) ), swipe (free-form,以逻辑像素表示),并 alert (接受或驳回) 系统警报。 这至少需要一个引擎。 通过每个设备引擎 配置声明: 工具名称是固定的, 所以两个包无法合并, 而 将每个呼叫发送到正在运行的引擎。 工具为 探测到这些引擎的平台, 所以一个混合网络和装置的套房 目标可以把包交给一个特工 tools。 。 。 .

带有原始驱动程序的自定义工具

unstable_deviceSession(...engines) 从 @e2e-dev/mobile/tools 给出一个 运行尝试的原始驱动程序会话的自定义工具, 用于 e2e 能力 尚未结束。 它的客户端与引擎的守护进程,租赁,和 届会。 客户端输入为 DeviceSessionClient从 @e2e-dev/mobile。 。 。 . 此 API 可以在任何发行中更改, 如 device.unstable_raw (单位:千美元)参考文献) (中文(简体) ).

秘诀

type_secret 财务报告和审定财务报表 screen.getByLabel(...).fill(secret) 填充公开的秘密 在设备上: 证书密码进入安全字段, a secrets 条目 输入可编辑的输入。 模型从不看价值,截图是 其余的尝试被扣留.

文档

完整文档生活于 e2e.com/文档。 。 。 .

版本与发布记录

@e2e-dev/mobile 共发布 54 个版本,首次发布于 2026/09/29;过去 12 个月发布了 54 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.12.7latest2026/11/13今天
0.12.7-nightly-20261113123338nightly2026/11/13今天
0.12.7-nightly-202611130943592026/11/13今天
0.12.7-nightly-202611130302072026/11/13今天
0.12.7-nightly-202611120302002026/11/121 天前
0.12.7-nightly-202611100302172026/11/103 天前

其他发布通道:canary → 0.8.0-canary-20260929180659,nightly → 0.12.7-nightly-20261113123338。

关于 @e2e-dev/mobile 的常见问题

@e2e-dev/mobile 是什么?

用于e2e代理端到端测试的移动引擎(iOS和Android),以代理端到端设备为基础

如何安装 @e2e-dev/mobile?

在项目目录运行 npm install @e2e-dev/mobile,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:e2e(>=0.22.1 <1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@e2e-dev/mobile 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@e2e-dev/mobile 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@e2e-dev/mobile 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.22.3 || >=24.8.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@e2e-dev/mobile 可以商用吗?

@e2e-dev/mobile 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@e2e-dev/mobile 的下载量有多少?

根据 npm 官方下载统计,@e2e-dev/mobile 在 2026/10/13 – 2026/11/11 这 30 天内被下载 483,891 次,日均约 16,130 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@e2e-dev/mobile 还在维护吗?

最新版本 0.12.7 发布于 2026/11/13(今天);至今共发布 54 个版本,其中过去 12 个月发布了 54 个;首次发布于 2026/09/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。