सेलेनियम में पृष्ठ लोड की प्रतीक्षा करें


240

आप सेलेनियम 2.0 कैसे लोड करने के लिए पेज का इंतजार करते हैं?


7
मेरे लिए केवल पॉल का उत्तर सही लगता है, अधिकांश उच्च मतदान वाले उत्तर किसी विशेष तत्व की प्रतीक्षा करते हैं।
xyz

जवाबों:


138

आप निम्नलिखित कोड का उपयोग करके पगेलोएड भी देख सकते हैं

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

22
आपको लगता है कि कुछ इस तरह से बनाया जाएगा। पेज लोड होने की प्रतीक्षा करना वेब पर एक बहुत ही सामान्य बात है।
18

19
क्या यह वास्तव में हर समय काम करता है? शायद Im अपने कोड से कुछ याद आ रही है, लेकिन आप डोम के तैयार राज्य में होने का इंतजार कर रहे हैं। लेकिन विचार करें कि यदि आपका कोड बहुत तेज़ी से निष्पादित होता है तो पिछला पृष्ठ अभी तक अनलोड नहीं किया जा सकता है और यह तब भी सही होगा जब आप पुराने पृष्ठ पर अभी भी हैं। आपको जो करने की आवश्यकता है वह वर्तमान पृष्ठ के अनलोड करने के लिए प्रतीक्षा करें और फिर अपने उपरोक्त कोड को कॉल करें। पेज अनलोड का पता लगाने का एक तरीका यह है कि वर्तमान पृष्ठ पर एक webelement प्राप्त करें और तब तक प्रतीक्षा करें जब तक कि यह बासी न हो जाए। obeythetestinggoat.com/…
जॉर्ज

6
FYI करें - अभी भी ऊपर ग्वारेंटी नहीं है कि पृष्ठ पूरा हो गया है - बस यह कि डोम तैयार है। कोई भी dojo / jquery अभी भी गतिशील रूप से पृष्ठ पर तत्वों का निर्माण कर सकता है ताकि आपको उनके साथ बातचीत करने से पहले गतिशील तत्वों की प्रतीक्षा करने की आवश्यकता हो।
जॉर्ज

3
विदित हो कि यह विधि केवल DOM की जाँच करती है। यदि आप Ajax या AngularJS का उपयोग करते हैं, तो यह काम नहीं करेगा क्योंकि कुछ अतुल्यकालिक कॉल होंगे जिन्हें दस्तावेज द्वारा पहले से ही पता नहीं लगाया जा सकता है।
होमवेकर

3
यह C # कोड है। यह जावा के साथ काम नहीं करता है, और जावा के बारे में पूछे गए सवाल ।

89

वर्ग WebDriverWait का उपयोग करें

यहां भी देखें

आप कुछ तत्व दिखाने की उम्मीद कर सकते हैं। C # में कुछ इस तरह:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));

यह बहुत अच्छा काम किया। समस्या को हल करने का यह एक बहुत अच्छा आधुनिक तरीका है।
क्रेजी डार्ट

3
@ EmmanuelAngelo.R TimeSpan एक .Net डेटा संरचना है।
rjzii

12
क्या होगा अगर मुझे पता नहीं है कि पृष्ठ पर कौन सा तत्व होगा?
JustGoscha

3
यह किसी विशेष तत्व को लोड करने के लिए इंतजार करने के लिए काम करेगा न कि पूरे पेज के लिए।
xyz

1
यह बिल्कुल गारंटी नहीं देता है कि एक तत्व पूरी तरह से भरा हुआ होगा और न ही सवाल का जवाब देगा। इसे कोई कैसे उभार सकता है?
बोरिस डी। तेहारोव

36

यदि आप ड्राइवर के निहित इंतजार को निर्धारित करते हैं, तो जिस findElementतत्व को आप लोड किए गए पृष्ठ पर होने की उम्मीद करते हैं, उस विधि पर कॉल करें , वेबड्राइवर उस तत्व के लिए मतदान करेगा जब तक कि वह तत्व नहीं ढूंढता है या समय आउट मान तक नहीं पहुंचता है।

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

source: निहित-प्रतीक्षा


3
यह पेज लोड की प्रतीक्षा में मदद नहीं करेगा।
xyz

