सेलेनियम वेबड्राइवर: जावास्क्रिप्ट लोड करने के लिए जटिल पृष्ठ की प्रतीक्षा करें


103

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

  • एक JavaScript स्क्रिप्ट फ़ॉर्म WebDriver चलाएं और परिणाम को document.body.innerHTMLएक स्ट्रिंग चर में संग्रहीत करें body
  • bodyचर की तुलना पिछले संस्करण से करें body। यदि वे समान हैं तो एक वेतन वृद्धि notChangedCountसेट notChangedCountकरें अन्यथा शून्य पर सेट करें।
  • एक litte time (उदाहरण के लिए 50 ms) की प्रतीक्षा करें।
  • यदि पृष्ठ कुछ समय के लिए नहीं बदला है (उदाहरण के लिए 500 एमएस) तो notChangedCount >= 10पहले चरण पर लूप अन्यथा लूप से बाहर निकलें।

क्या आपको लगता है कि यह एक वैध समाधान है?


findElement () इंतजार नहीं करता - आपका क्या मतलब है?
रोस्टिस्लाव मैटल

1
findElementउपलब्ध होने के लिए एक तत्व की प्रतीक्षा करता है, लेकिन कभी-कभी जावास्क्रिप्ट कोड से पहले तत्व पूरी तरह से उपलब्ध होता है, इसलिए यह एक विकल्प नहीं है।
Psadac

मैं इसे भूल गया - मुझे WebDriverWait और ExpectedCondition का उपयोग करने की आदत है, यह अधिक लचीला है।
रोस्टिस्लाव मतल

जवाबों:


73

यदि कोई वास्तव में एक सामान्य और हमेशा लागू होने वाला उत्तर जानता था, तो यह हर जगह युगों पहले लागू किया गया था और हमारे जीवन को बहुत आसान बना देगा।

कई चीजें हैं जो आप कर सकते हैं, लेकिन उनमें से हर एक में एक समस्या है:

  1. जैसा कि अश्विन प्रभु ने कहा, यदि आप स्क्रिप्ट को अच्छी तरह से जानते हैं, तो आप इसके व्यवहार का निरीक्षण कर सकते हैं और इसके कुछ चरों को ट्रैक कर सकते हैं windowया documentफिर यह समाधान, हालांकि, यह हर किसी के लिए नहीं है और इसका उपयोग केवल और केवल एक सीमित सेट पर ही किया जा सकता है। पृष्ठों की है।

  2. HTML कोड को देखकर आपका समाधान और चाहे वह कुछ समय के लिए बदल दिया गया हो या नहीं, बुरा नहीं है (साथ ही, मूल और संपादित नहीं किए गए HTML को सीधे प्राप्त करने की एक विधि है WebDriver), लेकिन:

    • यह वास्तव में एक पृष्ठ का दावा करने के लिए एक लंबा समय लेता है और परीक्षण को काफी लंबा कर सकता है।
    • आप कभी नहीं जानते कि सही अंतराल क्या है। स्क्रिप्ट कुछ बड़ा डाउनलोड कर रही हो सकती है जिसमें 500 से अधिक एमएस हो। हमारी कंपनी के आंतरिक पृष्ठ पर कई स्क्रिप्ट हैं जो IE में कई सेकंड लेती हैं। आपका कंप्यूटर अस्थायी रूप से संसाधनों पर कम हो सकता है - यह कहें कि एक एंटीवायरस आपके सीपीयू को पूरी तरह से काम कर देगा, तो 500 एमएस एक नॉनप्लेक्स स्क्रिप्ट के लिए बहुत छोटा हो सकता है।
    • कुछ स्क्रिप्ट्स कभी नहीं की जाती हैं। वे खुद को कुछ देरी से बुलाते हैं ( setTimeout()) और बार-बार काम करते हैं और संभवतः हर बार चलने पर HTML को बदल सकते हैं। गंभीरता से, हर "वेब 2.0" पेज करता है। स्टैक ओवरफ्लो भी। आप उपयोग की जाने वाली सबसे सामान्य विधियों को अधिलेखित कर सकते हैं और उन लिपियों पर विचार कर सकते हैं जो उन्हें पूर्ण के रूप में उपयोग करते हैं, लेकिन ... आप सुनिश्चित नहीं हो सकते।
    • यदि स्क्रिप्ट HTML को बदलने के अलावा कुछ और करता है तो क्या होगा? यह हजारों चीजें कर सकता है, न कि केवल कुछ innerHTMLमजेदार।
  3. इस पर आपकी मदद करने के लिए उपकरण हैं। अर्थात् प्रगति श्रोताओं के साथ मिलकर nsIWebProgressListener और कुछ अन्य। हालांकि, इसके लिए ब्राउज़र समर्थन भयानक है। फ़ायरफ़ॉक्स इसे FF4 से आगे (अभी भी विकसित) से समर्थन करने की कोशिश करने लगा, IE में IE9 में मूल समर्थन है।

