ExpectedConditions.or函数异常排查(Java+Selenium3.9)
Selenium 3.9中ExpectedConditions.or()失效的坑与解决办法
最近在做电商网站购物车的自动化测试时,遇到了一个挺棘手的小问题,跟大家分享下整个排查和解决的过程:
场景还原
这个电商网站的购物车区块会根据状态动态改变ID:
- 购物车为空时,区块ID是
empty-basket - 购物车有商品时,区块ID变为
basket
我用Java结合Selenium 3.9,定义了两个对应的元素定位器:
@FindBy(how = How.CSS, using = "#empty-basket > section") private WebElement conteneur_panier_vide; @FindBy(how = How.CSS, using = "#basket > section:nth-child(1)") private WebElement conteneur_panier_non_vide;
本来想通过ExpectedConditions.or()来等待其中一个元素加载完成,确保购物车区块结构正常,代码是这么写的:
this.wait.until( ExpectedConditions.or( ExpectedConditions.visibilityOf(conteneur_panier_vide), ExpectedConditions.visibilityOf(conteneur_panier_non_vide) ) );
结果执行直接报了超时错误:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for at least one condition to be valid
更奇怪的是,我单独等待空购物车的元素,或者只把单个条件放进or()里,代码都能正常找到元素。这说明只要or()里混了一个当前不存在的元素,整个函数就直接失效了,完全不符合“满足任一条件就返回”的预期逻辑。
问题根源
折腾了半天终于搞明白:调用or()的时候,页面上的购物车区块(不管是空还是非空的)还没加载出来!因为Selenium的@FindBy是懒加载机制,第一次引用元素时才会去DOM里查找,这时候两个元素都还没初始化,or()里的条件根本没法正确判断,直接就触发超时了。
解决办法
其实很简单,先加一步等待,确保页面已经加载到购物车页面,也就是等URL包含购物车的地址,再去判断元素可见性:
// 先等页面跳转到购物车页面,确保区块已经存在于DOM中 this.wait.until(ExpectedConditions.urlContains(MY_CART_URL)); // 再等待任一购物车区块可见 this.wait.until( ExpectedConditions.or( ExpectedConditions.visibilityOf(conteneur_panier_vide), ExpectedConditions.visibilityOf(conteneur_panier_non_vide) ) );
这样一来,在判断元素可见性之前,购物车的两个区块至少有一个已经出现在DOM里了,or()函数就能正常工作,不会再超时啦。
内容的提问来源于stack exchange,提问作者SzmaKS
相关产品推荐
相关产品推荐

