2012-03-21 13 views
6

Jestem nowym użytkownikiem Webbooka firmy Selenium, być może to pytanie jest oczywiste. Jestem po sytuację tak:Korzystanie z webdrivera, aby sprawdzić, czy istnieje element BEZ rzucania wyjątku?

Jeśli element nie istnieje, kliknij go i wróć do strony indeksu:

driver.findElement(By.id("...."])).click(); 

jeśli nie zostanie wysunięty, pomiń go i wróć do strony indeksu. Test nadal trwa bez żadnego wyjątku.

wiem jedno rozwiązanie do tego:

driver.findElements(By.id("...")).size() != 0 

więc próbowałem:

if(driver.findElements(By.id("....")).size() > 0) 
    { 
     driver.findElement(By.id("....")).click(); 
     driver.findElement(By.cssSelector("...")).click(); 
    } 
else 
    { 
     driver.findElement(By.cssSelector("....")).click(); 
    } 

okazało się naprawdę brzydki chociaż bo jeśli mam 10 elementów w celu sprawdzenia, ten warunek musi być napisane 10 razy.

Jakieś obejście, które sprawi, że będzie zgrabna?

Odpowiedz

1

Rozwiązanie może być wiele, ale może utrudnić architekturę.

więc najprostszym rozwiązaniem mogłoby być następujące:

Wystarczy utworzyć metodę jak optionalClick() w jakiejś klasie użytkowej lub gdzieś z argumentami jak:

  1. locator_keyword: {wartości: id lub cssSelector lub XPath itp}
  2. locator {wartości: "q"}

kroki w metodzie:

  1. Get element oparty na locator_keyword i locator
  2. Sprawdź, czy elementem jest tam i kliknij go
  3. W przeciwnym razie niczego nie

Metoda ta może być używana zrobić jako rodzaj rzeczy dla dowolnego rodzaju obiektów.

+0

dzięki za informację zwrotną !! Innym problemem jest to, że jeśli składnia jest strasznie powolna ... czy jest jakiś sposób, aby przyspieszyć? – user1282634

+0

OK, więc nie używaj, jeśli instrukcja w ogóle Zamiast tego użyj funkcji try/catch block as: wypróbuj {WebElement elemnt = driver.findElement (By.ID ("..")); elemnt.click(); (Wyjątek e) {// Nic nie robiąc} – Nayan

+0

zrozumiałem ~~ dzięki! – user1282634

1

Istnieją sposoby na znalezienie elementów bez wyrzucania wyjątków za pomocą warunków próbnych w pętlach. Na przykład ten sposób napisałem (co można uprościć w zależności od tego, czego użyć, jeśli dla) zwróci WebElement a to sprawia, że ​​na pewno, że jest klikalny przed wpuszczeniem go do ciebie:

public static WebElement getElementByLocator(By locator) { 
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); 
    WebElement we = null; 
    boolean unfound = true; 
    int tries = 0; 
    while (unfound && tries < 10) { 
    tries += 1; 
    try { 
     we = driver.findElement(locator); 
     unfound = false; // FOUND IT 
    } catch (StaleElementReferenceException ser) {       
     unfound = true; 
    } catch (NoSuchElementException nse) {       
     unfound = true; 
    } catch (Exception e) { 
     staticlogger.info(e.getMessage()); 
    } 
    } 
    driver.manage().timeouts().implicitlyWait(DEFAULT_IMPLICIT_WAIT, 
     TimeUnit.SECONDS); 
    return we; 
} 
+1

erm w jaki sposób nie korzysta z wyjątków ?! –

+0

Powiedziałem "bez rzucania", a nie "bez użycia". – djangofan

0

Dzięki za wskazówki na temat korzystania findelements. Myślę, że będziesz też potrzebował logiki oczekiwania, jeśli nie chcesz, aby powrócił zbyt wcześnie.

Oto moje rozwiązanie w języku C#.

W zasadzie reimplementuje logikę czekania w bibliotece selenu - niestety metoda, która czeka nie jest widoczna (irytująco to także rethrows exceptions the wrong way i traci ślady stosu!).

Prawdopodobnie musiałbyś trochę zmodyfikować dla java - nie wiesz, co to jest selen API, gdy nie możesz po prostu przekazać funkcji.

Wait reimplementacja:

private IWebElement WaitAndSeeIf(Func<IWebElement> canGet) 
    { 
     var end = DateTime.Now.AddSeconds(1); 

     IWebElement element; 
     while (true) 
     { 
      element = canGet(); 

      if (element != null) 
       break; 

      var time = DateTime.Now; 
      if (time > end) 
       break; 

      Thread.Sleep(200); 
     } 
     return element; 
    } 

Telefoniczny kod:

 var dashboardButton = WaitAndSeeIf(() => 
               { 
                var elements = Driver.FindElements(By.XPath("//button[contains(.//*,'Dashboard')]")); 
                return elements.Any() ? elements.Single() : null; 
               }); 

tej pory znalazłem to użyteczne w kilku miejscach (sprawdzanie pod kątem obecności dialogów w ExtJS etc), ale mają a mimo to musiał się zamulać i konfigurować. Przypuszczam, że najmilszą rzeczą, jaką można zrobić, byłoby przyjęcie domyślnego czasu oczekiwania, o którym mowa w drugiej odpowiedzi.

Powiązane problemy