और मुझे लगता है कि मैं जल्द ही एक और दोषपूर्ण समाधान के साथ आ सकता हूं। तथ्य यह है - यह बताने के लिए कोई निश्चित जवाब नहीं है कि "अब पृष्ठ पूरा हो गया है" क्योंकि हमेशा की स्क्रिप्ट्स अपना काम कर रही हैं। वह चुनें जो आपको सबसे अच्छा काम करता है, लेकिन इसकी कमियों से सावधान रहें।


31

धन्यवाद अश्विन!

मेरे मामले में मुझे कुछ तत्व में jquery प्लगइन निष्पादन की प्रतीक्षा करनी चाहिए .. विशेष रूप से "qtip"

आपके संकेत के आधार पर, इसने मेरे लिए पूरी तरह से काम किया:

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

नोट: मैं वेबड्राइवर 2 का उपयोग कर रहा हूं


2
यह मेरे लिए भी बहुत अच्छा काम करता है। मेरे मामले में, पृष्ठ को लोड करने के ठीक बाद जावास्क्रिप्ट द्वारा एक तत्व को संशोधित किया गया था, और सेलेनियम उस निहित का इंतजार नहीं कर रहा था।
Noxxys

2
प्रेडिकेट कहां से आता है? कौन सा आयात ??
अमादो सलादिनो

@AmadoSaladino "आयात com.google.common.base.Predicate?" Google lib guava -15.0 लिंक से: mvnrepository.com/artifact/com.google.guava/guava/15.0 नए संस्करण हैं 27.0 आप इसे आज़मा सकते हैं!
एडुआर्डो फैब्रिकियो

26

लोडिंग खत्म करने के लिए आपको जावास्क्रिप्ट और jQuery की प्रतीक्षा करनी होगी। जावास्क्रिप्ट की जाँच करें कि क्या jQuery.activeहै 0और क्या document.readyStateहै complete, जिसका अर्थ है कि JS और jQuery लोड पूरा हो गया है।

public boolean waitForJStoLoad() {

    WebDriverWait wait = new WebDriverWait(driver, 30);

    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
          return ((Long)executeJavaScript("return jQuery.active") == 0);
        }
        catch (Exception e) {
          return true;
        }
      }
    };

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

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

2
निश्चित नहीं है कि यह हर परिस्थिति में काम करेगा , लेकिन यह मेरे उपयोग के मामले के लिए एक उपचार का काम करता है
डेवह

1
यह मेरे लिए भी काम करता है लेकिन एक मुश्किल हिस्सा है: मान लीजिए कि आपका पृष्ठ पहले से लोड है। यदि आप एक तत्व के साथ बातचीत करते हैं [जैसे एक .click () भेजें या इसे कुछ कुंजियाँ भेजें] और फिर आप यह जांचना चाहते हैं कि आपका पृष्ठ कब समाप्त हो रहा है प्रसंस्करण में आपको देरी जोड़ने की आवश्यकता है: उदाहरण के लिए क्लिक करें (), नींद (0.5 सेकंड) ), जब तक प्रतीक्षा करें (तैयार = 'पूरा' और jQuery.active == 0)। यदि आप नींद नहीं जोड़ते हैं, तो परीक्षण के समय iQuery सक्रिय नहीं होगा! (यह पता लगाने में मुझे कुछ घंटे लगे, इसलिए मैंने इसे साझा करने के लिए सोचा)
फिवोस विलानकिस

document.readyState == 'complete' && jQuery.active == 0महान काम करता है, लेकिन प्रतिक्रिया के लिए ऐसा कुछ है? चूंकि वे चेक अभी भी डेटा / घटक को लोड करने की प्रतिक्रिया को नहीं पकड़ेंगे?
Rain9333

10

क्या जेएस लाइब्रेरी खिड़की पर किसी भी ज्ञात चर को परिभाषित / प्रारंभ करती है?

यदि ऐसा है तो आप चर के प्रकट होने की प्रतीक्षा कर सकते हैं। आप उपयोग कर सकते हैं

