Webdriver executeScript偶尔不检测动态生成的元素
Webdriver executeScript sporadically not detecting dynamically generated elements
我花了很长很长的时间才弄清楚,我仍然在努力解决这个问题。我试图访问动态生成的元素在网页上使用javascript注入使用硒webdriver。例如:
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次时抛出异常(即使元素是物理存在的)。
为什么会这样?解决办法是什么?如果任何提示/答案是有用的,我一定会投票的。
编辑:我已经把Thread.sleep(500),甚至1000秒等待,每次出现在我的代码中的executeScript()。还是不行
这是(部分)堆栈跟踪:
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)
关于检查CSS类:不需要执行脚本。您可以在纯Java代码中做到这一点。以下是对我有用的:
String cssClass = driver.findElement(By.xpath(xpath)).getAttribute("class");
assertTrue(cssClass.contains("disabledentry"));
对于动态生成的列表,最好使用xPath查找元素。
对于更好的解决方案,您需要说明元素是在哪里动态生成的?它可以在表或ul/li等等。
- 首先,找到父元素的xPath,即表或列表项。
-
然后使用循环为元素的位置创建一个动态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,可以使用下面的教程。你可以试试这个,然后告诉我。欢呼声
使用Selenium,您必须始终意识到,脚本执行可能需要一些时间。如果您遇到有时成功有时失败的情况,请检查Thread.sleep(500)是否对您有所帮助。否则,JUnit可能会在脚本完成之前评估断言。
- 将列表元素动态添加到ul元素中
- 将输入 html 元素动态关联到颜色选取器
- 媒体元素 - 动态加载音频
- 根据其内部元素动态更改 CSS
- 编写脚本以向元素动态添加.current(类似活动类)的场景
- 使用knockoutjs虚拟元素动态创建html部分
- 将JS中的元素动态添加到XUL中
- 如何从jquery中获得元素动态附加的完整表
- 使用jquery向li元素动态添加类
- 点击事件不't在尝试将元素动态添加到<ul>标签
- 使用Knockout.js Issue将元素动态添加到嵌套列表中
- 如何从DOM元素动态禁用popover
- 将样式元素动态插入DOM的最后一种跨浏览器方式
- 无法将元素动态添加到数组中
- 指令如何等待元素'动态插值属性被处理?
- 设置活动元素和非活动元素(动态)
- 是否可以使用JS/PHP为网页中的元素动态分配ID
- 如何制造<光>元素动态调整以填充浏览器窗口的整个宽度
- 基于页面元素动态构建菜单结构
- 向现有元素动态添加删除绑定