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


133

क्या कोई मुझे बता सकता है कि जब तक पेज पूरी तरह से लोड नहीं हो जाता, तब तक मैं सेलेनियम का इंतजार कैसे कर सकता हूं? मैं कुछ सामान्य चाहता हूं, मुझे पता है कि मैं 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"));

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


ऐसा क्यों है कि आप प्रतीक्षा का उपयोग नहीं करना चाहते हैं?
अमेय

7
आपका मतलब स्पष्ट प्रतीक्षा है? यह समय लेने वाला है, मैं कुछ 10k पृष्ठों का परीक्षण कर रहा हूं।
गिरीश

2
मेरा मतलब है, अगर मैं बड़ी संख्या में लिंक का परीक्षण कर रहा हूं, तो एक सही प्रतीक्षा जोड़ना एक अच्छा विचार नहीं हो सकता है?
गिरीश

10
कुछ सेकंड के लिए प्रतीक्षा करने का कोई फायदा नहीं है। वह अनुमान लगा रहा है।
एंडर्स लिंडन

यह देखते हुए कि किसी पृष्ठ की जावास्क्रिप्ट किसी भी सामान्य कोड को चला सकती है, उसके पूरा होने की प्रतीक्षा करने के लिए एक कार्यक्रम लिखना असंभव है। यह Halting Problem ( en.wikipedia.org/wiki/Halting_problem ) का एक रूप है । यहां किसी भी समाधान को समझौता करने या अंतर्निहित वेबपेज की मान्यताओं पर आधारित होने की आवश्यकता होगी।
स्पीड प्लेन

जवाबों:


83

इस कोड को आज़माएं:

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

पेज लोड होने के लिए उपरोक्त कोड 10 सेकंड तक प्रतीक्षा करेगा। यदि पृष्ठ लोड हो रहा है समय से अधिक है यह फेंक देगा TimeoutException। आप अपवाद को पकड़ते हैं और अपनी जरूरतों को पूरा करते हैं। मुझे यकीन नहीं है कि यह अपवाद फेंके जाने के बाद पेज लोड हो रहा है या नहीं। मैंने इस कोड को अभी तक आज़माया नहीं है। बस कोशिश करना चाहते हैं।

यह एक निहित प्रतीक्षा है। यदि आप इसे एक बार सेट करते हैं, तो इसका दायरा तब तक रहेगा जब तक कि वेब ड्राइवर का उदाहरण नष्ट न हो जाए।

अधिक जानकारी के लिए दस्तावेज़WebDriver.Timeouts देखें ।


3
धन्यवाद, इसलिए यदि पेज 10 सेकंड से पहले लोड हो जाता है तो यहां क्या होता है, क्या लोड के बाद अगली पंक्ति को निष्पादित करने के लिए 10 सेकंड का इंतजार करना होगा?
गिरीश

नहीं, यदि आपका पेज 10 सेकंड से पहले लोड होता है तो इसका मतलब है कि यह प्रतीक्षा की स्थिति को समाप्त कर देगा और पूर्ववर्ती लाइन को निष्पादित करेगा।
मनिगांदन

3
इसका उपयोग तब किया जाता है जब आप पृष्ठ लोड की अपेक्षा करते हैं जो समय-समय पर और अपवादों को फेंकने में बहुत लंबा समय लेता है, यह तुरंत पृष्ठ लोड की प्रतीक्षा नहीं करता है या बेहतर लोडिंग नीति सेट नहीं करता है। यह अनंत समय तक चूकता है, इसलिए आपका पेज लोड अपवादों को कभी नहीं फेंकता है और सेलेनियम हमेशा पूरी तरह से लोड होने के लिए इंतजार करने की कोशिश करता है।
पेट्र जेनेक

19
इस पद्धति के साथ समस्या यह है कि यह संभव है कि डोम पूरी तरह से सुलभ नहीं है, हालांकि अंतर्निहित प्रतीक्षा पहले सफलतापूर्वक एक WebElement वस्तु लौटा चुकी है। फिर, यदि आप तत्व को क्लिक करने का प्रयास करते हैं तो आपको एक बासी तत्व अपवाद मिलेगा। तो, यह जवाब पूरी तरह से सुरक्षित नहीं है।
djangofan

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

