我有一个相当基本的反应组件,它会渲染一个带有包含数字的span的按钮,以及一个yadda / mocha测试。
有时测试因StaleElementReference而失败 - 这似乎发生在组件更新缓慢时,所以
driver.findElement(By.css('.button-counter')).then(function(counter) {
在元素更新之前执行,然后自然
counter.getText()
失败。
似乎常见的方法是在实际测试失败之前尝试多次重新获取元素(就像它已经完成here);问题是,在我的情况下,无论我等多久,我总是得到陈旧元素的引用;感觉像driver.findElement
缓存某个地方的第一个结果,并且总是返回当前测试用例运行中的后续提取。
我在某些时候有以下方法,应该有效,但不知怎的,我仍然得到StaleElementReferences:
function waitForElementWithText(driver, cssSelector, txt, attempts) {
if (!attempts) {
attempts = 3;
}
// first wait for element to be present
return driver.findElement(By.css(cssSelector)).then(function(found) {
// now wait for it to be visible
driver.manage().timeouts().implicitlyWait(300); // we need this to be faster now
driver.wait(function() {
return found.isDisplayed().then(function(visible) {
// First wait for it to become visible
if (visible) {
// Then wait for text to be populated
return found.getText().then(function(gotTxt) {
return gotTxt === txt;
}, function(err) {
if (attempts > 0) {
return waitForElementWithText(driver, cssSelector, txt, attempts--);
}
throw err;
});
}
driver.sleep(300); // give it a break
return false;
}, function(err) { /* err hnd */
if (attempts > 0) {
return waitForElementWithText(driver, cssSelector, txt, attempts--);
}
throw err;
});
}, function(err) {
if (attempts > 0) {
return waitForElementWithText(driver, cssSelector, txt, attempts--);
}
throw err;
});
// restore implicit wait
driver.manage().timeouts().implicitlyWait(10000);
}, function(err) { /* err hnd */
if (attempts > 0) {
return waitForElementWithText(driver, cssSelector, txt, attempts--);
}
throw err;
});
}
现在我只是在做第一个findElement之前添加了1秒的睡眠,但当然这是次优的。 那么有一些推荐的处理这种情况的方法吗?或者我做错了什么?
提前致谢!
答案 0 :(得分:1)
除非绝对必要,否则最好不要将WebElement引用存储到变量中。相反,存储选择器并在需要时使用选择器检索元素。这应该可以缓解大部分或全部StaleElementExceptions。