Appium 点击事件后。如何等待下一个 page 加载完成?或者等待某几个元素种出现其中一个?

boyyao · 2017年01月11日 · 最后由 lf 回复于 2017年01月14日 · 1622 次阅读

比方说点击登录按钮后。因为服务器验证登录和网络延迟需要等待一段事件后判断是否登录成功?或者是其他状态。比如出现验证码。或者其他提示操作之类的。

我如何判断出现的是什么提示?并且做后续操作?

已经用
CalculatorSession.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(2)); 延迟 2 秒。
但是我后续用
CalculatorSession.FindElementByName("确定").Click();

if( CalculatorSession.PageSource.Contains("登录成功"))
CalculatorSession.FindElementByName("登录成功").Click();

这样的方法感觉在执行 if( CalculatorSession.PageSource.Contains("登录成功")) 的时候并没有延迟。而是直接非 false 了。。
当然这里只是一个例子。出现的可能会是登录成功。密码错误。需要验证码。错误过多。账号被精等等其他内容。我需要逐一处理。。当然由于网络延迟的不确定性。所以不希望直接 steep

PS。也无法通过判断一个 textbox 中的文字来判断状态。因为可能每种状态返回的 page 不一样。

共收到 7 条回复 时间 点赞

java 实现
写一个类,继承 FluentWait,例如:
public class AppiumDriverWait extends FluentWait
构造方法:
public AppiumDriverWait(AppiumDriver driver, long timeOutInSeconds) {
this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT);
}
然后在类里面用内部类 ExpectedCondition,实现 apply 方法查找元素
public static WebElement findAndWait(AppiumDriver driver, final By by, long timeout) {
WebElement ele = new AppiumDriverWait(driver, timeout)
.until(new ExpectedCondition() {
public WebElement apply(AppiumDriver d) {
return d.findElement(by);
}
});
return textView;
}
最后在你的脚本里面用如下语句查找页面元素
AppiumDriverWait.findAndWait(driver, By.xpath("xpath"), 60L);
60 秒内找到就返回 webelement,找不到就报 RuntimeException。

不过这是比较老的方法了,据说现在 selenium 最新 jar 包是 java8 平台上的了,java8 支持函数闭包,应该会有更简洁的方法实现此功能。没用过 java8,也没用过 selenium3.0 纯猜测。

我现在临时解决办法是登录后直接 steep 60 秒。然后看 PageSource 种包含的内容来判断。但是这样每次操作也需要 60 秒。。
我希望是能更加智能的效率的判断 4 种状态哪一种出现了。然后我可以分别处理。不知道能不能实现?

嗯。有更加简洁的其他办法么?我尝试过用 try 的方式。。但是这种方式判断每个元素存在都需要等待响应的时间。假如我每个元素等待 60 秒后没出现抛出异常后在检查其他元素。假设我点击登录按钮后可能出现 1,正常没出现任何多余元素 2,马上出现密码错误元素,3,出现验证码元素,4,登录后过出现账号异常元素。这样就需要 4 分钟来确定是否正常登录了,感觉效率很低。并且程序中用异常而不是其他控制语句来实现逻辑感觉怪怪的。。。 有没有办法判断点击登陆后 4 种状态出现了哪一种的方法?

#2 楼 @boyyao 你登录后直接判断一下只有登录成功才会显示的元素不就好了?比如登录后可以看到退出按钮,那就 AppiumDriverWait.findAndWait(driver, By.xpath("退出按钮"), 60L);,如果登录后 1 秒退出按钮就出现了,这个语句只需要 1 秒就执行完了。不明白你为什么要在一个脚本里连续判断 4 个元素......

在 findAndWait 内部类 ExpectedCondition,实现 apply 方法执行 js,通过 js 来判断页面是否加载完成。Ext.Ajax.isLoading() 是判断 ext 的,你可以换成自己想要的页面加载完成判断。
boolean isajax = (Boolean) ((JavascriptExecutor) driver).executeScript("return Ext.Ajax.isLoading()");
return (isajax==false);

#4 楼 @uniquet 你的提示的确是一个方法。但是还是有点问题。假设一个登录没成功。那我需要知道是为什么没成功。假设有 4 种没成功的状态。我还是需要判断 4 次。等待最多 4 次超时或者异常才能确定是什么问题造成的没登录成功。
其实这个问题只是一个比较容易理解的假设。。实际应用也并不是登录。我只是想知道。有什么简洁有效的方法能判断有没有出来元素。或者出来了什么元素。。。另外说起验证码突然想起一个问题。appium 能在 app 种出现验证码后吧验证码图片拿出来么?比如我需要做验证码识别。。
if()

#5 楼 @boyyao 哦,你这个目标属于开发一个复杂的程序,而不是编写测试脚本了。没干过正统的软件开发工作,就不瞎说免得误导你了。
验证码的话,appiumdriver 不是可以截图吗?先整个屏幕截图,之后想办法获得验证码图片所处的位置坐标,再利用 java 处理图片的工具包把验证码所在的区域截出来就好了。(纯理论,没有验证过......)
这里有个 python 的例子,可以看看https://testerhome.com/topics/1389 ,java 应该也有类似的工具包的。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册