[selenium] 문서가 준비 될 때까지 셀레늄 대기

누구든지 페이지가 완전히로드 될 때까지 어떻게 셀레늄을 기다릴 수 있습니까? 나는 일반적인 것을 원한다. WebDriverWait를 구성하고 ‘find’와 같은 것을 호출하여 기다릴 수는 있지만 멀리 가지 않는다는 것을 알고있다. 페이지가 성공적으로로드되는지 테스트하고 다음 페이지로 이동하여 테스트하십시오.

.net에서 무언가를 찾았지만 Java에서 작동시키지 못했습니다 …

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

어떤 생각이라도?



답변

이 코드를 사용해보십시오 :

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

위의 코드는 페이지로드를 위해 최대 10 초 동안 대기합니다. 페이지 로딩이 시간을 초과하면TimeoutException . 당신은 예외를 잡아서 당신의 필요를합니다. 예외가 발생한 후 페이지 로딩이 종료되는지 확실하지 않습니다. 아직이 코드를 시도하지 않았습니다. 그냥 시도하고 싶습니다.

이것은 암묵적인 대기입니다. 이 설정을 한 번 설정하면 웹 드라이버 인스턴스가 삭제 될 때까지 범위가 설정됩니다.

자세한 내용은 설명서를WebDriver.Timeouts 참조하십시오 .


답변

제안 된 솔루션은 DOMreadyState 신호 만 기다립니다 complete. 그러나 Selenium은 기본적으로 driver.get()and element.click()메소드 를 통해 페이지로드에있는 것들 (그리고 조금 더)을 기다리려고 합니다. 이미 차단 중이며 페이지가 완전히로드 될 때까지 기다렸다가 정상적으로 작동해야합니다.

분명히 문제는 AJAX 요청 및 실행 스크립트를 통한 리디렉션입니다. Selenium은이를 잡을 수 없으며 완료 될 때까지 기다리지 않습니다. 또한, 당신은 그들을 통해 확실하게 잡을 수 없습니다 readyState-그것은 조금 기다립니다, 유용 할 수 있지만, complete모든 AJAX 내용이 다운로드되기 오래 전에 신호를 보냅니다 .

어느 곳에서나 모든 사람에게 적용되는 일반적인 솔루션은 없기 때문에 어렵고 모든 사람이 조금 다른 것을 사용합니다.

일반적인 규칙은 WebDriver를 사용하여 자신의 역할을 수행 한 다음 암시 적 대기를 사용한 다음 페이지에서 주장하려는 요소에 대한 명시 적 대기를 사용하는 것이지만 수행 할 수있는 더 많은 기술이 있습니다. 테스트 한 페이지에서 귀하의 경우에 가장 적합한 것을 선택해야합니다.

자세한 내용은 이에 관한 두 가지 답변을 참조하십시오.


답변

이것은 당신이 준 예제의 작동하는 Java 버전입니다.

void waitForLoad(WebDriver driver) {
    new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

c #의 예 :

public static void WaitForLoad(IWebDriver driver, int timeoutSec = 15)
{
  IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
  WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
  wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}


답변

다음은 파이썬에서 완전히 일반적인 솔루션을 시도한 것입니다.

먼저, 일반적인 “대기”기능 (원하는 경우 WebDriverWait을 사용하면 추악합니다) :

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

다음으로 솔루션은 셀레늄이 최상위 <html>요소를 포함하여 페이지의 모든 요소에 대해 (내부) id 번호를 기록한다는 사실에 의존합니다 . 페이지를 새로 고치거나로드하면 새 ID를 가진 새로운 html 요소가 표시됩니다.

예를 들어, “my link”라는 텍스트가있는 링크를 클릭한다고 가정하면 다음과 같습니다.

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

더 파이썬적이고 재사용 가능한 일반 도우미를 위해 컨텍스트 관리자를 만들 수 있습니다.

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

그리고 거의 모든 셀레늄 상호 작용에 사용할 수 있습니다.

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

방탄이라고 생각합니다! 어떻게 생각해?

블로그 게시물에 대한 자세한 정보는 여기


답변

나는 비슷한 문제가 있었다. 문서가 준비 될 때까지 모든 Ajax 호출이 완료 될 때까지 기다려야했습니다. 두 번째 조건은 감지하기 어려운 것으로 판명되었습니다. 결국 나는 활성 Ajax 호출을 확인했고 작동했습니다.

자바 스크립트 :

return (document.readyState == 'complete' && jQuery.active == 0)

전체 C # 방법 :

private void WaitUntilDocumentIsReady(TimeSpan timeout)
{
    var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
    var wait = new WebDriverWait(WebDriver, timeout);

    // Check if document is ready
    Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
        .ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
    wait.Until(readyCondition);
}


답변

WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));


답변

C # NUnit의 경우 WebDriver를 JSExecuter로 변환 한 다음 document.ready 상태가 완료되었는지 여부를 확인하기 위해 스크립트를 실행해야합니다. 아래 코드를 참조하십시오.

 public static void WaitForLoad(IWebDriver driver)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        int timeoutSec = 15;
        WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
        wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
    }

조건이 충족되거나 시간 초과 될 때까지 기다립니다.