इसका मतलब है कि यह 10 सेकंड के दौरान कुछ करने की कोशिश करेगा, इससे पहले कि यह अपवाद को बढ़ाए। इसलिए यह सुनिश्चित नहीं किया जा सकता है कि इसमें 10 सेकंड की देरी होगी।
9

1
@xyz - यह मदद क्यों नहीं करेगा?
मास्टरजेओ 2

@ testerjoe2 यह तब तक इंतजार करता है जब तक कि विशेष तत्व नहीं मिल जाता है, सवाल यह है कि पेज लोड के लिए इंतजार कैसे किया जाए।
xyz

35

सामान्य तौर पर, सेलेनियम 2.0 के साथ वेब ड्राइवर को केवल कॉलिंग कोड पर नियंत्रण वापस करना चाहिए, क्योंकि यह निर्धारित किया गया है कि पृष्ठ लोड हो गया है। यदि ऐसा नहीं होता है, तो आप कॉल कर सकते हैं waitforelemement, जो चक्र कॉलिंग को findelementतब तक प्राप्त करता है जब तक कि यह नहीं मिलता है या टाइम आउट (टाइम आउट सेट किया जा सकता है)।


2
पॉल के जवाब में जोड़ना। कृपया इसे भी देखें stackoverflow.com/questions/5858743/…
माखन

27
दुर्भाग्य से, सेलेनियम 2 सभी मामलों में पेज लोड होने की प्रतीक्षा नहीं करता है। उदाहरण के लिए WebElement: क्लिक करें () प्रतीक्षा नहीं करता है और यह स्पष्ट रूप से संबंधित Javadoc में कहा गया है। हालांकि, वे यह नहीं बताते कि मैं लोड किए जाने वाले नए पृष्ठ के लिए कैसे जांच कर सकता हूं। If click() causes a new page to be loaded via an event or is done by sending a native event (which is a common case on Firefox, IE on Windows) then the method will not wait for it to be loaded and the caller should verify that a new page has been loaded.
सेबी

से डॉक ..और जब तक लोड पूर्ण विधि को अवरुद्ध कर देगा ...
xyz

2
@ कर्ण: हां, सिद्धांत रूप में यह हमेशा होना चाहिए और व्यवहार में यह ज्यादातर समय होता है। उस समय सेलेनियम का उपयोग करने पर प्रकाश डाला गया था कि कई बार ऐसा लगता था कि पृष्ठ लोड करना समाप्त कर चुका था, लेकिन यह नहीं था। मैंने हाल ही में सेलेनियम का उपयोग नहीं किया है इसलिए यह अभी भी हो सकता है या नहीं भी हो सकता है।
पॉल हैडफील्ड

3
मैं सहमत हूं: विशेष रूप से इंटरनेट एक्सप्लोरर चालक छोटी गाड़ी है और कुछ मामलों में तुरंत नियंत्रण वापस कर देता है, भले ही एक पृष्ठ अभी भी लोड हो रहा है। यह मेरा मामला है, मैंने एक प्रतीक्षा का उपयोग करते हुए कहा JavascriptExecutor, "पूर्ण" होने के लिए document.readyState की प्रतीक्षा कर रहा है । सेलेनियम से ब्राउज़र तक राउंड ट्रिप की वजह से, दौड़ की स्थिति का अनुमान लगाया गया है, और यह "हमेशा" मेरे लिए काम करता है। "क्लिक ()" के बाद जब मैं पृष्ठ को लोड करने की उम्मीद करता हूं, तो मैं स्पष्ट रूप से रीडिस्टेट के लिए (WebDriverWait का उपयोग करके) प्रतीक्षा करता हूं। ]
डाम्सफील्ड

22

रूबी कार्यान्वयन:

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

17
पायथन समतुल्य: WebDriverWait (ड्राइवर, 10) .until (लैम्ब्डा d: d.execute_script ('डॉक्युमेंट.आर्टस्टेट') == 'पूर्ण')
ब्लेज़

2
पायथन उपरोक्त कोड का उपयोग करता है लेकिन इस लाइन को मत भूलना .. | selenium.webdriver.support.ui आयात से WebDriverWait
t3dodson

