执行方法

由于 Appium 驱动程序中实现的命令范围比 W3C WebDriver 规范中定义的命令范围更广,因此 Appium 需要一种方法让客户端库访问这些“扩展”命令。为此,主要有两种策略

  1. Appium 驱动程序定义新的与 W3C 兼容的 API 路由,并且 Appium 客户端会更新以包含对这些新路由的支持。
  2. Appium 驱动程序定义所谓的“执行方法”,这些方法通过重载现有的 Execute Script 命令来提供新功能,该命令已在任何基于 WebDriver 的客户端库(包括所有 Selenium 和 Appium 客户端)中可用。

每种策略都有其优缺点,但最终由扩展作者决定他们希望如何实现新命令。

本指南旨在专门帮助您了解“执行方法”策略。此模式通常用于官方 Appium 驱动程序和其他第三方扩展。以下是如何在 WebDriver 和浏览器自动化世界中设计 Execute Script 命令的示例

await driver.executeScript('return arguments[0] + arguments[1]', [3, 4])
JavascriptExecutor jsDriver = (JavascriptExecutor) driver;
jsDriver.executeScript("return arguments[0] + arguments[1]", 3, 4);
driver.execute_script('return arguments[0] + arguments[1]', 3, 4)
driver.execute_script 'return arguments[0] + arguments[1]', 3, 4
((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0] + arguments[1]", 3, 4);

这里发生的事情是,我们正在定义一个 Javascript 代码片段(技术上是一个函数体)在 Web 浏览器中执行。客户端可以发送参数,这些参数会被序列化,通过 HTTP 发送,最后作为参数提供给函数。在这个例子中,我们实际上是在定义一个加法函数。Execute Script 命令的返回值就是 Javascript 代码片段的返回值!在这个例子中,该值将是数字 7 (3 + 4)。

每个客户端库都有自己的调用命令和向脚本函数提供任何参数的方式,但函数本身(代码片段)始终是一个字符串,并且在所有语言中都是相同的。

在 Appium 的世界中,我们通常不会自动化 Web 浏览器,这意味着此命令并不特别有用。但它确实可以用作对任意命令名称进行编码并提供参数的一种方式。例如,XCUITest 驱动程序 已经实现了一个命令,允许客户端在知道应用程序 ID (bundleId) 的情况下终止正在运行的应用程序。驱动程序使此命令可用的方式是通过执行方法 mobile: terminateApp。用户不是向“Execute Script”命令提供 Javascript 函数,而是提供驱动程序定义的已知字符串。客户端需要了解的另一件事是方法的参数集,这些参数由驱动程序记录。在这种情况下,我们有一个名为 bundleId 的参数,其值应该是对要终止的应用程序 ID 进行编码的字符串。以下是此执行方法的调用方式

await driver.executeScript('mobile: terminateApp', [{bundleId: 'com.my.app'}])
JavascriptExecutor jsDriver = (JavascriptExecutor) driver;
jsDriver.executeScript("mobile: terminateApp", ImmutableMap.of("bundleId", "com.my.app"));
driver.execute_script('mobile: terminateApp', {'bundleId': 'com.my.app'})
driver.execute_script 'mobile: terminateApp', { bundleId: 'com.my.app' }
((IJavaScriptExecutor)driver).ExecuteScript("mobile: terminateApp",
    new Dictionary<string, string> { { "bundleId", "com.my.app" } });

使用 Appium 执行方法与普通 Selenium Javascript 执行相比,有两个重要的区别

  1. 脚本字符串只是一个命令名称;它将由驱动程序文档提供
  2. 提供参数的标准方法是作为单个对象,其中键表示参数名称,值表示参数值。因此,在这种情况下,我们必须同时指定参数名称 (bundleId) 作为参数对象的键,以及参数值 (com.my.app) 作为该键的值。驱动程序可以将参数定义为必需可选

当然,始终参考特定执行方法的文档,以防作者对标准访问方法进行了任何更改。