रैंडम "एलिमेंट अब DOM से जुड़ी नहीं है" StaleElementReferenceException


143

मुझे उम्मीद है कि यह सिर्फ मेरे लिए है, लेकिन सेलेनियम वेबड्राइवर एक पूरी रात की तरह लगता है। वर्तमान में Chrome वेबड्राइवर अनुपयोगी है, और अन्य ड्राइवर काफी अविश्वसनीय हैं, या ऐसा लगता है। मैं कई समस्याओं से जूझ रहा हूं, लेकिन यहां एक है।

बेतरतीब ढंग से, मेरे परीक्षण एक के साथ असफल हो जाएंगे

"org.openqa.selenium.StaleElementReferenceException: Element is no longer attached 
to the DOM    
System info: os.name: 'Windows 7', os.arch: 'amd64',
 os.version: '6.1', java.version: '1.6.0_23'"

मैं वेबड्राइवर संस्करणों का उपयोग कर रहा हूं 2.0b3। मैंने FF और IE ड्राइवरों के साथ ऐसा होते देखा है। एकमात्र तरीका मैं इसे रोक सकता हूं Thread.sleepअपवाद होने से पहले एक वास्तविक कॉल जोड़ना है। हालांकि यह एक खराब समाधान है, इसलिए मुझे उम्मीद है कि कोई मेरी ओर से एक त्रुटि बता सकता है जो यह सब बेहतर बना देगा।


26
उम्मीद है कि 17k विचार इंगित करता है कि यह सिर्फ आप नहीं है;) यह वहाँ से बाहर सबसे निराशाजनक सेलेनियम अपवाद हो गया है।
मार्क मेयो

4
अब 48k! मेरी भी यही समस्या है ...
गल

3
मुझे लग रहा है कि सेलेनियम शुद्ध और पूर्ण कचरा है ....
C जॉनसन

4
60k, अभी भी एक मुद्दा :)
Pieter De Bie

मेरे मामले में ऐसा करने के कारण थाfrom selenium.common.exceptions import NoSuchElementException
Cpt। सेनकफस

जवाबों:


119

हां, यदि आपको StaleElementReferenceException की समस्या है तो यह इसलिए है क्योंकि आपके परीक्षण खराब लिखे गए हैं। यह एक दौड़ की स्थिति है। इस परिदृश्य पर विचार करें:

WebElement element = driver.findElement(By.id("foo"));
// DOM changes - page is refreshed, or element is removed and re-added
element.click();

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

// times out after 5 seconds
WebDriverWait wait = new WebDriverWait(driver, 5);

// while the following loop runs, the DOM changes - 
// page is refreshed, or element is removed and re-added
wait.until(presenceOfElementLocated(By.id("container-element")));        

// now we're good - let's click the element
driver.findElement(By.id("foo")).click();

उपस्थितिऑफ्लीमेंट लोकेटेड () विधि कुछ इस तरह दिखेगी:

private static Function<WebDriver,WebElement> presenceOfElementLocated(final By locator) {
    return new Function<WebDriver, WebElement>() {
        @Override
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    };
}

वर्तमान Chrome ड्राइवर के अस्थिर होने के बारे में आप काफी सही हैं, और आपको यह सुनकर खुशी होगी कि सेलेनियम ट्रंक में एक फिर से लिखा हुआ क्रोम ड्राइवर है, जहाँ अधिकांश कार्यान्वयन क्रोमियम डेवलपर्स द्वारा उनके पेड़ के हिस्से के रूप में किया गया था।

पुनश्च। वैकल्पिक रूप से, उपरोक्त उदाहरण में स्पष्ट रूप से प्रतीक्षा करने के बजाय, आप अंतर्निहित प्रतीक्षा को सक्षम कर सकते हैं - इस तरह से WebDriver हमेशा तब तक लूप करेगा जब तक कि तत्व के उपस्थित होने की प्रतीक्षा में निर्दिष्ट समय समाप्त न हो जाए:

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