जब पृष्ठ पूरी तरह से लोड नहीं हुआ, तो मुझे एक तत्व पर क्लिक करने में समस्या हुई। पायथन में मैंने समय की कोशिश की। स्लीप (30)। इसने काम कर दिया। यह हमेशा अधिकतम 30 सेकंड के लिए इंतजार करेगा। मैंने तब निम्न कोड की कोशिश की और यह अब और अधिक कुशल है, जल्दी। WebDriverWait (ड्राइवर, 10) .until (लैम्ब्डा d: ड्राइवर .find_element_by_xpath ("// div [। = 'व्यवस्थापन']") पर क्लिक करें ())
रियाज़ लधानी

20

आप System.outलाइन को हटा सकते हैं । यह डीबग उद्देश्यों के लिए जोड़ा गया है।

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}

इस टिप्स के लिए धन्यवाद। मैं इसे अपने सेलेनियम हेल्पर में जोड़ता हूं; सीएफ javabox
9 अक्टूबर को boly38

17

ये सभी समाधान विशिष्ट मामलों के लिए ठीक हैं, लेकिन वे कुछ संभावित समस्याओं में से कम से कम एक से पीड़ित हैं:

  1. वे पर्याप्त सामान्य नहीं हैं - वे चाहते हैं कि आप समय से पहले जानना चाहते हैं कि कुछ विशिष्ट स्थिति आपके द्वारा लिए जा रहे पृष्ठ के लिए सही होगी (जैसे कुछ तत्व प्रदर्शित किया जाएगा)

  2. वे एक दौड़ की स्थिति के लिए खुले हैं जहां आप एक ऐसे तत्व का उपयोग करते हैं जो वास्तव में पुराने पृष्ठ के साथ-साथ नए पृष्ठ पर भी मौजूद है।

यहाँ एक सामान्य समाधान पर मेरा प्रयास है जो इस समस्या से बचा जाता है (पायथन में):

सबसे पहले, एक सामान्य "प्रतीक्षा" फ़ंक्शन (यदि आप चाहें तो 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()

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

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


मैं आपके वेब पेज को फिर से खोजने से पहले विशेष रूप से जावा कोड के लिए खोजता हूं जो आपके समाधान को लागू करता है। अब तक कुछ भी नहीं ...
andrew lorien

11

आप कक्षा का उपयोग भी ExpectedConditionsकर सकते हैं: किसी भी कार्य को आगे की कार्रवाई करने से पहले वेबपृष्ठ पर दिखाने के लिए किसी तत्व के लिए स्पष्ट रूप से प्रतीक्षा करें

ExpectedConditionsयदि तत्व दिखाई दे रहा है, तो यह निर्धारित करने के लिए आप कक्षा का उपयोग कर सकते हैं :

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));

ExpectedConditions class Javadocउन सभी स्थितियों की सूची देखें जिन्हें आप जांचने में सक्षम हैं।


11

जावा 7 के लिए इमरान का जवाब मिला:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });

10

यह वेबड्राइवर की एक गंभीर सीमा लगती है। स्पष्ट रूप से एक तत्व की प्रतीक्षा करने से पृष्ठ लोड होने का अर्थ नहीं होगा, विशेष रूप से DOM को पूरी तरह से (पहले से ही राज्य) बनाया जा सकता है जिससे JS अभी भी निष्पादित हो रहा है और CSS और छवियां अभी भी लोड हो रही हैं।

मेरा मानना ​​है कि सब कुछ शुरू होने के बाद सबसे सरल समाधान जेएस वेरिएबल को ऑनलोड घटना पर सेट करना है और सेलेनियम में इस जेएस वेरिएबल की प्रतीक्षा करें।


यदि साइट संशोधित करने के लिए आपकी है तो यह आसान है!
रिस्टोरियरपोस्ट

हां, jQuery.js को अंजाम देने के लिए बस एक जावास्क्रिप्ट का उपयोग करें। फिर आप jQuery लोड घटनाओं तक पहुंच सकते हैं। यह एक दुर्लभ मामला है जब यह आवश्यक है। मानक वेबड्राइवर के पास 98% उचित प्रतीक्षा करने के लिए पर्याप्त शक्ति है।
djangofan 16

@djangofan इसका एक उदाहरण देखने के लिए बहुत बढ़िया होगा ... मैं एक सामने वाला लड़का हूं, तो यकीन नहीं होता कि जावास्क्रिप्ट कैसे या कहां प्रयोग की जाती है।
ब्रैडगर्न्स

