selenium - सेलेनियम प्रतीक्षा करें जब तक कि दस्तावेज़ तैयार न हो जाए




load document (16)

Document.ready घटना का इंतजार इस समस्या का पूरा समाधान नहीं है, क्योंकि यह कोड अभी भी दौड़ की स्थिति में है: कभी-कभी क्लिक कोड संसाधित होने से पहले इस कोड को निकाल दिया जाता है, इसलिए यह सीधे लौटाता है, क्योंकि ब्राउजर शुरू नहीं हुआ है अभी तक नया पेज लोड हो रहा है।

कुछ खोज के बाद मुझे ओबे पर परीक्षण बकरी पर एक पोस्ट मिली, जिसमें इस समस्या का समाधान है। उस समाधान के लिए सी # कोड इस तरह कुछ है:

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}

'मैं ड्राइवर के बाद सीधे इस विधि को आग लगाता हूं। Navigate.gotourl, ताकि यह जितनी जल्दी हो सके पृष्ठ का संदर्भ प्राप्त हो। इसके साथ मजे करो!

क्या कोई मुझे बता सकता है कि जब तक पेज पूरी तरह से लोड नहीं हो जाता तब तक मैं सेलेनियम इंतजार कैसे कर सकता हूं? मुझे कुछ सामान्य चाहिए, मुझे पता है कि मैं WebDriverWait को कॉन्फ़िगर कर सकता हूं और इसे प्रतीक्षा करने के लिए 'ढूंढ' जैसी कुछ कह सकता हूं लेकिन मैं अब तक नहीं जाता हूं। मुझे बस यह जांचने की आवश्यकता है कि पृष्ठ सफलतापूर्वक लोड हो और परीक्षण के लिए अगले पृष्ठ पर जाएं।

मुझे .NET में कुछ मिला लेकिन यह जावा में काम नहीं कर सका ...

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"));

कोई विचार किसी को भी?


आप इसे संभालने के लिए कुछ तर्क लिख सकते हैं। मैंने एक तरीका लिखा है जो WebElement वापस कर WebElement और इस विधि को तीन बार कहा जाएगा या आप समय बढ़ा सकते हैं और WebElement लिए शून्य जांच जोड़ सकते हैं यहां एक उदाहरण है

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.crowdanalytix.com/#home");
        WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
        int i = 1;
        while (webElement == null && i < 4) {
            webElement = getWebElement(driver, "homessssssssssss");
            System.out.println("calling");
            i++;
        }
        System.out.println(webElement.getTagName());
        System.out.println("End");
        driver.close();
    }

    public static WebElement getWebElement(WebDriver driver, String id) {
        WebElement myDynamicElement = null;
        try {
            myDynamicElement = (new WebDriverWait(driver, 10))
                    .until(ExpectedConditions.presenceOfElementLocated(By
                            .id(id)));
            return myDynamicElement;
        } catch (TimeoutException ex) {
            return null;
        }
    }

क्या आप कोणीय का उपयोग कर रहे हैं? यदि आप हैं तो यह संभव है कि वेबड्राइवर यह नहीं पहचानता कि एसिंक कॉल समाप्त हो गई है।

मैं पॉल हैमेंट्स ngWebDriver को देखने की सलाह देते हैं। विधि प्रतीक्षा करेंForAngularRequestsToFinish () काम में आ सकता है।


जावा में यह नीचे पसंद आएगा: -

  private static boolean isloadComplete(WebDriver driver)
    {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    }

निम्नलिखित कोड शायद काम करना चाहिए:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfAllElementsLocated(By.xpath("//*")));

नोडज में आप इसे वादे के माध्यम से प्राप्त कर सकते हैं ...

यदि आप यह कोड लिखते हैं, तो आप सुनिश्चित कर सकते हैं कि पृष्ठ तब तक पूरी तरह से लोड हो जाता है जब आप उस समय पहुंच जाते हैं ...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

यदि आप यह कोड लिखते हैं, तो आप नेविगेट करेंगे, और सेलेनियम 3 सेकंड प्रतीक्षा करेगा ...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

सेलेनियम दस्तावेज से:

this.get (यूआरएल) → फिर से

दिए गए यूआरएल पर नेविगेट करने के लिए अनुसूची एक कमांड।

एक वादा वापस करता है जिसे दस्तावेज़ लोड होने पर हल किया जाएगा।

सेलेनियम दस्तावेज़ीकरण (नोडेज)


पृष्ठ को फिर से लोड होने तक आप थ्रेड सो सकते हैं। यह सबसे अच्छा समाधान नहीं है, क्योंकि आपको यह अनुमान लगाने की आवश्यकता है कि पृष्ठ कितना समय लोड करता है।

driver.get(homeUrl); 
Thread.sleep(5000);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(userName);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(passWord);
driver.findElement(By.xpath("Your_Xpath_here")).click();

प्रारंभिक पृष्ठ लोड के लिए मैंने देखा है कि ब्राउजर विंडो को "अधिकतम करना" व्यावहारिक रूप से तब तक प्रतीक्षा करता है जब तक कि पृष्ठ लोड पूरा न हो (स्रोतों सहित)

बदलने के:

AppDriver.Navigate().GoToUrl(url);

साथ में:

public void OpenURL(IWebDriver AppDriver, string Url)
            {
                try
                {
                    AppDriver.Navigate().GoToUrl(Url);
                    AppDriver.Manage().Window.Maximize();
                    AppDriver.SwitchTo().ActiveElement();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
                    throw;
                }
            }

