click()
调用做出响应,其中单击有时会激活元素背后的行为(加载新页面),有时却无法激活。由于click()
不返回任何内容,因此我无法捕获那些驱动程序没有进入新页面的情况。这是一个代码段:
因此,我正在找到链接,检查链接是否已启用并具有正确的名称,然后单击它。下一步有时会超时(我将驱动程序设置为等待10秒后才超时),因为未加载新页面。有时候,它工作正常。
有问题的页面是基于JavaScript的,并使用Ext JS进行页面的呈现。
click()
不可靠的地方。别人有类似的问题吗? 我不希望使用我所看到的变通方法
sendkeys(Enter)
,因为我想尽可能模拟真实的用户点击和数据输入。 > #1 楼
短语“有时有时不起作用”通常意味着Selenium试图在当时不可用时进行操作(最简单的检查方法是在每个操作之前进行长时间的暂停)。在此情况下,我建议您制作自己的自定义方法
WaitWhileProcessing
,该方法命令WebDriver等待呈现整个页面。在自定义方法上编写该代码的方式取决于您的Web应用程序(有时您只需要等到特定页面元素被加载即可。)。评论
我进行了进一步的研究,并尝试确保元素确实存在,并且具有我单击的链接(通过检查元素的href属性)。这将返回正确的值,但是单击仍然不起作用。
–Cesspit
2012年1月6日在22:21
@theCesspit您是否在每次操作(调试时)之前尝试过time.sleep(10)方法?但是,在SO上似乎存在类似的问题。
–user9440008
2012年1月7日在11:31
我在某处超时,但这似乎无法解决。实际上,在发送点击之前,我已经检查了href元素是否可用。在没有JavaScript的另一段代码中,每次单击一次按钮元素都会完全失败(只有sendkeys返回代码有效)。
–Cesspit
2012年1月7日17:50
#2 楼
只要确保您要单击的元素已经准备就绪,它就可以可靠地工作。通过在循环内使用try-catch条件,可以找到不引发异常的元素。例如,我编写的此方法(可以简化使用,具体取决于您使用的方法)将返回WebElement,并确保在将其返回给您之前确保它是可单击的:/**
* Example of using finally to "ignore" exceptions from Selenium
* findElement() method.
*/
public static WebElement getElementByLocator( final By locator ) {
driver.manage().timeouts().implicitlyWait( 15, TimeUnit.SECONDS );
WebElement we = null;
int tries = 0;
while ( tries < 4 ) {
try {
we = driver.findElement( locator );
break;
} catch ( StaleElementReferenceException e ) {
LOGGER.info( "Ignoring stale element exception.");
} finally { // use finally block to totally ignore exception block
tries += 1;
}
}
driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );
return we;
}
注意:您也可以通过将其更改为使用FluentWait类或Wait类来忽略异常而不是显式处理异常(如上所示)来改进此方法。我建议这样做,但如果您愿意,也可以像上面显示的那样有机地进行。
#3 楼
我不是Selenium的专家,但是这里有一些我用于解决此问题的技术(使用Java):使用Actions类:builder.clickAndHold('your web element')
方法,然后是builder.release('your web element')
。这会在单击和释放之间留出一些时间,因此单击操作将生效。单击并确保在没有在while循环中再次重复此部分代码的情况下获得了预期的结果。
有一些建议在try catch块中单击两次元素,然后捕获
NoSuchElementException
,然后执行所需的任何操作。评论
Pt.1是不错的小费;不过,其他两点看起来并不适合测试。
– \ nibra
13年5月16日在18:03
#4 楼
我不确定您使用的是哪种语言API,但是我使用WaitForWait
类解决了JavaScript应用中的许多加载问题。您可能需要做一些翻译工作,但是在.NET中,我建立了一个工厂方法来生成带有WaitForWait
的totalWaitTimeout
类,如果到达该类将引发异常,而waitInterval
是驱动程序将等待直到再次检查元素的时间。 public static class WaitFactory
{
public const int TotalWaitSeconds = 10;
public const int WaitIntervalMiliseconds = 50;
public static WebDriverWait GetWait(IWebDriver driver)
{
var clock = new SystemClock();
var totalWaitTimeout = new TimeSpan(0, 0, TotalWaitSeconds);
var waitInterval = new TimeSpan(0, 0, 0, 0, WaitIntervalMiliseconds);
return new WebDriverWait(clock, driver, totalWaitTimeout, waitInterval);
}
}
然后编写如下函数:
public void WaitForPanelToAppear(IWebDriver driver)
{
var wait = WaitFactory.GetWait(driver);
wait.Until(webDriver => webDriver.findElement(By.id("profile-panel")).Displayed);
}
单击按钮后应调用生成页面更改,并且在处理要加载的元素之前。
#5 楼
它在最新版本的Firefox(v29)上可以正常工作,但是对于Chrome来说会产生问题,有时您必须手动单击页面链接以继续执行代码。元素如果您的鼠标指针不在运行代码的浏览器上,则单击菜单和子菜单仅适用于Chrome v34.0。将指针放在远离浏览器的地方,或者在可行的情况下,使用其他屏幕。为我工作!
评论
我将2.16与2.14和2.12进行了比较,我非常确信.click()方法的更改已破坏了某些内容。只有2.16中的sendkeys()似乎可以让我按下按钮和链接,对于我需要单击的项目(在网站本身中发送回车键),这些项目均无法按预期工作,单击为null -op。2.17已解决我在2.16中遇到的问题:code.google.com/p/selenium/issues/detail?id=3144谢谢大家的帮助。