@ ब्रैडगर्न्स - ठीक है, मेरे प्रोजेक्ट को यहाँ देखें: github.com/djangofan/jquery-growl-selenium-example । यदि आपके पास उस उदाहरण को समाप्त करने के लिए बैंडविड्थ है, तो मैं उस परीक्षण परियोजना में काम करने के लिए jGrowl को काफी नहीं मिल सका, हालांकि jQuery ठीक काम करता है।
djangofan

1
@BradGreens djangofan की टिप्पणी के अलावा मेरा जवाब यहाँ देखें: stackoverflow.com/a/24638792/730326
jmathew

9

यदि आप किसी विशिष्ट तत्व को लोड करने के लिए इंतजार करना चाहते हैं, तो आप isDisplayed()विधि का उपयोग कर सकते हैं RenderedWebElement:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));

    // If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}

( 5 मिनट से शुरू होने वाली गाइड का उदाहरण )


4
एक साल बाद (वर्तमान सेलेनियम संस्करण 2.23.1), RenderedWebElementएपीआई में नहीं है। हालाँकि, isDisplayed()विधि अब सीधे उपलब्ध है WebElement
पेट्र जेनेक

1
मतदान भयानक है जब इसे टाला जा सकता है।
रिस्टोरियरपोस्ट

8

इस प्रतीक्षा में स्पष्ट रूप से प्रतीक्षा या सशर्त प्रतीक्षा करें जब तक कि यह शर्त न दी जाए।

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

यह 60 सेकंड के लिए प्रत्येक वेब तत्व की प्रतीक्षा करेगा।

उस समय तक पृष्ठ पर प्रत्येक तत्व की प्रतीक्षा के लिए अनुमानित प्रतीक्षा का उपयोग करें।

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

यह 60 सेकंड के लिए प्रत्येक वेब तत्व की प्रतीक्षा करेगा।


5

दिए गए समय तक पृष्ठ पर प्रत्येक तत्व की प्रतीक्षा के लिए अनुमानित प्रतीक्षा का उपयोग करें।

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

यह 30 सेकंड के लिए पृष्ठ पर हर तत्व की प्रतीक्षा करता है।

एक और प्रतीक्षा स्पष्ट रूप से इस प्रतीक्षा में सशर्त प्रतीक्षा या सशर्त प्रतीक्षा है जब तक कि दी गई स्थिति नहीं है।

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

आईडी में स्टेटिक एलिमेंट आईडी देते हैं, जो पेज पर लोड होते ही प्रदर्शित होता है।


4

मुझे आश्चर्य है कि आम तौर पर आप पहली पसंद नहीं थे क्योंकि आप आमतौर पर जानते हैं कि आप उस पृष्ठ पर किस तत्व के साथ बातचीत करेंगे जिसे आप लोड करने की प्रतीक्षा कर रहे हैं। मेरा दृष्टिकोण हमेशा विधेयकों / कार्यों जैसे / waitForElementByID(String id)और waitForElemetVisibleByClass(String className)आदि का निर्माण करने के लिए रहा है और फिर इनका उपयोग और पुन: उपयोग करें जहाँ भी मुझे उनकी आवश्यकता है, यह एक पृष्ठ लोड या पृष्ठ सामग्री परिवर्तन के लिए हो, जिसका मैं इंतजार कर रहा हूं।

उदाहरण के लिए,

मेरी परीक्षा कक्षा में:

driverWait.until(textIsPresent("expectedText");

मेरे टेस्ट क्लास पैरेंट में:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}

हालांकि यह बहुत कुछ लगता है, यह आपके लिए बार-बार जाँच का ध्यान रखता है और समय-समय पर अंतिम प्रतीक्षा समय के साथ कितनी बार जाँच की जा सकती है इसके लिए अंतराल। इसके अलावा, आप इस तरह के तरीकों का पुन: उपयोग करेंगे।

इस उदाहरण में, मूल वर्ग को परिभाषित किया और आरंभ WebDriver driverकिया WebDriverWait driverWait

आशा है कि ये आपकी मदद करेगा।