((JavascriptExecutor)driver).executeScript(String script, Object... args)

इस स्थिति के लिए परीक्षण करने के लिए (जैसे कुछ window.SomeClass && window.SomeClass.variable != null) : और एक बूलियन true/ लौटाएं false

इसमें लपेटें WebDriverWait, और स्क्रिप्ट के वापस आने तक प्रतीक्षा करें true


7

मेरे पास एक ही मुद्दा था। यह समाधान मेरे लिए WebDriverDoku से काम करता है:

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

http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp


धन्यवाद। लिंक में जो कोड है, वह मेरे लिए काम करता है,
ecamur

7

अगर आपको तत्वों के साथ बातचीत करने से पहले पृष्ठ पर html के स्थिर होने की प्रतीक्षा करनी है, तो आप समय-समय पर DOM पर क्लिक कर सकते हैं और परिणामों की तुलना कर सकते हैं, यदि DOM दिए गए पोल समय के भीतर समान हैं, तो आप स्वर्ण। ऐसा कुछ जहां आप अधिकतम प्रतीक्षा समय और पृष्ठ के बीच के समय की तुलना करने से पहले मतदान करते हैं। सरल और प्रभावी।

public void waitForJavascript(int maxWaitMillis, int pollDelimiter) {
    double startTime = System.currentTimeMillis();
    while (System.currentTimeMillis() < startTime + maxWaitMillis) {
        String prevState = webDriver.getPageSource();
        Thread.sleep(pollDelimiter); // <-- would need to wrap in a try catch
        if (prevState.equals(webDriver.getPageSource())) {
            return;
        }
    }
}

1
मैं यहां ध्यान देना चाहूंगा कि मैंने एक मध्यम आकार के पृष्ठ को दो बार सर्वेक्षण करने में लगने वाले समय को लॉग किया, फिर जावा में उन तारों की तुलना की और इसमें 20 मी से अधिक का समय लगा।
TheFreddyKilo

2
सबसे पहले मैंने इसे एक गंदा समाधान पाया, लेकिन यह बहुत अच्छा काम करता है और इसमें चर क्लाइंट साइड सेट करना शामिल नहीं है। एक गुफा एक पृष्ठ हो सकती है जिसे लगातार जावास्क्रिप्ट (यानी जावास्क्रिप्ट घड़ी) द्वारा बदला जा रहा है, लेकिन मेरे पास ऐसा नहीं है इसलिए यह काम करता है!
पीटर

4

नीचे दिया गया कोड मेरे मामले में पूरी तरह से काम करता है - मेरे पेज में जटिल जावा स्क्रिप्ट हैं

public void checkPageIsReady() {

  JavascriptExecutor js = (JavascriptExecutor)driver;


  //Initially bellow given if condition will check ready state of page.
  if (js.executeScript("return document.readyState").toString().equals("complete")){ 
   System.out.println("Page Is loaded.");
   return; 
  } 

  //This loop will rotate for 25 times to check If page Is ready after every 1 second.
  //You can replace your value with 25 If you wants to Increase or decrease wait time.
  for (int i=0; i<25; i++){ 
   try {
    Thread.sleep(1000);
    }catch (InterruptedException e) {} 
   //To check page ready state.
   if (js.executeScript("return document.readyState").toString().equals("complete")){ 
    break; 
   }   
  }
 }

स्रोत - सेलेनियम वेबड्राइवर में लोड / तैयार होने के लिए पेज का इंतजार कैसे करें


2
आपको उन लूपों के बजाय सेलेनियम
वेट्स

4

पृष्ठ पर किसी भी तत्व को खोजने से पहले पृष्ठ लोड होने पर जांचने के लिए दो शर्तों का उपयोग किया जा सकता है:

WebDriverWait wait = new WebDriverWait(driver, 50);

रेडीस्टेट के नीचे का उपयोग पेज लोड होने तक प्रतीक्षा करेगा

wait.until((ExpectedCondition<Boolean>) wd ->
   ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));

नीचे JQuery प्रतीक्षा करेगा जब तक डेटा लोड नहीं किया गया है

  int count =0;
            if((Boolean) executor.executeScript("return window.jQuery != undefined")){
                while(!(Boolean) executor.executeScript("return jQuery.active == 0")){
                    Thread.sleep(4000);
                    if(count>4)
                        break;
                    count++;
                }
            }

इन जावास्क्रिप्ट के बाद webOlement को खोजने का प्रयास करें।

WebElement we = wait.until(ExpectedConditions.presenceOfElementLocated(by));

