8

doClick(locator) への呼び出しをインターセプトすることにより、(user-extentions.js を介して) Selenium のクリック コマンドの動作をカスタマイズしようとしています。基本的に、アプリケーションの「ビジー インジケーター」が表示されているときはいつでも、クリック アクションを遅らせる必要があります。

(現在、この種のことに対する標準的な答えは、そのような状況のスクリプトに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 はすべてのクリックの前に呼び出されますが、条件が false と評価されても待機しません。nativeClick は常にすぐに呼び出されるため、遅延は発生しません。doWaitForCondition 関数は実際には待機自体を行わず、コマンド実行ループ内でその条件を確立しているのではないかと思います。この場合、クリック コマンドは既に実行されており、コマンド内でコマンドを実行しようとしています。

Seleniumコマンドの実行とwaitForがどのように機能するか、またはこれがどのように行われるかについて提案を提供する方法について誰かが光を当てることができますか?

4

2 に答える 2

5

私はついにこれを解決しました。そして、さまざまな形でクリック処理を傍受しようとするよりもはるかに優れたアプローチを使用します. 私の洗練された目標は、アプリケーションが「ビジー」なときにスクリプトコマンドの実行を遅らせることです。

Selenium コマンド処理のしくみ:

完了すると、各 selenium コマンドはActionResultオブジェクトを返します( を参照ActionHandler.prototype.execute)。このオブジェクトのterminationCondition属性は、selenium が次のコマンド( TestLoop.prototype.continueTestWhenConditionIsTrue)に進むことができるタイミングを決定する関数です。基本的に、セレンは条件関数が true になるまで繰り返し実行します。結果オブジェクトは非常に簡単です:

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

カスタマイズ:

myAppIsBusy()true を返すたびに実行を遅らせたい。もちろん、ページ読み込みの待機や、スクリプト化された明示的な waitFor 条件など、すべての標準的な遅延もそのままにしておく必要があります。解決策は、次のように、user-extensions.js でセレンの結果オブジェクトを再定義することです。

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

素晴らしいことは、これが十分に低いレベルであるため、RC だけでなく IDE でも機能することです。

これは、異なる結果オブジェクトを返す 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 に答える