107

私はJava Selenium-WebDriverに取り組んでいます。追加した

driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

WebElement textbox = driver.findElement(By.id("textbox"));

アプリケーションがユーザー インターフェイスをロードするのに数秒かかるためです。だから私は2秒のimplicitwaitを設定しました。しかし、要素のテキストボックスを見つけることができませんでした

それから私は追加しますThread.sleep(2000);

今では正常に動作します。どちらがより良い方法ですか?

4

14 に答える 14

127

待機には、明示的待機と暗黙的待機の2種類があります。明示的な待機の考え方は

WebDriverWait.until(condition-that-finds-the-element);

暗黙の待機の概念は

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

あなたはここで詳細の違いを得ることができます。

fluentWaitそのような状況では、(特に)明示的な待機を使用することをお勧めします。

public WebElement fluentWait(final By locator) {
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(30, 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(locator);
        }
    });

    return  foo;
};

fluentWait関数は、見つかったWeb要素を返します。ドキュメントからfluentWaitタイムアウトとポーリング間隔をオンザフライで構成できるWaitインターフェースの実装。各FluentWaitインスタンスは、条件を待機する最大時間と、条件をチェックする頻度を定義します。さらに、ユーザーは、ページ上の要素を検索するときのNoSuchElementExceptionsなど、待機中に特定のタイプの例外を無視するように待機を構成できます。あなたがここで 得ることができる詳細

fluentWaitあなたの場合の使用法は次のとおりです。

WebElement textbox = fluentWait(By.id("textbox"));

このアプローチは、待機する時間が正確にわからないため、IMHOの方が優れています。ポーリング間隔では、を介して要素の存在を確認する任意の時間値を設定できます。よろしく。

于 2012-10-12T13:02:26.330 に答える
16

このスレッドは少し古いですが、現在行っていること (進行中の作業) を投稿すると思いました。

システムに大きな負荷がかかっていて、送信ボタン (login.jsp など) をクリックすると、3 つの条件 (以下を参照) はすべて返さtrueれるが、次のページ (home.jsp など) が表示されないという状況がまだ続いていますが、まだロードを開始していません。

これは、ExpectedConditions のリストを受け取る汎用の待機メソッドです。

public boolean waitForPageLoad(int waitTimeInSec, ExpectedCondition<Boolean>... conditions) {
    boolean isLoaded = false;
    Wait<WebDriver> wait = new FluentWait<>(driver)
            .withTimeout(waitTimeInSec, TimeUnit.SECONDS)
            .ignoring(StaleElementReferenceException.class)
            .pollingEvery(2, TimeUnit.SECONDS);
    for (ExpectedCondition<Boolean> condition : conditions) {
        isLoaded = wait.until(condition);
        if (isLoaded == false) {
            //Stop checking on first condition returning false.
            break;
        }
    }
    return isLoaded;
}

再利用可能なさまざまな ExpectedConditions を定義しました (3 つを以下に示します)。この例では、3 つの予想される条件には、document.readyState = 'complete'、「wait_dialog」が存在しない、および「スピナー」が存在しない (非同期データが要求されていることを示す要素) が含まれます。

すべての Web ページに一般的に適用できるのは、最初の 1 つだけです。

/**
 * Returns 'true' if the value of the 'window.document.readyState' via
 * JavaScript is 'complete'
 */
public static final ExpectedCondition<Boolean> EXPECT_DOC_READY_STATE = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        String script = "if (typeof window != 'undefined' && window.document) { return window.document.readyState; } else { return 'notready'; }";
        Boolean result;
        try {
            result = ((JavascriptExecutor) driver).executeScript(script).equals("complete");
        } catch (Exception ex) {
            result = Boolean.FALSE;
        }
        return result;
    }
};
/**
 * Returns 'true' if there is no 'wait_dialog' element present on the page.
 */
public static final ExpectedCondition<Boolean> EXPECT_NOT_WAITING = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        Boolean loaded = true;
        try {
            WebElement wait = driver.findElement(By.id("F"));
            if (wait.isDisplayed()) {
                loaded = false;
            }
        } catch (StaleElementReferenceException serex) {
            loaded = false;
        } catch (NoSuchElementException nseex) {
            loaded = true;
        } catch (Exception ex) {
            loaded = false;
            System.out.println("EXPECTED_NOT_WAITING: UNEXPECTED EXCEPTION: " + ex.getMessage());
        }
        return loaded;
    }
};
/**
 * Returns true if there are no elements with the 'spinner' class name.
 */
public static final ExpectedCondition<Boolean> EXPECT_NO_SPINNERS = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver driver) {
        Boolean loaded = true;
        try {
        List<WebElement> spinners = driver.findElements(By.className("spinner"));
        for (WebElement spinner : spinners) {
            if (spinner.isDisplayed()) {
                loaded = false;
                break;
            }
        }
        }catch (Exception ex) {
            loaded = false;
        }
        return loaded;
    }
};

ページによっては、それらの 1 つまたはすべてを使用する場合があります。

waitForPageLoad(timeoutInSec,
            EXPECT_DOC_READY_STATE,
            EXPECT_NOT_WAITING,
            EXPECT_NO_SPINNERS
    );