1
सेलेनियम भी डिफ़ॉल्ट रूप से ऐसा करता है, यह आपकी स्क्रिप्ट में कुछ अतिरिक्त कोड निष्पादन समय जोड़ देगा (जो अतिरिक्त चीजों को लोड करने के लिए पर्याप्त समय हो सकता है, लेकिन फिर नहीं हो सकता है)
Ardesco

2

मैंने अपने डेवलपर्स से एक जावास्क्रिप्ट चर "आइसप्रोसेसिंग" बनाने के लिए कहा, जिसे मैं ("एई" ऑब्जेक्ट में) एक्सेस कर सकता हूं, जब वे सेट करना शुरू करते हैं, जब चीजें चलती हैं और चीजें साफ हो जाती हैं। मैं इसे एक संचयक में चलाता हूं जो इसे हर 100 एमएस में जांचता है जब तक कि यह बिना किसी बदलाव के कुल 500 एमएस के लिए एक पंक्ति में पांच नहीं हो जाता। अगर 30 सेकंड बीत जाते हैं, तो मैं एक अपवाद फेंक देता हूं क्योंकि तब तक कुछ हो जाना चाहिए था। यह C # में है।

public static void WaitForDocumentReady(this IWebDriver driver)
{
    Console.WriteLine("Waiting for five instances of document.readyState returning 'complete' at 100ms intervals.");
    IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
    int i = 0; // Count of (document.readyState === complete) && (ae.isProcessing === false)
    int j = 0; // Count of iterations in the while() loop.
    int k = 0; // Count of times i was reset to 0.
    bool readyState = false;
    while (i < 5)
    {
        System.Threading.Thread.Sleep(100);
        readyState = (bool)jse.ExecuteScript("return ((document.readyState === 'complete') && (ae.isProcessing === false))");
        if (readyState) { i++; }
        else
        {
            i = 0;
            k++;
        }
        j++;
        if (j > 300) { throw new TimeoutException("Timeout waiting for document.readyState to be complete."); }
    }
    j *= 100;
    Console.WriteLine("Waited " + j.ToString() + " milliseconds. There were " + k + " resets.");
}

1

इसे ठीक से करने के लिए, आपको अपवादों को संभालने की आवश्यकता है।

यहाँ है कि मैं एक iFrame के लिए प्रतीक्षा कैसे करता हूं। इसके लिए आवश्यक है कि आपका JUnit परीक्षण वर्ग पृष्ठ ऑब्जेक्ट में RemoteWebDriver का उदाहरण दें:

public class IFrame1 extends LoadableComponent<IFrame1> {

    private RemoteWebDriver driver;

    @FindBy(id = "iFrame1TextFieldTestInputControlID" )
    public WebElement iFrame1TextFieldInput;

    @FindBy(id = "iFrame1TextFieldTestProcessButtonID" )
    public WebElement copyButton;

    public IFrame1( RemoteWebDriver drv ) {
        super();
        this.driver = drv;
        this.driver.switchTo().defaultContent();
        waitTimer(1, 1000);
        this.driver.switchTo().frame("BodyFrame1");
        LOGGER.info("IFrame1 constructor...");
    }

    @Override
    protected void isLoaded() throws Error {        
        LOGGER.info("IFrame1.isLoaded()...");
        PageFactory.initElements( driver, this );
        try {
            assertTrue( "Page visible title is not yet available.", driver
     .findElementByCssSelector("body form#webDriverUnitiFrame1TestFormID h1")
                    .getText().equals("iFrame1 Test") );
        } catch ( NoSuchElementException e) {
            LOGGER.info("No such element." );
            assertTrue("No such element.", false);
        }
    }

