我花了很长时间才弄明白,但我仍然在努力解决这个问题。 我试图使用selenium webdriver使用javascript注入访问网页上动态生成的元素。 例如:
String hasclass = js.executeScript("return document.getElementById('additional-details').children[0].children[0].children["
+ k + "].children[0].classList.contains(\"results-execs-name\")").toString();
现在当我在firefox控制台中执行此脚本时,它可以正常工作。但是当在webdriver 5-6中运行10次时,该行抛出异常(甚至认为元素IS存在于物理上)。
为什么会这样?最新解决方案是什么?如果有任何提示/答案有用,我肯定会赞成。
编辑:
我已经放入Thread.sleep(500),甚至在我的代码中每次出现executeScript()之前等待1000秒。仍然没有用。
这是(部分)堆栈跟踪:
org.openqa.selenium.WebDriverException: document.getElementById(...).children[0].children[0] is undefined
Command duration or timeout: 169 milliseconds
Build info: version: '2.39.0', revision: 'ff23eac', time: '2013-12-16 16:12:12'
System info: host: 'rahulserver-PC', ip: '121.245.92.68', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_17'
Session ID: 747d2095-09f3-48b9-a433-59c5e334d430
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=XP, databaseEnabled=true, cssSelectorsEnabled=true, javascriptEnabled=true, acceptSslCerts=true, handlesAlerts=true, browserName=firefox, webStorageEnabled=true, nativeEvents=false, rotatable=false, locationContextEnabled=true, applicationCacheEnabled=true, takesScreenshot=true, version=31.0}]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:193)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:554)
at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:463)
at Scraper.main(Scraper.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
答案 0 :(得分:1)
关于检查CSS类:不需要为此执行脚本。您可以在纯Java代码中执行此操作。这对我有用:
String cssClass = driver.findElement(By.xpath(xpath)).getAttribute("class");
assertTrue(cssClass.contains("disabledentry"));
答案 1 :(得分:1)
对于动态生成的列表,最好使用 xPath 来查找元素。
为了获得更好的解决方案,您需要说明元素的动态生成位置? 它可以位于表或 ul / li 中,依此类推。
然后使用循环创建动态xPath到元素的位置。代码段如下:
String xPath_1 = ".//li[@class='item drop-shadow tiny-shadow' and position()=";
String xPath_2 = "]//div[@class='item-inner']//a";
String finalxPath = xPath_1 + i + xPath_2;
创建一个名为fluentWait的方法来等待元素存在而不是使用线程休眠。线程睡眠不可靠,这是测试失败的原因。此外,fluentWait方法将忽略 NoSuchElementException (您可以向列表添加更多内容,例如 StateStateElementException )。代码段如下:
public void fluentWait(final By by)
{
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(60, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(by);
}
});
}
然后用动态生成的xPath调用此方法,如下所示:
fluentWait(By.xpath(finalxPath ));
要了解xPath,您可以使用以下Tutorial。你可以尝试一下,让我知道。干杯
答案 2 :(得分:0)
使用Selenium你总是要注意,脚本执行可能需要一点时间。如果您的情况有时会成功并且有时会失败,请检查Thread.sleep(500)是否可以帮助您。否则JUnit可能会在脚本完成之前评估断言。