次のクラスには、事前定義された ExpectedConditions もあります: org.openqa.selenium.support.ui.ExpectedConditions

于 2014-11-08T00:39:05.657 に答える
2

クリックがブロックしているように見えますか? - WebDriverJS を使用している場合の別の待機方法は次のとおりです。

driver.findElement(webdriver.By.name('mybutton')).click().then(function(){
  driver.getPageSource().then(function(source) {
    console.log(source);
  });
});

上記のコードは、ボタンがクリックされた後、次のページが読み込まれるのを待ってから、次のページのソースを取得します。

于 2014-02-28T02:03:57.830 に答える
1

Implicitly wait と Thread.sleep どちらも同期にのみ使用されます..しかし、違いは、Implicitly wait をプログラム全体に使用できますが、Thread.sleep はその単一のコードに対してのみ機能することです..ここで私の提案は、Implicitly wait once をプログラムで使用することですWebページが更新されるたびに、その時点で Thread.sleep を使用することを意味します..それははるかに優れています:)

これが私のコードです:

package beckyOwnProjects;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;

public class Flip {

    public static void main(String[] args) throws InterruptedException {
        WebDriver driver=new FirefoxDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.MINUTES);
        driver.get("https://www.flipkart.com");
    WebElement ele=driver.findElement(By.cssSelector(".menu-text.fk-inline-block"));
    Actions act=new Actions(driver);
    Thread.sleep(5000);
    act.moveToElement(ele).perform();
    }

}
于 2015-12-19T12:38:45.383 に答える
0

暗黙の待機が無効になり、待機時間が短縮される場合があります。[@ eugene.polschikov]には、その理由に関する優れたドキュメントがありました。Selenium 2を使用したテストとコーディングで、暗黙的な待機は適切であることがわかりましたが、明示的に待機しなければならない場合があります。

スレッドを直接スリープ状態にすることは避けたほうがよいですが、それを回避する良い方法がない場合もあります。ただし、他にもSeleniumが提供する待機オプションがあります。waitForPageToLoadwaitForFrameToLoadは特に便利であることが証明されています。

于 2013-02-05T19:37:39.913 に答える
0

回答: Selenium WebDriver を使用した要素の可視性が以下のメソッドを通過するまで数秒待ちます。

ImplicitlyWait () : WebDriver インスタンスは、ページが完全に読み込まれるまで待機します。30 ~ 60 秒を使用して、ページが完全に読み込まれるまで待ちます。

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

ExplicitlyWait WebDriverWait() : WebDriver インスタンスは、ページが完全に読み込まれるまで待機します。

WebDriverWait wait = new WebDriverWait(driver, 60);

wait.until(ExpectedConditions.visibilityOf(textbox));

driver.findElement(By.id("Year")).sendKeys(allKeys);

: ExplicitlyWait WebDriverWait() を使用して、特定の WebElement を処理してください。

于 2018-04-05T08:36:22.157 に答える
-1

次のコードは 2 秒間待機することをお勧めします。

for(int i=0; i<2 && driver.findElements(By.id("textbox")).size()==0 ; i++){
   Thread.sleep(1000);
}
于 2013-11-26T08:44:13.090 に答える
-1

Implicit Wait: Implicit wait の間、Web ドライバーが利用可能であるためにすぐに要素を見つけられない場合、WebDriver は指定された時間だけ待機し、指定された期間中は要素を再度見つけようとしません。指定された時間が経過すると、例外をスローする前にもう一度要素を検索しようとします。デフォルト設定はゼロです。時間を設定すると、Web Driver は WebDriver オブジェクト インスタンスの期間待機します。

明示的な待機: 特定の要素の読み込みに 1 分以上かかる場合があります。その場合、Implicit 待機に膨大な時間を設定することは絶対に好きではありません。これを行うと、ブラウザはすべての要素に対して同じ時間を待機することになります。そのような状況を回避するには、必要な要素だけに別の時間を設定するだけです。これに従うことで、ブラウザの暗黙的な待機時間はすべての要素で短くなり、特定の要素では大きくなります。

于 2015-12-27T07:49:03.920 に答える
-1
Thread.sleep(1000);

さらに悪いのは、静的な待機であるため、テスト スクリプトが遅くなるということです。

driver.manage().timeouts.implicitlyWait(10,TimeUnit.SECONDS);

これは動的な待機です

  • Webドライバーが存在するまで有効であるか、ドライバーの有効期間まで有効です
  • 暗黙的に待機することもできます。

最後に、私が提案するのは

WebDriverWait wait = new WebDriverWait(driver,20);
wait.until(ExpectedConditions.<different canned or predefined conditions are there>);

いくつかの事前定義された条件を使用:

isAlertPresent();
elementToBeSelected();
visibilityOfElementLocated();
visibilityOfAllElementLocatedBy();
frameToBeAvailableAndSwitchToIt();
  • 動的待機でもあります
  • この場合、待機は数秒で済みます
  • 使用したい特定の Web 要素を明示的に待機する必要があります。
于 2018-02-16T17:32:46.130 に答える