    @Override
    protected void load() {
        LOGGER.info("IFrame1.load()...");
        Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
                .withTimeout(30, TimeUnit.SECONDS)
                .pollingEvery(5, TimeUnit.SECONDS)
                .ignoring( NoSuchElementException.class ) 
                .ignoring( StaleElementReferenceException.class ) ;
            wait.until( ExpectedConditions.presenceOfElementLocated( 
            By.cssSelector("body form#webDriverUnitiFrame1TestFormID h1") ) );
    }
....

नोट: आप यहां मेरा संपूर्ण कार्य उदाहरण देख सकते हैं


1

के लिए nodejsसेलेनियम पुस्तकालय, मैं निम्नलिखित स्निपेट का इस्तेमाल किया। मेरे मामले में, मैं दो ऑब्जेक्ट्स की तलाश कर रहा था जो विंडो में जोड़े जाते हैं, जो इस उदाहरण में हैं <SOME PROPERTY>, 10000टाइमआउट मिलीसेकंड है, <NEXT STEP HERE>जो कि विंडो पर गुण पाए जाने के बाद होता है।

driver.wait( driver => {
    return driver.executeScript( 'if(window.hasOwnProperty(<SOME PROPERTY>) && window.hasOwnProperty(<SOME PROPERTY>)) return true;' ); }, 10000).then( ()=>{
        <NEXT STEP HERE>
}).catch(err => { 
    console.log("looking for window properties", err);
});

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

यहाँ मेरे अपने कोड से है:
Window.setTimeout केवल तभी निष्पादित होता है जब ब्राउज़र निष्क्रिय होता है।
तो फ़ंक्शन को पुनरावर्ती रूप से कॉल करना (42 बार) ब्राउज़र में कोई गतिविधि नहीं होने पर 100ms लेगा और यदि ब्राउज़र कुछ और करने में व्यस्त है तो बहुत अधिक।

    ExpectedCondition<Boolean> javascriptDone = new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver d) {
            try{//window.setTimeout executes only when browser is idle,
                //introduces needed wait time when javascript is running in browser
                return  ((Boolean) ((JavascriptExecutor) d).executeAsyncScript( 

                        " var callback =arguments[arguments.length - 1]; " +
                        " var count=42; " +
                        " setTimeout( collect, 0);" +
                        " function collect() { " +
                            " if(count-->0) { "+
                                " setTimeout( collect, 0); " +
                            " } "+
                            " else {callback(" +
                            "    true" +                            
                            " );}"+                             
                        " } "
                    ));
            }catch (Exception e) {
                return Boolean.FALSE;
            }
        }
    };
    WebDriverWait w = new WebDriverWait(driver,timeOut);  
    w.until(javascriptDone);
    w=null;

एक बोनस के रूप में काउंटर को document.readyState पर या jQuery के अजाक्स कॉल पर रीसेट किया जा सकता है या यदि कोई jQuery एनिमेशन चल रहा है (केवल अगर आपका ऐप ajax कॉल के लिए jQuery का उपयोग करता है ...)
...

" function collect() { " +
                            " if(!((typeof jQuery === 'undefined') || ((jQuery.active === 0) && ($(\":animated\").length === 0))) && (document.readyState === 'complete')){" +
                            "    count=42;" +
                            "    setTimeout( collect, 0); " +
                            " }" +
                            " else if(count-->0) { "+
                                " setTimeout( collect, 0); " +
                            " } "+ 

...

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

public static ExpectedCondition<Boolean> documentNotActive(final int counter){ 
    return new ExpectedCondition<Boolean>() {
        boolean resetCount=true;
        @Override
        public Boolean apply(WebDriver d) {

            if(resetCount){
                ((JavascriptExecutor) d).executeScript(
                        "   window.mssCount="+counter+";\r\n" + 
                        "   window.mssJSDelay=function mssJSDelay(){\r\n" + 
                        "       if((typeof jQuery != 'undefined') && (jQuery.active !== 0 || $(\":animated\").length !== 0))\r\n" + 
                        "           window.mssCount="+counter+";\r\n" + 
                        "       window.mssCount-->0 &&\r\n" + 
                        "       setTimeout(window.mssJSDelay,window.mssCount+1);\r\n" + 
                        "   }\r\n" + 
                        "   window.mssJSDelay();");
                resetCount=false;
            }

            boolean ready=false;
            try{
                ready=-1==((Long) ((JavascriptExecutor) d).executeScript(
                        "if(typeof window.mssJSDelay!=\"function\"){\r\n" + 
                        "   window.mssCount="+counter+";\r\n" + 
                        "   window.mssJSDelay=function mssJSDelay(){\r\n" + 
                        "       if((typeof jQuery != 'undefined') && (jQuery.active !== 0 || $(\":animated\").length !== 0))\r\n" + 
                        "           window.mssCount="+counter+";\r\n" + 
                        "       window.mssCount-->0 &&\r\n" + 
                        "       setTimeout(window.mssJSDelay,window.mssCount+1);\r\n" + 
                        "   }\r\n" + 
                        "   window.mssJSDelay();\r\n" + 
                        "}\r\n" + 
                        "return window.mssCount;"));
            }
            catch (NoSuchWindowException a){
                a.printStackTrace();
                return true;
            }
            catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return ready;
        }
        @Override
        public String toString() {
            return String.format("Timeout waiting for documentNotActive script");
        }
    };
}