उपयोग से:

OpenURL(myDriver, myUrl);

यह पृष्ठ लोड करेगा, पूर्ण होने तक प्रतीक्षा करें, अधिकतम करें और उस पर ध्यान केंद्रित करें। मुझे नहीं पता कि ऐसा क्यों है लेकिन यह काम करता है।

यदि आप अगले या किसी अन्य पृष्ठ नेविगेशन पर क्लिक करने के बाद पेज लोड के लिए प्रतीक्षा करना चाहते हैं तो "नेविगेट ()", बेन डायर का जवाब (इस धागे में) काम करेगा।


मानक जब सेलेनियम एक क्लिक से एक नया पृष्ठ खोलता है या सबमिट करता है या विधियों को प्राप्त करता है, तो पृष्ठ को लोड नहीं किया जाएगा, लेकिन समस्या तब होती है जब पृष्ठ में xhr कॉल (AJAX) होता है, वह कभी भी xhr लोड होने की प्रतीक्षा नहीं करेगा, इसलिए एक एक्सएचआर की निगरानी करने के लिए एक नया मेथोड बनाना और उनके लिए इंतजार करना अच्छा होगा। (मेरी बुरी अंग्रेजी के बारे में खेद है: डी)

public boolean waitForJSandJQueryToLoad() {
    WebDriverWait wait = new WebDriverWait(webDriver, 30);
    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
            Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
            return r == 0;
        } catch (Exception e) {
            LOG.info("no jquery present");
            return true;
        }
      }
    };

    // wait for Javascript to load
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor)driver).executeScript("return document.readyState")
        .toString().equals("complete");
      }
    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);
}

अगर $ .active == 0 तो कोई सक्रिय xhrs कॉल नहीं है (जो केवल jQuery के साथ काम करता है)। जावास्क्रिप्ट AJAX कॉल के लिए आपको अपनी प्रोजेक्ट में एक चर बनाना है और इसे अनुकरण करना है।


मुझे भी ऐसी ही समस्या का समाधान करना पड़ा था। मुझे तब तक इंतजार करना पड़ा जब तक कि मेरा दस्तावेज़ तैयार न हो, तब तक जब तक सभी अजाक्स कॉल समाप्त नहीं हो जाते। दूसरी स्थिति का पता लगाना मुश्किल साबित हुआ। अंत में मैंने सक्रिय अजाक्स कॉल के लिए जांच की और यह काम किया।

जावास्क्रिप्ट:

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

पूर्ण सी # विधि:

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);
}

यह आपके द्वारा दिए गए उदाहरण का एक वर्किंग जावा संस्करण है:

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

सी # के लिए उदाहरण:

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

रूबी में कुछ ऐसा ही है:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }

सी # एनयूनीट के लिए, आपको WebDriver को JSExecuter में कनवर्ट करने की आवश्यकता है और उसके बाद दस्तावेज़ को जांचने के लिए स्क्रिप्ट निष्पादित करें। पहले से ही राज्य पूर्ण है या नहीं। संदर्भ के लिए कोड नीचे देखें:

 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");
    }

यह तब तक इंतजार करेगा जब तक कि स्थिति संतुष्ट न हो या टाइमआउट हो।


tapestry वेब-फ्रेमवर्क पर एक नज़र डालें। आप वहां स्रोत कोड डाउनलोड कर सकते हैं।

विचार यह है कि यह पृष्ठ सिग्नल करना है कि पृष्ठ एचटीएमएल विशेषता द्वारा तैयार है। आप इस विचार का उपयोग जटिल मुकदमे के मामलों को अनदेखा कर सकते हैं।

<html>
<head>
</head>
<body data-page-initialized="false">
    <p>Write you page here</p>

    <script>
    $(document).ready(function () {
        $(document.body).attr('data-page-initialized', 'true');
    });
    </script>  
</body>
</html>

और फिर सेलेनियम वेबड्राइवर का विस्तार बनाएं (टेपेस्ट्री फ्रेमवर्क के अनुसार)

public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
    //wait a bit for the page to start loading
    Thread.Sleep(100);

    //// In a limited number of cases, a "page" is an container error page or raw HTML content
    // that does not include the body element and data-page-initialized element. In those cases,
    // there will never be page initialization in the Tapestry sense and we return immediately.
    if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
    {                
        return;
    }

    Stopwatch stopwatch = Stopwatch.StartNew();

    int sleepTime = 20;

    while(true)
    {
        if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
        {
            return;
        }

        if (stopwatch.ElapsedMilliseconds > 30000)
        {
            throw new Exception("Page did not finish initializing after 30 seconds.");
        }

        Thread.Sleep(sleepTime);
        sleepTime *= 2; // geometric row of sleep time
    }          
}

एलीस्टर स्कॉट द्वारा लिखित विस्तार ElementIsDisplayed का उपयोग करें।

public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
    try
    {
        return driver.FindElement(By.XPath(xpath)).Displayed;
    }
    catch(NoSuchElementException)
    {
        return false;
    }
}

और अंत में परीक्षण बनाएं:

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();

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

public boolean waitForElement(String zoneName, String element, int index, int timeout) {
        WebDriverWait wait = new WebDriverWait(appiumDriver, timeout/1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(element)));
        return true;
    }