我不确定我的问题是否有任何解决方案,但遗憾的是我没有找到任何关于它的文章或信息。
情况如下。我们有一个大量使用jQuery的站点,并且有一项服务可以在每隔5或10秒刷新一部分站点。由于这一半的时间我从WebDriver得到了这个错误:
"Element not found in the cache - perhaps the page has changed since it was looked up"
根据互联网,当DOM树在初始化WebElement的时刻和我想用它来执行时(例如点击事件)之间发生了变化时,我收到了这个错误。
根据我们的开发人员的说法,我们的jquery解决方案有一个变量,用于控制是否刷新页面。所以,要解决我的问题,我必须覆盖这个变量。我必须以这种方式覆盖这个变量,jQuery将能够理解它 - 我的意思是在同一个实例中,如果这个定义在这个上下文中是正确的。
所以,我想问一下是否可能?如果是这样,我想问一个小例子。
提前致谢!
安德拉什
答案 0 :(得分:4)
我只能同意Aleh。
使用JavaScriptExecutor
是处理此类问题的唯一方法。
我遇到了jQuery jNice库的问题,无法找到任何其他解决方案。
以下是Java中用于填充文本字段的示例:
JavascriptExecutor js = (JavascriptExecutor) webDriver;
js.executeScript("document.getElementsByName('<field_name_gets_here>')[0].value='" + your_value + "'");
答案 1 :(得分:2)
如果您提到的JavaScript变量是全局的,那么是 - 您可以通过从Selenium执行JavaScript来覆盖它。例如,如果该变量被称为doRefresh
,则可以通过执行JS来覆盖它:来自Selenium的doRefresh = false;
。
如果该变量不是全局变量,则上述变量不起作用。但是,听起来有问题的元素可能是通过ajax动态加载的 - 在这种情况下,xhr
对象是全局的,你可以改为访问它。
因此,首先您可以制作xhr
对象的本地副本,然后通过从Selenium执行JavaScript来覆盖原始对象(有效地禁用它):
// create a copy of the xhr object for later use
var xhrHolder = window.XMLHttpRequest;
// overwrite the original object to disable it
window.XMLHttpRequest = {};
然后像往常一样通过Selenium找到你的元素。继续进行测试。
完成后,您可以通过从Selenium执行JavaScript来将xhr对象放回原位(以便页面可以继续刷新并执行ajax):
// put the xhr object back
window.XMLHttpRequest = xhrHolder;
答案 2 :(得分:1)
您可以尝试我的方法 - 我为可能加载页面的情况创建了自己的包装器。下面的代码试图在循环中搜索元素三秒钟(可配置)。顺便说一句,下面的driver
变量是WebDriver
private WebElement foundElement;
public WebElement find(By by){
for (int milis=0; milis<3000; milis = milis+200){
try{
foundElement = driver.findElement(by);
}catch (Exception e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
return foundElement;
}
后来在代码中:
WebElement submitButton = find(By.id("submitNewBid"));
submitButton.click();
答案 3 :(得分:0)
我相信这是可能的。 c#的示例:
((IJavaScriptExecutor)driver).ExecuteScript("window.$('.class').data('var') = 0;")