0

पता नहीं है कि यह कैसे करना है, लेकिन मेरे मामले में, पेज लोड का अंत और फ़ायरफ़ॉक्स टैब में प्रदर्शित FAVICON के साथ मैच प्रदान करना।

इसलिए अगर हम वेबब्रोज़र में फ़ेविकॉन इमेज प्राप्त कर सकते हैं, तो वेब पेज पूरी तरह से लोड हो जाता है।

लेकिन यह कैसा प्रदर्शन ...।



-1

यहाँ है कि मैं यह कैसे करते हैं:

new WebDriverWait(driver, 20).until(
       ExpectedConditions.jsReturnsValue(
                   "return document.readyState === 'complete' ? true : false"));

सेलेनियम डिफ़ॉल्ट रूप से भी ऐसा करता है, यह आपकी स्क्रिप्ट में कुछ अतिरिक्त कोड निष्पादन समय जोड़ देगा (जो अतिरिक्त चीजों को लोड करने के लिए पर्याप्त समय हो सकता है, लेकिन फिर नहीं हो सकता है)
Ardesco

-1

मुझे HTML को मतदान करने का आपका विचार पसंद है जब तक कि यह स्थिर न हो। मैं इसे अपने समाधान में जोड़ सकता हूं। निम्नलिखित दृष्टिकोण C # में है और jQuery की आवश्यकता है।

मैं एक SuccessFactors (SaaS) परीक्षण परियोजना के लिए डेवलपर हूं जहां वेब पेज के पीछे डेवलपर्स या डोम की विशेषताओं पर हमारा कोई प्रभाव नहीं है। सास उत्पाद संभावित रूप से अपने अंतर्निहित DOM डिज़ाइन को वर्ष में 4 बार बदल सकता है, इसलिए शिकार स्थायी रूप से सेलेनियम के साथ परीक्षण करने के लिए मजबूत, प्रदर्शन करने के तरीकों पर है (जिसमें सेलेनियम के साथ परीक्षण नहीं किया गया है, जहां ब्ली!)

यहां मैं "पेज रेडी" के लिए उपयोग करता हूं। यह वर्तमान में मेरे सभी परीक्षणों में काम करता है। इसी दृष्टिकोण ने कुछ साल पहले एक बड़े इन-हाउस जावा वेब ऐप के लिए भी काम किया था, और जब मैंने प्रोजेक्ट छोड़ा था उस समय एक साल से अधिक समय तक मजबूत रहा था।

  • Driver वेबड्राइवर उदाहरण है जो ब्राउज़र के साथ संचार करता है
  • DefaultPageLoadTimeout टिक्स में एक टाइमआउट मान (100 टिक प्रति टिक)

public IWebDriver Driver { get; private set; }

// ...

const int GlobalPageLoadTimeOutSecs = 10;
static readonly TimeSpan DefaultPageLoadTimeout =
    new TimeSpan((long) (10_000_000 * GlobalPageLoadTimeOutSecs));
Driver = new FirefoxDriver();

इस प्रकार, विधि में प्रतीक्षा के क्रम पर ध्यान दें PageReady(सेलेनियम दस्तावेज़ तैयार, अजाक्स, एनिमेशन), जो समझ में आता है यदि आप इसके बारे में सोचते हैं:

  1. कोड वाले पेज को लोड करें
  2. Ajax के माध्यम से कहीं से डेटा लोड करने के लिए कोड का उपयोग करें
  3. संभवतः एनिमेशन के साथ डेटा प्रस्तुत करते हैं

आपके DOM तुलना दृष्टिकोण की तरह कुछ का इस्तेमाल मजबूती की एक और परत जोड़ने के लिए 1 और 2 के बीच किया जा सकता है।


public void PageReady()
{
    DocumentReady();
    AjaxReady();
    AnimationsReady();
}


private void DocumentReady()
{
    WaitForJavascript(script: "return document.readyState", result: "complete");
}

private void WaitForJavascript(string script, string result)
{
    new WebDriverWait(Driver, DefaultPageLoadTimeout).Until(
        d => ((IJavaScriptExecutor) d).ExecuteScript(script).Equals(result));
}

private void AjaxReady()
{
    WaitForJavascript(script: "return jQuery.active.toString()", result: "0");
}

private void AnimationsReady()
{
    WaitForJavascript(script: "return $(\"animated\").length.toString()", result: "0");
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.