Appium iOS 真机未实现 push_file?& 如何通过 libimobiledevice or ios-deploy 关闭指定 app

骆天涯 · 2018年05月18日 · 最后由 骆天涯 回复于 2018年05月21日 · 1786 次阅读

环境说明

操作系统:Mac OS 10.13.4
设备:iPhone 6 / iOS 10.3.3
Python:3.6.5
Appium:1.8.0

问题

  1. Appium 的文档中有关于 push_file 的接口说明Push File,但是没有说明/path/to/device/foo.bar 具体的例子,想请教有成功在 iOS 真机上执行成功的吗?

  2. 查了一些资料(比较老了)说只在模拟器上实现了。但其实 Appium 使用的 ifuse 是可以在真机上完成 push_file 的操作的,如果没有实现真机,不知道出于什么考虑没有实现这个功能?

  3. 另外,因为我没有对 UI 操作的需求,所以可以不用 Appium。我也用 ios-deploy 和 ifuse 完成了大部分功能。但是没有办法通过命令行退出 APP,请教有什么工具可以吗?

附加信息说明

我的方法:

driver.push_file('image_0.txt', 'test')

对于 path,尝试了如下 3 种写法:

/Documents/xx/image_0.txt
Documents/xx/image_0.txt
image_0.txt

image_0.txt 没有报错,但是没有在沙盒中找到 image_0.txt,其他两者均报错

Updated 5.22

  1. push_file 确认是可以在真机上运行,我怕在 appium-xcuitest-driver 中找到了 pushFileToRealDevice 函数(就是二楼大大贴的代码),调用的是 ifuse commandline。
  2. 写对文件目录以后 appium 可以 push_file,然后 pull_file(pushed_file) 可以读到正确的数据。但是出现的问题是没法在沙盒上找到写入的数据,已提 issue 给 appium,等待答复中~

答复如下:

By default the file is copied into the global media folder. If you want to put the file into the particular application container then the following target format should be used: @bundleId/. Read https://github.com/appium/appium-xcuitest-driver/blob/ed9740894ebf634789feb95e70c90f5b73f144e8/lib/commands/file-movement.js#L97for  more details.

即:默认写入的是 media 文件夹,如果需要读写沙盒,要写成@com.xxx.xx.xxx/Documents/xxx.xx 这种格式,带上@bundleId/,再加上沙盒内的路径。亲测可用。

共收到 3 条回复 时间 点赞

/**
 * Save the given base64 data chunk as a binary file on the device under test.
 * ifuse/osxfuse should be installed and configured on the target machine in order
 * for this function to work properly. Read https://github.com/libimobiledevice/ifuse
 * and https://github.com/osxfuse/osxfuse/wiki/FAQ for more details.
 *
 * @param {Object} device - The device object, which represents the device under test.
 *                          This object is expected to have the `udid` property containing the
 *                          valid device ID.
 * @param {string} remotePath - The remote path on the device. This variable can be prefixed with
 *                              bundle id, so then the file will be uploaded to the corresponding
 *                              application container instead of the default media folder, for example
 *                              '@com.myapp.bla/RelativePathInContainer/111.png'. The '@' character at the
 *                              beginning of the argument is mandatory in such case.
 * @param {string} base64Data - Base-64 encoded content of the file to be uploaded.
 */
async function pushFileToRealDevice (device, remotePath, base64Data) {
  await verifyIFusePresence();
  const mntRoot = await tempDir.openDir();
  let isUnmountSuccessful = true;
  try {
    let dstPath = path.resolve(mntRoot, remotePath);
    let ifuseArgs = ['-u', device.udid, mntRoot];
    if (remotePath.startsWith(CONTAINER_PATH_MARKER)) {
      const [bundleId, pathInContainer] = await parseContainerPath(remotePath, mntRoot);
      dstPath = pathInContainer;
      log.info(`Parsed bundle identifier '${bundleId}' from '${remotePath}'. ` +
               `Will put the data into '${dstPath}'`);
      ifuseArgs = ['-u', device.udid, '--container', bundleId, mntRoot];
    } else {
      verifyIsSubPath(dstPath, mntRoot);
    }
    await mountDevice(device, ifuseArgs);
    isUnmountSuccessful = false;
    try {
      if (!await fs.exists(path.dirname(dstPath))) {
        log.debug(`The destination folder '${path.dirname(dstPath)}' does not exist. Creating...`);
        await mkdirp(path.dirname(dstPath));
      }
      await fs.writeFile(dstPath, Buffer.from(base64Data, 'base64').toString('binary'), 'binary');
    } finally {
      await exec('umount', [mntRoot]);
      isUnmountSuccessful = true;
    }
  } finally {
    if (isUnmountSuccessful) {
      await fs.rimraf(mntRoot);
    } else {
      log.warn(`Umount has failed, so not removing '${mntRoot}'`);
    }
  }
}
恒温 回复

多谢,ifuse 的命令行实现我已经尝试并验证可行了~可以看我写的附加信息-3~我想确认是否可以完全通过 appium 接口来进行全部测试流程~如果最终确认不可行,我会采用两者结合的方法~~

4楼 已删除
骆天涯 关闭了讨论 05月22日 14:42
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册