8

我正在尝试通过拦截对 doClick(locator) 的调用来自定义 Selenium 的单击命令的行为(通过 user-extentions.js)。基本上,每当显示我们的应用程序的“忙碌指示器”时,我都需要延迟点击操作。

(现在这种事情的标准答案是在这些情况下在脚本中插入一个 waitFor 。事实上,我们目前在我们的脚本中有数以千计的它们。我正试图消除这些。)

检测页面元素是微不足道的部分。棘手的部分是让脚本真正等待。我看起来很有希望但失败的尝试如下所示:

var nativeClick = Selenium.prototype.doClick;
Selenium.prototype.doClick = function(locator) {
  this.doWaitForCondition("!selenium.browserbot.findElementOrNull('busy-indicator')", 5000);
  return nativeClick.call(this, locator);
}

doWaitForCondition 在每次点击之前被调用,但当条件评估为假时它不会等待。nativeClick 总是立即被调用,因此不会引入延迟。我怀疑 doWaitForCondition 函数本身实际上并没有做任何等待,而是在命令执行循环中为它建立了条件。在这种情况下,点击命令已经在发挥作用,我正在尝试在命令中运行命令。

有人可以阐明 Selenium 命令执行和 waitFor 的工作原理,或者提供有关如何完成的建议吗?

4

2 回答 2

5

我终于解决了这个问题。并且采用一种比试图拦截各种形式的点击处理要好得多的方法。我改进的目标是:当我们的应用程序“忙”时延迟执行脚本命令完成。

Selenium 命令处理的工作原理:

完成后,每个 selenium 命令都会返回一个ActionResult对象,(请参阅ActionHandler.prototype.execute。该terminationCondition对象的属性是一个函数,用于确定 selenium 何时可以继续执行下一个命令( TestLoop.prototype.continueTestWhenConditionIsTrue)。基本上,selenium 重复执行条件函数,直到它产生 true。结果对象非常简单:

function ActionResult(terminationCondition) {
  this.terminationCondition = terminationCondition;
}

自定义它:

我想在任何时候延迟执行myAppIsBusy()返回 true。当然,所有标准延迟也需要保持不变,例如等待页面加载,以及脚本中的显式 waitFor 条件。解决办法是在我的user-extensions.js中重新定义selenium结果对象,如下:

function ActionResult(terminationCondition) {
  this.terminationCondition = function() {
    // a null terminationCondition means okay to continue
    return (!terminationCondition || terminationCondition()) && !myAppIsBusy();
  }
}

很棒的是,它的级别足够低,可以在 IDE 和 RC 中使用。

请注意,这不会影响返回不同结果对象的 Accessor 或 Assert 命令类型。但这应该没问题,因为这些命令不会影响应用程序的状态。

于 2011-04-15T18:34:42.313 回答
0

好吧,看一下 java 驱动程序com.thoughtworks.selenium.Wait类就会发现:

public void wait(String message, long timeoutInMilliseconds, long intervalInMilliseconds) {
    long start = System.currentTimeMillis();
    long end = start + timeoutInMilliseconds;
    while (System.currentTimeMillis() < end) {
        if (until()) return;
        try {
            Thread.sleep(intervalInMilliseconds);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    throw new WaitTimedOutException(message);
}

我不会深入研究硒,但我希望每个 waitXXX 方法都指向这一点。

因此,Selenium 正在使用Thread.sleep(). 虽然这可能看起来不是一个理想的解决方案,但它至少表明,如果有必要,您不能通过自己使用 Thread.sleep() 来使情况变得更糟。;-)

于 2010-11-17T17:09:28.420 回答