2013-04-04 9 views
5

Stosuję metodę sevikto webdriverwait do określonego elementu IWebElement w celu pobrania elementów podrzędnych tego elementu IWebElement, gdy są one dostępne. To jest mój kod ...przy użyciu webdriverwait na konkretnym serwerze IWebElement

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
IList<IWebElement> elementsA = wait.Until<IList<IWebElement>>((d) => 
{ 
    return driver.FindElements(By.XPath("//table[@class='boxVerde']")); 
}); 

foreach (IWebElement iwe in elementsA) 
{ 
     wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
     IList<IWebElement> elementsB = wait.Until<IList<IWebElement>>((d) => 
     { 
      return iwe.FindElements(By.XPath("tr/td/div/a")); 
      //trying to fetch the anchor tags from the element 
     }); 
} 

Utrzymuje daje mi błąd mówiąc: „Element nie jest już przywiązany do DOM” ... Myślę, że jest po prostu czekać webdriver nie działa. Czy robię coś złego? bardzo dziękuję z góry

+0

Jaką wersję Selenium? Jaka przeglądarka i wersja tej przeglądarki? Próbowałem za pomocą selektora CSS równoważnego z zapytaniem XPath? Czy ty * potrzebujesz * czekania? – Arran

+0

Cześć Arran, używam chromeedriver_win_26.0.1383.0 a selen wersja 2 ... nie próbowałem selektorów css. Szczerze mówiąc nie sądzę, że muszę czekać, ponieważ i tak nie zmieniam dominu, zanim zadzwonię, ale ponieważ przekazano mi element czerpiący oldElementReferenceException ", który nie jest już dołączony do DOM" Zakładam, że w jakiś sposób wstrzymałem oczekiwanie ... –

+0

Jaką masz wersję Chrome? Selenium wersja 2 punkt co? Najnowszym jest v2.31, czy go używasz? – Arran

Odpowiedz

-1

Spróbuj tego użyć. Czeka na obecność Elementów na stronie.

static void ForElementsArePresent(IWebDriver wd, double waitForSeconds, By by) 
     { 
      try 
      { 
       WebDriverWait wait = new WebDriverWait(wd, TimeSpan.FromSeconds(waitForSeconds)); 
       wait.Until(x => (x.FindElements(by).Count > 0)); 
      } 
      catch (WebDriverTimeoutException) 
      { 
       Console.WriteLine("Waiting for element " + by + " to disappear timed out after " + waitForSeconds + " seconds."); 
       throw; 
      }      
     } 
3

Wygląda na to, że cierpisz na Stale Element.

Każdy WebElement że selen wyszukuje jest rzeczywiście odniesienie do elementu wewnątrz DOM

Czasami JavaScript używanych w witrynie zniszczy i odtworzyć element, kiedy to nastąpi istniejące odniesienia staje się przestarzały i zobaczysz StaleElementReferenceException (Przynajmniej tak się nazywa w języku Java, powinieneś zobaczyć coś bardzo podobnego).

Tak więc, jeśli kiedykolwiek zobaczysz wyjątek StaleElementReferenceException lub komunikat informujący, że "element nie jest już dołączony do DOM", oznacza to, że odwołanie do elementu w DOM, który był wcześniej używany, nie jest już ważne, ponieważ element, który odniesienie do zostało zniszczone.

Nie zawsze jest to oczywiste wizualnie, ponieważ pierwotny element mógł zostać zniszczony, a następnie odtworzony identyczny, jest to jednak nowy element, więc trzeba utworzyć nowe odniesienie do interakcji z nim.

Sposób na utworzenie nowego odniesienia polega na ponownym odnalezieniu elementu.

Z twoich pytań nie wynika jednoznacznie, ale zakładam, że pojawia się problem podczas przeglądania listy elementów kotwicy po znalezieniu stołu. W takim przypadku sugeruje, że tabela została zniszczona i odtworzona między punktem, w którym znalazłeś element tabeli, a następnie zaczęła się iterować przez elementy kotwiące wewnątrz stołu.

W takim przypadku należy ponownie znaleźć tabelę. Przydatną metodą jest poczekanie, aż stół stanie się nieaktualny, zanim spróbujesz go znaleźć. W ten sposób możesz być dość pewny, że dowolny skrypt JavaScript na stronie, który niszczy tabelę, a następnie ponownie ją tworzy, zakończył przetwarzanie. Model .NET ExpectedConditions class nie jest tak dojrzały jak Java ExpectedConditions class. Sugerowałabym przejrzenie niektórych Java i przeniesienie ich do .NET (powinno być dość trywialne, struktura jest dość podobna), szczególnie interesująca jest Java, która czeka, aż element stanie się nieaktualny.

+0

Miło, jeśli ktokolwiek, kto zagłosował, wyjaśniłby, dlaczego rozważenie wszystkich powyższych jest poprawne ... – Ardesco

0

Musisz zdefiniować czas oczekiwania na Webdriver, aby zignorować wyjątki, aż do czasu pollingu. Następująca metoda java odpytuje element za 60 sekund i zwraca, jeśli zostanie załadowany, spowoduje odrzucenie wyjątku limitu czasu. Proszę przekonwertować to na swój język, jak potrzebne. (Niestety, jestem javaist)

public WebElement fluentWait(final By locator, WebDriver driver) { 
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) 
    .withTimeout(60, TimeUnit.SECONDS) 
    .pollingEvery(1, TimeUnit.SECONDS) 
    .ignoring(StaleElementReferenceException.class) 
    .ignoring(NoSuchElementException.class); 
    WebElement foo = wait.until(
    new Function<WebDriver, WebElement>() { 
    public WebElement apply(WebDriver driver) { 
    return driver.findElement(locator); 
    } 
     } ); 
    return foo;} 

Poza tym, jeśli szukasz dla pojedynczej kotwy elementu znacznika użyć XPath jako

 iwe.FindElements(By.XPath(" //a[text()='anchor tag text']")); 

lub Zlokalizuj swój element za pomocą By.linkText ("tekst znacznika kotwicy");

 iwe.FindElements(By.linkText("anchor tag text")); 
1

Uważam, że niektóre tabele zostały usunięte dla strony. Przydatne będzie spojrzenie na wydarzenia na twojej stronie. Zamiast przeszukiwać wnętrze elementu, należy użyć ścieżki xpath //table[@class='boxVerde']/tr/td/div/a.

+0

W jaki sposób przy użyciu tej XPath pomóc, jeśli, jak sugerujesz, tabela została usunięta z Strona? – Ardesco