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

boyyao · 发布于 2017年01月11日 · 最后由 uniquet 回复于 2017年01月14日 · 807 次阅读

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

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

已经用
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 条回复
Ffd003

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纯猜测。

96
boyyao · #2 · 2017年01月12日 作者

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

96
boyyao · #3 · 2017年01月12日 作者

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

Ffd003

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

96
boyyao · #5 · 2017年01月14日 作者

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

8447

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

Ffd003

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

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