gpt4 book ai didi

页面刷新期间的 selenium.common.exceptions.StaleElementReferenceException

转载 作者:行者123 更新时间:2023-12-03 06:26:30 25 4
gpt4 key购买 nike

页面包含一些数据(只有几行的表)。有“刷新”按钮,可以重新加载和重新绘制页面上的某些元素,而无需重新加载静态数据(ajax)。

我正在尝试为该页面创建正确的测试,但有时会出现 StaleElementReferenceException。

我的代码(python):

from selenium import webdriver
browser=webdriver.Firefox()
browser.get('http://mytisite')
browser.implicitly_wait(10)
browser.find_element_by_id('start').click()
while browser.find_element_by_id('status').text!='Done':
browser.find_element_by_id('refresh').click()
for row in browser.find_elements_by_class_name('datarow'):
if not is_correct(row.text):
print "incorrect"
time.sleep(10)

5 次迭代中的 1 次在“if not is_ Correct(row.text)”行失败:

selenium.common.exceptions.StaleElementReferenceException: 
Message: u'Element not found in the cache - perhaps the page
has changed since it was looked up' ; Stacktrace: Method
fxdriver.cache.getElementAt threw an error in
resource://fxdriver/modules/web_element_cache.js

主要问题:页面已经包含以前的数据,因此我在 ajax 刷新和 find_elements_by_class_name('datarow') 的 webdriver 元素查询之间发生竞争。

如何正确解决ajax刷新和webdriver之间的竞争?谢谢。

最佳答案

恐怕我无法帮助您进行 python 绑定(bind)。不过,我可以帮助您提供有关 WebDriver 的一般建议和一些 Java 片段,这些片段可能会帮助您(其他人)找到相应的 Python 版本。在 Selenium 中,您可以做很多处理 AJAX 的事情。

<强>1。隐式等待 - 这将告诉 Web 驱动程序在一段时间内轮询 DOM。

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

<强>2。显式等待 - 我更喜欢这些!人们可以将它们与隐式等待结合使用。您可以告诉 WebDriver 等待特定条件。您需要使用 WebDriverWait 来使用显式等待。

WebDriverWait wait = new WebDriverWait(driver, 60/*timeout in seconds*/);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("refresh")));

ExpectedConditions免费提供了很多等待条件,我发现它非常有用。

如果我用 Java 编写上面的代码片段,我会做下面的事情。注意我是在编辑器中编写的,所以它应该可以编译。我想这会让您对 WebDriverWait 的使用有所了解。

WebDriverWait wait = new WebDriverWait(driver, 60/*timeout in seconds*/);
ExpectedCondition<Boolean> untilIFindStatus = ExpectedConditions
.elementToBeSelected(By.id("status"));
while (wait.until(untilIFindStatus)) {
WebElement refresh = wait.until(ExpectedConditions
.elementToBeClickable(By.id("refresh")));
refresh.click();
List<WebElement> allRows = wait.until(ExpectedConditions
.presenceOfAllElementsLocatedBy(By.className("datarow")));
for (WebElement row : allRows) {
if (row.getText().equals("awesome"))
System.out.println("do something");
}
}

最后,根据我的经验,许多现代 AJAX 应用程序都使用 jQuery。几年来我已经成功地使用 jQuery.active 标志来检查页面是否已加载。您可以将其与纯 JavaScript document.readyState 结合起来。这是我在 AJAX 应用程序每次“点击”后等待的一般方法。

ExpectedCondition<Boolean> jQueryActive_toBeZero = new ExpectedCondition<Boolean>()   {
public Boolean apply(WebDriver driver) {
try {
return ((Long) jsExecutor
.executeScript("return jQuery.active") == 0) ? true
: false;
} catch (WebDriverException e) {
log.debug("It looks like jQuery is not available on the page, skipping the jQuery wait, check stack trace for details");
return true; //skip the wait
}
}
};
ExpectedCondition<Boolean> document_readyState_toBeComplete = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return jsExecutor.executeScript("return document.readyState")
.toString().equals("complete") ? true : false;
}
};
wait.until(jQueryActive_toBeZero);
wait.until(document_readyState_toBeComplete);

关于页面刷新期间的 selenium.common.exceptions.StaleElementReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16008302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com