मेरे अनुभव में, हालांकि, स्पष्ट रूप से प्रतीक्षा हमेशा अधिक विश्वसनीय होती है।


2
क्या मैं यह कहने में सही हूं कि तत्वों को चर में पढ़ना और उनका पुन: उपयोग करना संभव नहीं है? क्योंकि मेरे पास एक विशाल सूखा और गतिशील वॉटआईआर डीएसएल है जो गुजरने वाले तत्वों पर निर्भर करता है और मैं वेबड्राइवर को पोर्ट करने की कोशिश कर रहा हूं, लेकिन मुझे वही समस्या हो रही है। अनिवार्य रूप से मुझे DOM को बदलने वाले हर परीक्षण चरण के लिए मॉड्यूल में सभी तत्वों को फिर से पढ़ने के लिए कोड जोड़ना होगा ...
kinofrost

नमस्ते। क्या मैं पूछ सकता हूं कि इस उदाहरण में फंक्शन क्या है? मैं इसे खोजने के लिए प्रतीत नहीं कर सकते .... धन्यवाद!
हनीबल

1
@ हनीबल:, अमरूदcom.google.common.base.Function<F, T> द्वारा प्रदान किया गया ।
Stephan202

@ शारिब, मैं आपके समाधान के एक साल बाद से इसी मुद्दे का सामना कर रहा हूं। समस्या यह है कि मैं रूबी में अपनी स्क्रिप्ट्स लिख रहा हूं, और 'उपस्थितिऑफ्लीमेंटलेटेड' या इसी तरह के किसी भी नाम से कोई फ़ंक्शन नहीं है। एएनआई की सिफारिशें?
अमेय

56
@ शारिब मैं असहमत हूं, यह सब खराब तरीके से तैयार किए गए परीक्षण के कारण हुआ है। क्योंकि AJAX कॉल के बाद भी एलीमेंट दिखाई देता है तब भी jQuery कोड हो सकता है जो StaleElementReferenceException का कारण बन सकता है। और कुछ भी नहीं है जो आप स्पष्ट प्रतीक्षा को जोड़ने के अलावा कर सकते हैं जो बहुत अच्छा नहीं लगता है। मुझे लगता है कि यह WebDriver में एक डिजाइन दोष है
munch

10

मैं कुछ सफलता के साथ इस तरह एक विधि का उपयोग करने में सक्षम है:

WebElement getStaleElemById(String id) {
    try {
        return driver.findElement(By.id(id));
    } catch (StaleElementReferenceException e) {
        System.out.println("Attempting to recover from StaleElementReferenceException ...");
        return getStaleElemById(id);
    }
}

हां, यह केवल तब तक तत्व को मतदान करता रहता है जब तक कि इसे बासी (ताजा) नहीं माना जाता है। वास्तव में समस्या की जड़ तक नहीं पहुंचता है, लेकिन मैंने पाया है कि वेबड्राइवर इस अपवाद को फेंकने के बारे में चुन सकता है - कभी-कभी मैं इसे प्राप्त करता हूं, और कभी-कभी मैं नहीं करता। या यह हो सकता है कि DOM वास्तव में बदल रहा है।

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


7
आपके पास इस कोड में एक बग है, आपको किसी प्रकार की टोपी के बिना पुनरावर्ती तरीके से कॉल नहीं करना चाहिए या आप अपने स्टैक को उड़ा देंगे।
हैरी

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

मैं मानता हूं कि यह खराब लिखित परीक्षाओं का परिणाम नहीं है। सेलेनियम के लिए आधुनिक वेबसाइटों पर ऐसा करने की प्रवृत्ति है, यहां तक ​​कि सर्वोत्तम लिखित परीक्षाओं के लिए भी - शायद इसलिए कि वेबसाइटें लगातार दो-तरफा बाइंडिंग के माध्यम से अपने तत्वों को ताज़ा कर रही हैं जो प्रतिक्रियाशील वेब ऐप फ्रेमवर्क में आम हैं, भले ही कोई बदलाव न हो उन तत्वों को बनाने की जरूरत है। इस तरह का एक तरीका हर सेलेनियम ढांचे का एक हिस्सा होना चाहिए जो एक आधुनिक वेब ऐप का परीक्षण करता है।
एमरी