90

आपके सुझाए गए समाधान केवल संकेत के लिए DOMreadyState का इंतजार कर रहे हैं complete। लेकिन डिफ़ॉल्ट रूप से सेलेनियम उन और (और थोड़ा अधिक) के लिए पृष्ठ लोड driver.get()और element.click()विधियों के माध्यम से प्रतीक्षा करने की कोशिश करता है । वे पहले से ही अवरुद्ध हैं, वे पृष्ठ के पूरी तरह से लोड होने की प्रतीक्षा करते हैं और उन्हें ठीक काम करना चाहिए।

समस्या, जाहिर है, AJAX अनुरोधों और स्क्रिप्ट चलाने के माध्यम से पुनर्निर्देशित हैं - जिन्हें सेलेनियम द्वारा पकड़ा नहीं जा सकता है, यह उनके समाप्त होने की प्रतीक्षा नहीं करता है। इसके अलावा, आप मज़बूती से उन्हें पकड़ नहीं सकते हैं readyState- यह थोड़ा इंतजार करता है, जो उपयोगी हो सकता है, लेकिन यह completeसभी AJAX सामग्री डाउनलोड होने से बहुत पहले संकेत देगा ।

कोई भी सामान्य समाधान नहीं है जो हर जगह और हर किसी के लिए काम करेगा, इसलिए यह कठिन है और हर कोई कुछ अलग सा उपयोग करता है।

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

अधिक जानकारी के लिए इसके बारे में मेरे दो उत्तर देखें:


20
यह गलत है, सेलेनियम प्रतीक्षा या element.click()कॉल पर ब्लॉक नहीं करता है ।
hwjp

3
@hwjp अधिक विस्तार से देखभाल? JavaDocs अन्यथा कहती है : "यदि यह नया पृष्ठ लोड करने का कारण बनता है, तो यह विधि तब तक ब्लॉक करने का प्रयास करेगी जब तक पृष्ठ लोड नहीं हो जाता।"
पेट्र जेनकॉक

5
सीएफ कुछ बातचीत मैं मेलिंग सूची पर पड़ा है ऐसा लगता है कि यह गलत है। सेलेनियम .get कॉल को ब्लॉक कर सकता है जहां आप स्पष्ट रूप से URL का अनुरोध करते हैं, लेकिन यह क्लिक कॉल पर कुछ खास नहीं करता है, क्योंकि यह नहीं बता सकता है कि आपने "वास्तविक" हाइपरलिंक पर क्लिक किया है या एक जो जावास्क्रिप्ट द्वारा इंटरसेप्ट किया जाएगा। ..
hwjp

4
मैं मेलिंग सूची चर्चा की शुरुआत में एक बग से जोड़ता हूं। यहां तक ​​कि डॉक्स समतुल्य: "यदि क्लिक करें () [...] एक मूल घटना भेजकर किया जाता है, तो विधि * प्रतीक्षा नहीं होगी"
hwjp

4
तो यह सब चालू होता है कि क्या ब्राउज़र "मूल घटनाओं" का उपयोग कर रहा है। और ऐसा लगता है कि उनमें से अधिकांश डिफ़ॉल्ट रूप से होंगे: code.google.com/p/selenium/wiki/… (इसलिए मैं कहूंगा कि डॉक्स सबसे अच्छे तरीके से भ्रामक हैं। मेलिंग सूची पिंग करेंगे)।
hwjp

61

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

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

1
यार, मैं इसे कॉपी / पेस्ट कर रहा हूं। यह स्निपेट सिर्फ शानदार है। मैंने ऐसा क्यों नहीं सोचा? सच है कि एक से अधिक जोड़ी नेत्रगोलक हमेशा एक अच्छा समाधान का नेतृत्व करते हैं। धन्यवाद।
luis.espinal

2
क्या आप इसे java 1.7 वर्जन में डाल सकते हैं क्योंकि लैम्ब्डा एक्सप्रेशन सपोर्ट नहीं करता है
vkrams