यह मेरी मदद करता है! इस उत्कृष्ट नमूने के लिए धन्यवाद। मैं इसे अपने सेलेनियम हेल्पर में जोड़ता हूं; सीएफ javabox
boly38

4

वेबड्राइवर के लिए जावा बाइंडिंग का उपयोग करते समय पेज लोड के लिए इंतजार करने का सबसे अच्छा तरीका पेजएक्टीविटी के साथ पेज ऑब्जेक्ट डिज़ाइन पैटर्न का उपयोग करना है। यह आपको इसका उपयोग करने की अनुमति देता है AjaxElementLocatorFactoryजो इसे डालने के लिए बस आपके सभी तत्वों के लिए एक वैश्विक प्रतीक्षा के रूप में कार्य करता है। इसमें ड्रॉप-बॉक्स या जटिल जावास्क्रिप्ट संक्रमण जैसे तत्वों की सीमाएं हैं, लेकिन यह आवश्यक कोड की मात्रा को काफी कम कर देगा और परीक्षण समय को गति देगा। इस ब्लॉगपोस्ट में एक अच्छा उदाहरण पाया जा सकता है। कोर जावा की बुनियादी समझ है।

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html


4

NodeJS समाधान:

में 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)


4

यहाँ एक जावा 8 संस्करण है जो वर्तमान में सबसे अधिक उत्तर दिया गया है :

WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));

जहां myDriverएक WebDriverवस्तु (पहले घोषित) है।

नोट : ध्यान रखें कि यह विधि ( document.readyState) केवल DOM की जाँच करती है।


4

अपनी स्क्रिप्ट में फ़ंक्शन के नीचे कॉल करें, यह तब तक इंतजार करेगा जब तक जावास्क्रिप्ट का उपयोग करके पृष्ठ लोड नहीं किया जाता है

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

मैंने शून्य के लिए बूलियन को बदल दिया है, लेकिन क्रोम में काम नहीं कर रहा है
nosequeweaponer

3
/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}

/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}

आप दस्तावेज़ से एक तत्व में बदल सकते हैं, उस स्थिति में जहां दस्तावेज़ का केवल एक हिस्सा बदला जा रहा है।

यह तकनीक तब से जवाब से प्रेरित थी।


3

सेलेनियमवाटर :

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

और आप इसका उपयोग करते हैं :

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}

3

आप नीचे दिए गए मौजूदा तरीके का उपयोग कर सकते हैं कि पेजेजलडाईटाउट के लिए समय निर्धारित करें नीचे दिए गए उदाहरण में यदि पृष्ठ को लोड होने में 20 सेकंड से अधिक समय लग रहा है, तो यह पेज रीलोड के अपवाद को फेंक देगा

 WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)

2

वेबपृष्ठ पर किसी तत्व को दिखाने के लिए आप स्पष्ट रूप से प्रतीक्षा कर सकते हैं, इससे पहले कि आप कोई कार्रवाई कर सकें (जैसे element.click ())

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(new ExpectedCondition<WebElement>(){
        @Override
        public WebElement apply(WebDriver d) {
        return d.findElement(By.id("myDynamicElement"));
}});

यह वही है जो मैंने एक समान परिदृश्य के लिए इस्तेमाल किया और यह ठीक काम करता है।


मुझे लगता है कि Driver.get कोड पर नियंत्रण वापस करने से पहले ऑनलोड फ़ंक्शन के समाप्त होने तक इंतजार करता है, जब तक कि पेज में ajax का एक बहुत कुछ न हो
goh

2

मेरा आसान तरीका:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;

        while (System.currentTimeMillis() < end) {

            if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }

2

मैंने जो सबसे अच्छा तरीका देखा है, उसका उपयोग करना है stalenessOf ExpectedCondition करना है, पुराने पेज के बासी होने का इंतजार करना है।

उदाहरण:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);

WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));

यह पुराने HTML टैग के बासी होने के लिए दस सेकंड तक प्रतीक्षा करेगा, और यदि ऐसा नहीं होता है तो एक अपवाद फेंक दें।


1
एक वेबलेमेंट बासी जा रहा है एक नया पृष्ठ लोड हो रहा है मतलब नहीं है।
कोरी गोल्डबर्ग