10

मुझे यह त्रुटि कभी-कभी तब मिलती है जब AJAX अपडेट मिडवे होते हैं। Capybara DOM परिवर्तनों की प्रतीक्षा करने के बारे में बहुत स्मार्ट प्रतीत होता है (देखें कि क्यों wa_until Capybara से हटा दिया गया था ), लेकिन 2 सेकंड का डिफ़ॉल्ट प्रतीक्षा समय मेरे मामले में बस पर्याप्त नहीं था। उदाहरण के साथ _spec_helper.rb_ में बदला गया

Capybara.default_max_wait_time = 5

2
इससे मेरी समस्या भी ठीक हो गई: मैं एक StaleElementReferenceError प्राप्त कर रहा था और Capybara.default_max_wait_time को बढ़ाकर इस मुद्दे को हल किया।
ब्रेंडन

1

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

private void setElementLocator()
{
    this.locatorVariable = "selenium_" + DateTimeMethods.GetTime().ToString();
    ((IJavaScriptExecutor)this.driver).ExecuteScript(locatorVariable + " = arguments[0];", this.element);
}

private void RetrieveElement()
{
    this.element = (IWebElement)((IJavaScriptExecutor)this.driver).ExecuteScript("return " + locatorVariable);
}

आप i "ढूँढ" पाते हैं या वैश्विक js चर में तत्व को बचाते हैं और यदि आवश्यक हो तो तत्व को पुनः प्राप्त करते हैं। यदि पृष्ठ पुनः लोड हो जाता है तो यह संदर्भ अब काम नहीं करेगा। लेकिन जब तक संदर्भ में बदलाव के लिए केवल बदलाव किए जाते हैं। और वह ज्यादातर मामलों में काम करना चाहिए।

इसके अलावा यह तत्व को फिर से खोजने से बचता है।

जॉन


1

मेरे पास एक ही समस्या थी और मेरा एक पुराना सेलेनियम संस्करण था। मैं विकास के माहौल के कारण एक नए संस्करण में अपडेट नहीं कर सकता। समस्या HTMLUnitWebElement.switchFocusToThisIfNeeded () के कारण होती है। जब आप एक नए पृष्ठ पर जाते हैं, तो ऐसा हो सकता है कि जिस तत्व को आपने पुराने पृष्ठ पर क्लिक किया है वह हैoldActiveElement (नीचे देखें)। सेलेनियम पुराने तत्व से संदर्भ प्राप्त करने की कोशिश करता है और विफल रहता है। यही कारण है कि उन्होंने भविष्य के रिलीज में एक कोशिश पकड़ बनाई।

सेलेनियम-एचटीएमएल-चालक संस्करण से कोड <2.23.0:

private void switchFocusToThisIfNeeded() {
    HtmlUnitWebElement oldActiveElement =
        ((HtmlUnitWebElement)parent.switchTo().activeElement());

    boolean jsEnabled = parent.isJavascriptEnabled();
    boolean oldActiveEqualsCurrent = oldActiveElement.equals(this);
    boolean isBody = oldActiveElement.getTagName().toLowerCase().equals("body");
    if (jsEnabled &&
        !oldActiveEqualsCurrent &&
        !isBody) {
      oldActiveElement.element.blur();
      element.focus();
    }
}

सेलेनियम-एचटीएमएल-चालक संस्करण से कोड> = 2.23.0:

private void switchFocusToThisIfNeeded() {
    HtmlUnitWebElement oldActiveElement =
        ((HtmlUnitWebElement)parent.switchTo().activeElement());

    boolean jsEnabled = parent.isJavascriptEnabled();
    boolean oldActiveEqualsCurrent = oldActiveElement.equals(this);
    try {
        boolean isBody = oldActiveElement.getTagName().toLowerCase().equals("body");
        if (jsEnabled &&
            !oldActiveEqualsCurrent &&
            !isBody) {
        oldActiveElement.element.blur();
        }
    } catch (StaleElementReferenceException ex) {
      // old element has gone, do nothing
    }
    element.focus();
}

2.23.0 या नए पर अपडेट किए बिना आप केवल पृष्ठ फ़ोकस पर कोई तत्व दे सकते हैं। मैंने सिर्फ element.click()उदाहरण के लिए इस्तेमाल किया ।


1
वाह ... यह एक बहुत अस्पष्ट खोज थी, अच्छा काम .. मैं अब सोच रहा हूं कि क्या अन्य ड्राइवरों (जैसे क्रोमेड्रिवर) में भी समान मुद्दे हैं
kevlarr

0

मेरे पास एक खोज इनपुट बॉक्स में send_keys करने की कोशिश करते समय हुआ - जो आपके द्वारा टाइप किए गए के आधार पर स्वतः पूर्ण है। जैसा कि Eero द्वारा उल्लेख किया गया है, यह तब हो सकता है जब आपका तत्व इनपुट तत्व के अंदर आपके पाठ में टाइप करते समय कुछ अजाक्स अपडेट करता है। । इसका समाधान यह है कि एक बार में एक वर्ण भेजा जाए और इनपुट तत्व को फिर से खोजा जाए । (उदा। नीचे दिखाए गए रूबी में)

def send_keys_eachchar(webdriver, elem_locator, text_to_send)
  text_to_send.each_char do |char|
    input_elem = webdriver.find_element(elem_locator)
    input_elem.send_keys(char)
  end
end

0

@ जरीब के जवाब में जोड़ने के लिए, मैंने कई विस्तार विधियां बनाई हैं जो दौड़ की स्थिति को खत्म करने में मदद करती हैं।

यहाँ मेरा सेटअप है:

मेरे पास एक क्लास है जिसे "Driver.cs" कहा जाता है। इसमें ड्राइवर और अन्य उपयोगी स्थिर कार्यों के लिए विस्तार विधियों से भरा एक स्थिर वर्ग होता है।

उन तत्वों के लिए जिन्हें मुझे आमतौर पर पुनर्प्राप्त करने की आवश्यकता होती है, मैं निम्नलिखित की तरह एक एक्सटेंशन विधि बनाता हूं:

public static IWebElement SpecificElementToGet(this IWebDriver driver) {
    return driver.FindElement(By.SomeSelector("SelectorText"));
}

यह आपको कोड के साथ किसी भी परीक्षण वर्ग से उस तत्व को पुनः प्राप्त करने की अनुमति देता है:

driver.SpecificElementToGet();

अब, यदि इसका परिणाम होता है StaleElementReferenceException, तो मेरे पास मेरे ड्राइवर वर्ग में निम्नलिखित स्थैतिक विधि है:

public static void WaitForDisplayed(Func<IWebElement> getWebElement, int timeOut)
{
    for (int second = 0; ; second++)
    {
        if (second >= timeOut) Assert.Fail("timeout");
        try
        {
            if (getWebElement().Displayed) break;
        }
        catch (Exception)
        { }
        Thread.Sleep(1000);
    }
}

इस फ़ंक्शन का पहला पैरामीटर कोई भी फ़ंक्शन है जो IWebElement ऑब्जेक्ट लौटाता है। दूसरा पैरामीटर सेकंड में एक टाइमआउट है (टाइमआउट के लिए कोड को सेलेनियम आईडीई से फायरफॉक्स के लिए कॉपी किया गया था)। कोड का उपयोग बासी तत्व अपवाद से बचने के लिए निम्न तरीके से किया जा सकता है:

MyTestDriver.WaitForDisplayed(driver.SpecificElementToGet,5);

उपरोक्त कोड driver.SpecificElementToGet().Displayedतब तक कॉल करेगा जब तक driver.SpecificElementToGet()कोई अपवाद नहीं फेंकता और .Displayedमूल्यांकन नहीं करता है trueऔर 5 सेकंड बीत चुके हैं। 5 सेकंड के बाद, परीक्षण विफल हो जाएगा।

दूसरी तरफ, तत्व के मौजूद न होने का इंतजार करने के लिए, आप निम्न फ़ंक्शन का उसी तरह उपयोग कर सकते हैं:

public static void WaitForNotPresent(Func<IWebElement> getWebElement, int timeOut) {
    for (int second = 0;; second++) {
        if (second >= timeOut) Assert.Fail("timeout");
            try
            {
                if (!getWebElement().Displayed) break;
            }
            catch (ElementNotVisibleException) { break; }
            catch (NoSuchElementException) { break; }
            catch (StaleElementReferenceException) { break; }
            catch (Exception)
            { }
            Thread.Sleep(1000);
        }
}

0

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

इस कोड को जोड़ना

webDriverWait.until((webDriver1) -> (((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete")));

if ((Boolean) ((JavascriptExecutor) webDriver).executeScript("return window.jQuery != undefined")) {
    webDriverWait.until((webDriver1) -> (((JavascriptExecutor) webDriver).executeScript("return jQuery.active == 0")));
}

हर WebElement कार्रवाई से पहले आपके परीक्षणों की स्थिरता बढ़ सकती है लेकिन आप अभी भी समय-समय पर StaleElementReferenceException प्राप्त कर सकते हैं।

तो यह मैं (AspectJ का उपयोग कर) के साथ आया है:

package path.to.your.aspects;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.pagefactory.DefaultElementLocator;
import org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@Aspect
public class WebElementAspect {
    private static final Logger LOG = LogManager.getLogger(WebElementAspect.class);
    /**
     * Get your WebDriver instance from some kind of manager
     */
    private WebDriver webDriver = DriverManager.getWebDriver();
    private WebDriverWait webDriverWait = new WebDriverWait(webDriver, 10);

    /**
     * This will intercept execution of all methods from WebElement interface
     */
    @Pointcut("execution(* org.openqa.selenium.WebElement.*(..))")
    public void webElementMethods() {}

    /**
     * @Around annotation means that you can insert additional logic
     * before and after execution of the method
     */
    @Around("webElementMethods()")
    public Object webElementHandler(ProceedingJoinPoint joinPoint) throws Throwable {
        /**
         * Waiting until JavaScript and jQuery complete their stuff
         */
        waitUntilPageIsLoaded();

        /**
         * Getting WebElement instance, method, arguments
         */
        WebElement webElement = (WebElement) joinPoint.getThis();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        Object[] args = joinPoint.getArgs();

        /**
         * Do some logging if you feel like it
         */
        String methodName = method.getName();

        if (methodName.contains("click")) {
            LOG.info("Clicking on " + getBy(webElement));
        } else if (methodName.contains("select")) {
            LOG.info("Selecting from " + getBy(webElement));
        } else if (methodName.contains("sendKeys")) {
            LOG.info("Entering " + args[0].toString() + " into " + getBy(webElement));
        }

        try {
            /**
             * Executing WebElement method
             */
            return joinPoint.proceed();
        } catch (StaleElementReferenceException ex) {
            LOG.debug("Intercepted StaleElementReferenceException");

            /**
             * Refreshing WebElement
             * You can use implementation from this blog
             * http://www.sahajamit.com/post/mystery-of-stale-element-reference-exception/
             * but remove staleness check in the beginning (if(!isElementStale(elem))), because we already caught exception
             * and it will result in an endless loop
             */
            webElement = StaleElementUtil.refreshElement(webElement);

            /**
             * Executing method once again on the refreshed WebElement and returning result
             */
            return method.invoke(webElement, args);
        }
    }

    private void waitUntilPageIsLoaded() {
        webDriverWait.until((webDriver1) -> (((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete")));

        if ((Boolean) ((JavascriptExecutor) webDriver).executeScript("return window.jQuery != undefined")) {
            webDriverWait.until((webDriver1) -> (((JavascriptExecutor) webDriver).executeScript("return jQuery.active == 0")));
        }
    }

    private static String getBy(WebElement webElement) {
        try {
            if (webElement instanceof RemoteWebElement) {
                try {
                    Field foundBy = webElement.getClass().getDeclaredField("foundBy");
                    foundBy.setAccessible(true);
                    return (String) foundBy.get(webElement);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            } else {
                LocatingElementHandler handler = (LocatingElementHandler) Proxy.getInvocationHandler(webElement);

                Field locatorField = handler.getClass().getDeclaredField("locator");
                locatorField.setAccessible(true);

                DefaultElementLocator locator = (DefaultElementLocator) locatorField.get(handler);

                Field byField = locator.getClass().getDeclaredField("by");
                byField.setAccessible(true);

                return byField.get(locator).toString();
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }

        return null;
    }
}

इस पहलू को सक्षम करने के लिए फ़ाइल बनाएं src\main\resources\META-INF\aop-ajc.xml और लिखें

<aspectj>
    <aspects>
        <aspect name="path.to.your.aspects.WebElementAspect"/>
    </aspects>
</aspectj>

इसे अपने में जोड़ें pom.xml

<properties>
    <aspectj.version>1.9.1</aspectj.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.0</version>
            <configuration>
                <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                </argLine>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
</build>

और बस यही। आशा करता हूँ की ये काम करेगा।


0

आप इसे स्पष्ट प्रतीक्षा का उपयोग करके हल कर सकते हैं ताकि आपको कठिन प्रतीक्षा का उपयोग न करना पड़े।

यदि आप सभी तत्वों को एक संपत्ति के साथ लाते हैं और प्रत्येक लूप का उपयोग करके इसके माध्यम से पुनरावृति करते हैं, तो आप इस तरह लूप के अंदर प्रतीक्षा का उपयोग कर सकते हैं:

List<WebElement> elements = driver.findElements("Object property");
for(WebElement element:elements)
{
    new WebDriverWait(driver,10).until(ExpectedConditions.presenceOfAllElementsLocatedBy("Object property"));
    element.click();//or any other action
}

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

new WebDriverWait(driver,10).until(ExpectedConditions.presenceOfAllElementsLocatedBy("Your object property"));
driver.findElement("Your object property").click();//or anyother action 


-5
FirefoxDriver _driver = new FirefoxDriver();

// create webdriverwait
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10));

// create flag/checker
bool result = false;

// wait for the element.
IWebElement elem = wait.Until(x => x.FindElement(By.Id("Element_ID")));

do
{
    try
    {
        // let the driver look for the element again.
        elem = _driver.FindElement(By.Id("Element_ID"));

        // do your actions.
        elem.SendKeys("text");

        // it will throw an exception if the element is not in the dom or not
        // found but if it didn't, our result will be changed to true.
        result = !result;
    }
    catch (Exception) { }
} while (result != true); // this will continue to look for the element until
                          // it ends throwing exception.

मैं इसे अभी पता लगाकर इसे जोड़ दिया। खेद प्रारूप के लिए इसे मेरा पहली बार पोस्ट करने के लिए है। बस मदद करने का प्रयास कर रहा हूं। आप इसे उपयोगी पाते हैं, तो दूसरों के लिए :) भी अवगत कराएं
एल्विन वेरा

Stackoverflow में आपका स्वागत है! यह हमेशा बेहतर एक संक्षिप्त विवरण प्रदान करने के लिए एक नमूना कोड पद सटीकता :) में सुधार करने के लिए
Picrofo सॉफ्टवेयर

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