3
Java 1.7 संस्करण: Wait.until (नया Predicate <WebDriver> () {जनता का बूलियन लागू (WebDriver ड्राइवर) {return ((JavascriptExecutor) ड्राइवर) .executeScript ("रिटर्न डॉक्यूमेंट पहले से हीस्टेट")। बराबर ("पूर्ण");} };
luQ

1
अगर कोई @IuQ द्वारा समाधान का उपयोग करना चाहता है, तो Predicate का आयात होता हैimport com.google.common.base.Predicate
Knu8

मैंने इस विचार को वीबी टेस्ट ऐप में आज़माया। ज्यादातर समय काम करता है। मुझे यह त्रुटि कभी-कभी मिलती है: System.InvalidOperationException: OpenQA.Selenium.Remote.RemoteWemDriver.UnpackAndTrowOnError (Response errorResponse) टेस्ट ऐप पर लेवल 2 मेनू लिंक पर क्लिक करने पर, फिर WaitObjj.U. D, InternetExplorerDriver) .ExecuteScript ("डॉक्यूमेंट डॉक्यूमेंट.ट्रेडस्टैट") = "पूर्ण")। मुझे लगता है कि त्रुटि का कारण बनता है क्योंकि ब्राउज़र वर्तमान पृष्ठ को अनलोड करता है और कोई दस्तावेज़ ऑब्जेक्ट नहीं है। हो सकता है "रिटर्न डॉक्यूमेंट.डरिस्टेट? आइडियाज?
कूलब्रीज

12

यहाँ पायथन में एक पूरी तरह से सामान्य समाधान पर मेरा प्रयास है:

सबसे पहले, एक सामान्य "प्रतीक्षा" फ़ंक्शन (यदि आप चाहें तो 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>तत्व सहित एक पृष्ठ पर सभी तत्वों के लिए एक (आंतरिक) आईडी-संख्या रिकॉर्ड करता है । जब कोई पेज रिफ्रेश या लोड होता है, तो उसे नई आईडी के साथ एक नया html एलिमेंट मिलता है।

इसलिए, यह मानते हुए कि आप उदाहरण के लिए टेक्स्ट "माई लिंक" के लिंक पर क्लिक करना चाहते हैं:

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()

मुझे लगता है कि बुलेटप्रूफ है! तुम क्या सोचते हो?

इसके बारे में एक ब्लॉग पोस्ट में अधिक जानकारी यहाँ


बहुत दिलचस्प दृष्टिकोण। एक चुनौती यह है कि क्या यह ब्राउज़र के पहले लॉन्च के बाद प्रारंभिक पृष्ठ लोड पर काम कर सकता है। इस बात की कोई गारंटी नहीं है कि ब्राउज़र की प्रारंभिक स्थिति में कोई पेज लोड है। इसके अलावा, जावा में, मैं यह नहीं देख रहा हूं कि हमारे पास ऑब्जेक्ट पर एक 'आईडी' है - मैं मान रहा हूं कि इसका मतलब यह नहीं है कि सेलेनियम एक html आईडी विशेषता सम्मिलित करता है। जब मैंने इस विकल्प को और खोज लिया, तो मैं इस प्रतिक्रिया में और जोड़ दूंगा। पोस्ट के लिए धन्यवाद!
लुकस

@hwjp मैं उत्कृष्ट परिणाम के साथ कई बार इस समाधान का उपयोग करता हूं, लेकिन ऐसा लगता है कि यह एक मामले में काम नहीं करता है। समस्या का पूर्ण विवेचन stackoverflow.com/q/31985739/4249707
एल रुसो

7

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

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

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

क्या document.readyState == 'complete' && jQuery.active == 0रिएक्ट के लिए कुछ ऐसा है ?
Rain9333

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

4

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

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


3

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

बदलने के:

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

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

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


1

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

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

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

1

बेन ड्रायर के जवाब ने मेरी मशीन ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait") पर संकलन नहीं किया ।

कार्य जावा 8 संस्करण:

Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
        "return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);

जावा 7 संस्करण:

Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver input) {
            return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
        }

};
new FluentWait<WebDriver>(driver).until(pageLoaded);

1

मैंने इस कोड की कोशिश की और यह मेरे लिए काम करता है। जब भी मैं किसी अन्य पृष्ठ पर जाता हूं, मैं इस फ़ंक्शन को कॉल करता हूं

