programing

Ajax 호출이 Selenium 2 WebDriver로 완료 될 때까지 기다립니다.

randomtip 2021. 1. 17. 10:49
반응형

Ajax 호출이 Selenium 2 WebDriver로 완료 될 때까지 기다립니다.


AJAX를 사용하는 UI를 테스트하기 위해 Selenium 2 WebDriver를 사용하고 있습니다.

드라이버가 Ajax 요청이 완료 될 때까지 기다리도록하는 방법이 있습니까?

기본적으로 나는 이것을 가지고 있습니다 :

d.FindElement(By.XPath("//div[8]/div[3]/div/button")).Click();
// This click trigger an ajax request which will fill the below ID with content.
// So I need to make it wait for a bit.

Assert.IsNotEmpty(d.FindElement(By.Id("Hobbies")).Text);

var wait = new WebDriverWait(d, TimeSpan.FromSeconds(5));
var element = wait.Until(driver => driver.FindElement(By.Id("Hobbies")));

ajax 요청에 jQuery를 사용하는 경우 jQuery.active속성이 0 이 될 때까지 기다릴 수 있습니다 . 다른 라이브러리에는 유사한 옵션이있을 수 있습니다.

public void WaitForAjax()
{
    while (true) // Handle timeout somewhere
    {
        var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
        if (ajaxIsComplete)
            break;
        Thread.Sleep(100);
    }
}

여기에서 Selenium 명시 적 대기를 사용할 수도 있습니다. 그러면 타임 아웃을 직접 처리 할 필요가 없습니다.

public void WaitForAjax()
{
    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
    wait.Until(d => (bool)(d as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0"));
}

Morten Christiansens 답변을 기반으로 한 Java 솔루션

    public void WaitForAjax ()가 InterruptedException을 던집니다.
    {

        while (true)
        {

            Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor) driver) .executeScript ( "return jQuery.active == 0");
            if (ajaxIsComplete) {
                단절;
            }
            Thread.sleep (100);
        }
    }



제한 시간 매개 변수를 추가하여 약간의 개선이 있습니다.

internal static void WaitForAllAjaxCalls(this ISelenium selenium, IWebDriver driver, int timeout = 40)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        while (true)
        {
            if (sw.Elapsed.Seconds > timeout) throw new Exception("Timeout");
            var ajaxIsComplete = (bool)driver.ExecuteScript("return jQuery.active == 0");
            if (ajaxIsComplete)
                break;
            Thread.Sleep(100);
        }            
    }

내 코드는 다음과 같습니다.

public static void WaitForCommission (WebDriver driver) throws Exception {
    for (int second = 0;; second++) {
        if (second >= 30) fail("timeout");
        try { 
            if (IsElementActive(By.id("transferPurposeDDL"), driver)) 
                break; 
            } catch (Exception e) {}
        Thread.sleep(1000);
    }
}

private static boolean IsElementActive(By id, WebDriver driver) {
    WebElement we =  driver.findElement(id);        
    if(we.isEnabled())
        return true;
    return false;
}

이 코드는 정말 작동합니다.


약간의 개선 :

//Wait for Ajax call to complete
  public void WaitForAjax1() throws InterruptedException
    {

        while (true)
        {
            if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){
                break;
            }
            Thread.sleep(100);
        }
    }

Graphene사용하는 경우 다음을 사용할 수 있습니다.

Graphene.waitModel().until((Predicate<WebDriver>) input -> (Boolean) ((JavascriptExecutor) input).executeScript("return jQuery.active == 0"));

"XML Http Request"는 Ajax 요청을 서버로 보내는 데 사용되는 프로토콜이므로 이러한 요청이 있으면 Ajax 기반 작업이 진행 중임을 나타냅니다.

There are a number of browser plugins that allow you to monitor XML Http Requests sent by the browser. I personally use the Firebug plugin for Firefox which is a very useful tool. Once installed Firebug displays a Bug-like icon at the bottom right corner of the browser window. Clicking on the bug-like icon launches Firebug as shown in the image above. Select the “Net” and then “XHR” to launch the XHR console where all XML HTTP Requests sent by the browser will be displayed.

Avoid using thread.sleep() as much as possible. Here is a piece of code that accepts wait time as input and runs a stop watch for the specified time.

You may set the input time in seconds to 30 to start with.

protected void WaitForAjaxToComplete(int timeoutSecs)
        {

            var stopWatch = new Stopwatch();

            try
            {
                while (stopWatch.Elapsed.TotalSeconds < timeoutSecs)
                {

                    var ajaxIsComplete = (bool)(WebDriver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
                    if (ajaxIsComplete)
                    {
                        break;
                    }

                }
            }
            //Exception Handling
            catch (Exception ex)
            {
                stopWatch.Stop();
                throw ex;
            }
            stopWatch.Stop();

        }

If you use Coypu you can Check if an element exists after an AJAX call and then you can click it:

private void WaitUntilExistsThenClick(string selectorId)
{
    var searchBoxExists = new State(() => browser.FindId(selectorId).Exists());
    if (browser.FindState(searchBoxExists) == searchBoxExists)
    {                
        browser.FindId(selectorId).Click();
    }
}       

ReferenceURL : https://stackoverflow.com/questions/6201425/wait-for-an-ajax-call-to-complete-with-selenium-2-webdriver

반응형