我正在使用Selenium 2 2.16构建。我一直遇到问题,无法对click()调用做出响应,其中单击有时会激活元素背后的行为(加载新页面),有时却无法激活。由于click()不返回任何内容,因此我无法捕获那些驱动程序没有进入新页面的情况。

这是一个代码段:

因此,我正在找到链接,检查链接是否已启用并具有正确的名称,然后单击它。下一步有时会超时(我将驱动程序设置为等待10秒后才超时),因为未加载新页面。有时候,它工作正常。

有问题的页面是基于JavaScript的,并使用Ext JS进行页面的呈现。 click()不可靠的地方。别人有类似的问题吗?

我不希望使用我所看到的变通方法sendkeys(Enter),因为我想尽可能模拟真实的用户点击和数据输入。 >

评论

我将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谢谢大家的帮助。

#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中,我建立了一个工厂方法来生成带有WaitForWaittotalWaitTimeout类,如果到达该类将引发异常,而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。将指针放在远离浏览器的地方,或者在可行的情况下,使用其他屏幕。
为我工作!