public static void waitForPageToBeReady() 
{
    JavascriptExecutor js = (JavascriptExecutor)driver;

    //This loop will rotate for 100 times to check If page Is ready after every 1 second.
    //You can replace your if you wants to Increase or decrease wait time.
    for (int i=0; i<400; i++)
    { 
        try 
        {
            Thread.sleep(1000);
        }catch (InterruptedException e) {} 
        //To check page ready state.

        if (js.executeScript("return document.readyState").toString().equals("complete"))
        { 
            break; 
        }   
      }
 }

1

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

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

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 (url) → तब करने योग्य

शेड्यूल दिए गए URL पर नेविगेट करने के लिए एक कमांड है।

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

सेलेनियम प्रलेखन (Nodejs)


1

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

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

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

}

`मैं इस तरीके को सीधे Driver.navigate.gotourl के बाद फायर करता हूं, ताकि इसे जल्द से जल्द पेज का संदर्भ मिल जाए। इसके साथ मजे करो!


1

सामान्य तब होता है जब सेलेनियम एक क्लिक से एक नया पृष्ठ खोलता है या जमा करता है या विधियाँ प्राप्त करता है, यह पृष्ठ को लोड होने तक इंतजार नहीं करेगा लेकिन समस्या यह है कि जब पृष्ठ में xhr कॉल (ajax) है तो वह कभी भी xhr के लोड होने की प्रतीक्षा नहीं करेगा, इसलिए एक 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);
}

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


0

इसे संभालने के लिए आप कुछ तर्क लिख सकते हैं। मैंने एक विधि लिखी है, जो वापस आ जाएगी 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;
        }
    }

0

मैंने दस्तावेज़ तैयार है या नहीं यह जांचने के लिए एक जावास्क्रिप्ट कोड निष्पादित किया है। मुझे कई बार उन साइटों के लिए सेलेनियम परीक्षण डिबगिंग से बचाया, जिनमें क्लाइंट साइड रेंडरिंग है।

public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
    Thread.sleep(100)
    def ready = isDOMReady(driver);
    if (ready) {
        break;
    }
}

}

public static boolean isDOMReady(WebDriver driver){
    return driver.executeScript("return document.readyState");
}

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

0

जैसे रुबानोव ने C # के लिए लिखा, मैंने इसे जावा के लिए लिखा, और यह है:

    public void waitForPageLoaded() {
    ExpectedCondition<Boolean> expectation = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return (((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete")&&((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")));
                }
            };
    try {
        Thread.sleep(100);
        WebDriverWait waitForLoad = new WebDriverWait(driver, 30);
        waitForLoad.until(expectation);
    } catch (Throwable error) {
        Assert.fail("Timeout waiting for Page Load Request to complete.");
    }
}

0

जावा में यह निम्नानुसार होगा: -

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

1
जेएस कमांड्स को एक में संयोजित करना बेहतर होगा ताकि आपको पेज को दो बार हिट न करना पड़े, जैसेreturn document.readyState == 'loaded' || return document.readyState == 'complete'
जेफ़सी

0

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

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

0

यदि आपके पास एक धीमा पृष्ठ या नेटवर्क कनेक्शन है, तो संभावना है कि उपरोक्त में से कोई भी काम नहीं करेगा। मैंने उन सभी की कोशिश की है और मेरे लिए काम करने वाली एकमात्र चीज उस पृष्ठ पर अंतिम दृश्य तत्व की प्रतीक्षा करना है। उदाहरण के लिए Bing वेबपेज लें। उन्होंने मुख्य खोज बटन के बगल में एक CAMERA आइकन (छवि बटन द्वारा खोज) रखा है जो पूरा पृष्ठ लोड होने के बाद ही दिखाई देता है। यदि सभी ने ऐसा किया है, तो हमें बस इतना करना है कि ऊपर दिए गए उदाहरणों की तरह स्पष्ट प्रतीक्षा करें।


-1
public void waitForPageToLoad()
  {
(new WebDriverWait(driver, DEFAULT_WAIT_TIME)).until(new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver d) {
        return (((org.openqa.selenium.JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
      }
    });//Here DEFAULT_WAIT_TIME is a integer correspond to wait time in seconds

-1

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

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

आपका कोड मेरे लिए काम नहीं करता है। मैं iframe को कैसे स्विच करूं और onload = "javascript: pageload (); functionalPageLoad ();" रूबी में पृष्ठ पुनः लोड करने के लिए? मैं अपने आप को एक पेज के अंदर iframe खोलते हुए पाता हूं, मेरे पास इसकी पहुंच है, फिर पेज पुनः लोड होता है, और मैं अब फ्रेम तक नहीं पहुंच सकता। मैंने प्रतीक्षा, नींद, समय, स्विच के बारे में कई उत्तर माता-पिता के पास पढ़े हैं, हालांकि मैं अपने लक्ष्य तक नहीं पहुंच सकता।
अमांडा कैवलारो

1
ऐसा लगता है कि आपका प्रश्न मुख्य रूप से iFrame पर स्विच करने के बारे में है, दस्तावेज़ लोड के लिए इंतजार करने के बारे में नहीं। एक नया प्रश्न शुरू करना बेहतर हो सकता है यदि आप iFrames के साथ काम करने के बारे में एक प्रश्न में समाधान नहीं ढूंढ सकते हैं।
एमरी

-1

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

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

मुझे लगता है कि थ्रेड। स्लीप (5000) अक्सर एकमात्र तरीका है जो परीक्षण का काम करता है, इसके उपयोग के खिलाफ सभी सिफारिशों के बावजूद। तत्व के लिए प्रतीक्षा का कोई संयोजन मेरे लिए काम नहीं करता है, विशेष रूप से कई तत्वों की पहचान नहीं की जा सकती है जब तक कि वे वास्तव में नहीं मिले हैं।
स्टीव स्टेपल

-1

मैंने पृष्ठ लोड पूरा होने की जाँच की, सेलेनियम 3.14.0 में काम किया

    public static void UntilPageLoadComplete(IWebDriver driver, long timeoutInSeconds)
    {
        Until(driver, (d) =>
        {
            Boolean isPageLoaded = (Boolean)((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete");
            if (!isPageLoaded) Console.WriteLine("Document is loading");
            return isPageLoaded;
        }, timeoutInSeconds);
    }

    public static void Until(IWebDriver driver, Func<IWebDriver, Boolean> waitCondition, long timeoutInSeconds)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
        webDriverWait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
        try
        {
            webDriverWait.Until(waitCondition);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

-1

उन लोगों के लिए जिन्हें दिखाने के लिए एक विशिष्ट तत्व की प्रतीक्षा करने की आवश्यकता है। (प्रयुक्त c #)

public static void WaitForElement(IWebDriver driver, By element)
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    wait.Until(ExpectedConditions.ElementIsVisible(element));
}

तब यदि आप उदाहरण के लिए इंतजार करना चाहते हैं यदि आपके द्वारा किए गए DOM में एक वर्ग = "त्रुटि-संदेश" मौजूद है:

WaitForElement(driver, By.ClassName("error-message"));

आईडी के लिए, यह तब होगा

WaitForElement(driver, By.Id("yourid"));


-3

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

मैं पॉल Hammants ngWebDriver को देखने की सलाह देता हूं । विधि WaitForAngularRequestsToFinish () काम आ सकती है।


वह बहुत ज्यादा नहीं था जो कोणीय का उपयोग कर रहा था। यह उत्तर अस्वीकृत कर दिया गया था क्योंकि ऐसा प्रतीत होता है कि आपने मूल प्रश्न को ध्यान से नहीं पढ़ा था।
ज़ेल्लेस

लेकिन मत नीचे मत देना तुम आकार से बाहर झुकना। यहां के लोग अच्छी तरह से मतलब रखते हैं। और आलोचना वास्तव में प्यार का एक रूप है (क्योंकि यदि किसी को किसी को सही करने के लिए समय लगता है क्योंकि वे परवाह करते हैं)। चेकआउट स्मार्ट तरीके से प्रश्न कैसे पूछें - स्मार्ट तरीके से सवालों के जवाब देने के लिए वे विचार भी लागू होते हैं।
ज़ेल्लेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.