如何快速获取所有UI元素



我有一个任意打开的应用程序(可以是android或ios),我想从UI获得所有元素。

简单的方法是:

appiumWebDriver.findElements(By.xpath("//*")) // this works and returns elements but is slow

然而,这是缓慢和不鼓励的。使用By.className或其他平台相关策略会更快。但是,我不确定如何编写通配符选择器。

appiumWebDriver.findElements(By.className("*")) // this does not work and returns 0 elements

我不介意在这里区分iOS或Android应用程序并编写特定的代码,但我想要一种快速可靠的方式来获得所有显示的元素。

最快的方法是使用driver.getPageSource()命令。

我最后做了一些速度测试。

对于Android, driver.getPageSource()可以比使用XPath快3到6倍。对于我使用的演示应用程序,获取页面源大约需要0.2秒,使用XPath获取所有元素大约需要0.3到0.6秒。

对于iOS, driver.getPageSource()可以比XPath或谓词字符串快10到15倍。对于我使用的演示应用程序,获取页面源大约需要1-3秒,使用XPath或谓词字符串获取元素大约需要20-30秒。谓词字符串比XPath快一点。

有两点需要注意:

  1. 无论你使用什么方法,对于iOS,它都会给出页面上的所有元素。对于Android,它只会给出那些在屏幕上可见的元素。如果页面是一个可滚动的页面,在屏幕下方有更多的元素,那么这些元素将不会被获取。您需要向下滚动,然后再次运行命令来获取这些元素。

  2. getPageSource()将把XML作为字符串提供给您。然后,您可以使用任何XML解析器来解析它并将其用于您的目的。

希望这对你有帮助。

下面是我用来测试iOS和Android的代码。

public static void main(String[] args) throws Exception {
AppiumDriver driver;
// -> Initialize Android driver
driver = CreateDriverSession.initializeDriver("Android");
driver.findElement(AppiumBy.accessibilityId("Views")).click();
long time1 = System.currentTimeMillis();
driver.getPageSource();
long time2 = System.currentTimeMillis();
System.out.println("GET PAGE SOURCE TIME IN MILLIS" + (time2 - time1));
time1 = System.currentTimeMillis();
driver.findElements(AppiumBy.xpath("//*"));
time2 = System.currentTimeMillis();
System.out.println("XPATH TIME IN MILLIS" + (time2 - time1));
// -> Initialize iOS driver
driver = CreateDriverSession.initializeDriver("iOS");
time1 = System.currentTimeMillis();
String page = driver.getPageSource();
time2 = System.currentTimeMillis();
System.out.println("GET PAGE SOURCE TIME IN MILLIS" + (time2 - time1));
time1 = System.currentTimeMillis();
List<WebElement> elementsUsingXPath = driver.findElements(AppiumBy.xpath("//*"));
time2 = System.currentTimeMillis();
System.out.println("XPATH TIME IN MILLIS" + (time2 - time1));
time1 = System.currentTimeMillis();
List<WebElement> elementsUsingPredicateString = driver.findElements(AppiumBy.iOSNsPredicateString("TRUEPREDICATE"));
time2 = System.currentTimeMillis();
System.out.println("PREDICATE STRING TIME IN MILLIS" + (time2 - time1));
System.out.println("PAGE SOURCE = ");
System.out.println(page);
System.out.println("ELEMENTS USING XPATH = ");
for (WebElement element : elementsUsingXPath) {
System.out.println(element.getText());
}
System.out.println("ELEMENTS USING PREDICATE STRING = ");
for (WebElement element : elementsUsingPredicateString) {
System.out.println(element.getText());
}
}

需要平台特定代码。对于iOS,你可以使用:

appiumWebdriver.asInstanceOf[IOSDriver].findElements(AppiumBy.iOSNsPredicateString("TRUEPREDICATE"))

最新更新