ज़रूर, लेकिन इसका मतलब है कि पुराने पृष्ठ को उतारना समाप्त हो गया है। मेरे अनुभव में, यह जानना उतना ही महत्वपूर्ण है कि पुराना पृष्ठ कब उतार दिया गया है, या यदि यह किसी कारण से रुका हुआ है।
forresthopkinsa

बेशक, मैं आमतौर पर पूर्ण अनलोड / लोड प्रक्रिया प्राप्त करने के लिए अन्य परीक्षणों के साथ संयोजन में stalenessOf का उपयोग करता हूं।
forresthopkinsa

2

मैं नोड + सेलेनियम-वेबड्राइवर का उपयोग करता हूं (जो संस्करण अब 3.5.0 है)। मैं इसके लिए क्या करता हूं:

var webdriver = require('selenium-webdriver'),
    driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
  return state === 'complete';
}))

2

आप प्रतीक्षा का उपयोग कर सकते हैं। सेलेनियम में मूल रूप से प्रतीक्षा के 2 प्रकार हैं

  • अधूरा इंतजार
  • स्पष्ट प्रतीक्षा करें

- अधूरा इंतजार

यह बहुत सरल है कृपया नीचे सिंटैक्स देखें:

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

- स्पष्ट प्रतीक्षा करें

इस प्रतीक्षा में स्पष्ट रूप से प्रतीक्षा या सशर्त प्रतीक्षा करें जब तक कि दी गई स्थिति उत्पन्न न हो जाए।

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

आप अन्य गुणों का उपयोग कर सकते हैं जैसे visblityOf(),visblityOfElement()



2

मेरे मामले में, मैंने पेज लोड की स्थिति जानने के लिए निम्नलिखित का उपयोग किया। हमारे आवेदन में लोडिंग जिफ़ (एस) मौजूद हैं और, मैं उन्हें स्क्रिप्ट में अवांछित प्रतीक्षा समय को समाप्त करने के लिए निम्नानुसार सुनता हूं।

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

जहाँ xpath HTML DOM में gif का पता लगाता है। इसके बाद, आप अपनी कार्रवाई के तरीकों को भी लागू कर सकते हैं क्लिक करें।

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }

2

इन सभी उत्तरों के लिए मनुष्य को बहुत अधिक कोड की आवश्यकता होती है। यह एक बहुत ही साधारण चीज होनी चाहिए।

सिर्फ वेबड्राइवर और जाँच के साथ कुछ सरल जावास्क्रिप्ट क्यों नहीं इंजेक्ट करें। यह मैं अपने webscraper वर्ग में उपयोग की जाने वाली विधि है। जावास्क्रिप्ट बहुत ही बुनियादी है भले ही आप js नहीं जानते हों।

    def js_get_page_state(self):        
    """
    Javascript for getting document.readyState
    :return: Pages state.

    More Info: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
    """
    ready_state = self.driver.execute_script('return document.readyState')
    if ready_state == 'loading':
        self.logger.info("Loading Page...")
    elif ready_state == 'interactive':
        self.logger.info("Page is interactive")
    elif ready_state == 'complete':
        self.logger.info("The page is fully loaded!")
    return ready_state

1

एक क्लिक के बाद पृष्ठ लोड के लिए प्रतीक्षा करने के लिए सेलेनियम कैसे प्राप्त करें निम्नलिखित दिलचस्प दृष्टिकोण प्रदान करता है:

  1. WebElementपुराने पृष्ठ से एक संदर्भ संग्रहीत करें ।
  2. लिंक पर क्लिक करें।
  3. WebElementजब तक StaleElementReferenceExceptionफेंका नहीं जाता तब तक ऑपरेशन जारी रखें ।

नमूना कोड:

WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
    try
    {
        link.isDisplayed();
        return false;
    }
    catch (StaleElementReferenceException unused)
    {
        return true;
    }
});

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

4
यह आपको यह बताने के लिए नहीं जा रहा है कि क्या वर्तमान पृष्ठ लोड है, यह आपको यह बताने जा रहा है कि क्या अंतिम पृष्ठ (विशेष रूप से एक तत्व) अनलोड है । लोड करने के लिए आपको अभी भी वर्तमान पृष्ठ की प्रतीक्षा करनी होगी। BTW, आप ऊपर के साथ अपने कोड को बदल सकते हैं new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(element))
जेफ़सी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.