2011-07-19 53 views
2

前檢查文本是否存在我遇到了Checking If alert exists before switching to it中描述的問題。捕獲NullPointerException我覺得很可怕。有沒有人更優雅地解決這個問題?Selenium 2(WebDriver):在調用Alert.getText()

我目前的解決方案使用一個等待捕獲NPE。客戶端代碼只需要調用waitForAlert(driver, TIMEOUT)

/** 
* If no alert is popped-up within <tt>seconds</tt>, this method will throw 
* a non-specified <tt>Throwable</tt>. 
* 
* @return alert handler 
* @see org.openqa.selenium.support.ui.Wait.until(com.​google.​common.​base.Function) 
*/ 
public static Alert waitForAlert(WebDriver driver, int seconds) { 
    Wait<WebDriver> wait = new WebDriverWait(driver, seconds); 
    return wait.until(new AlertAvailable()); 
} 

private static class AlertAvailable implements ExpectedCondition<Alert> { 
    private Alert alert = null; 
    @Override 
    public Alert apply(WebDriver driver) { 
     Alert result = null; 
     if (null == alert) { 
      alert = driver.switchTo().alert(); 
     } 

     try { 
      alert.getText(); 
      result = alert; 
     } catch (NullPointerException npe) { 
      // Getting around https://groups.google.com/d/topic/selenium-users/-X2XEQU7hl4/discussion 
     } 
     return result; 
    } 
} 
+1

看起來像對我做的方式。 – Ardesco

回答

2

基於@Joe編碼器answer,這個等待的簡化版本是:

/** 
* If no alert is popped-up within <tt>seconds</tt>, this method will throw 
* a non-specified <tt>Throwable</tt>. 
* 
* @return alert handler 
* @see org.openqa.selenium.support.ui.Wait.until(com.​google.​common.​base.Function) 
*/ 
public static Alert waitForAlert(WebDriver driver, int seconds) { 
    Wait<WebDriver> wait = new WebDriverWait(driver, seconds) 
     .ignore(NullPointerException.class); 
    return wait.until(new AlertAvailable()); 
} 

private static class AlertAvailable implements ExpectedCondition<Alert> { 
    @Override 
    public Alert apply(WebDriver driver) { 
     Alert alert = driver.switchTo().alert(); 
     alert.getText(); 
     return alert; 
    } 
} 

我已經寫了一個簡短的測試,以證明理念:

import com.google.common.base.Function; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.concurrent.TimeUnit; 
import org.junit.Test; 
import org.openqa.selenium.support.ui.FluentWait; 
import org.openqa.selenium.support.ui.Wait; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class TestUntil { 
    private static Logger log = LoggerFactory.getLogger(TestUntil.class); 

    @Test 
    public void testUnit() { 
     Wait<MyObject> w = new FluentWait<MyObject>(new MyObject()) 
       .withTimeout(30, TimeUnit.SECONDS) 
       .ignoring(NullPointerException.class); 
     log.debug("Waiting until..."); 
     w.until(new Function<MyObject, Object>() { 
      @Override 
      public Object apply(MyObject input) { 
       return input.get(); 
      } 
     }); 
     log.debug("Returned from wait"); 
    } 

    private static class MyObject { 
     Iterator<Object> results = new ArrayList<Object>() { 
      { 
       this.add(null); 
       this.add(null); 
       this.add(new NullPointerException("NPE ignored")); 
       this.add(new RuntimeException("RTE not ignored")); 
      } 
     }.iterator(); 
     int i = 0; 
     public Object get() { 
      log.debug("Invocation {}", ++i); 
      Object n = results.next(); 
      if (n instanceof RuntimeException) { 
       RuntimeException rte = (RuntimeException)n; 
       log.debug("Throwing exception in {} invocation: {}", i, rte); 
       throw rte; 
      } 
      log.debug("Result of invocation {}: '{}'", i, n); 
      return n; 
     } 
    } 
} 

在這代碼,在untilMyObject.get()被調用四次。第三次,它拋出一個被忽略的異常,但最後一個拋出一個不被忽略的異常,中斷了等待。

輸出(簡化可讀性):

Waiting until... 
Invocation 1 
Result of invocation 1: 'null' 
Invocation 2 
Result of invocation 2: 'null' 
Invocation 3 
Throwing exception in 3 invocation: java.lang.NullPointerException: NPE ignored 
Invocation 4 
Throwing exception in 4 invocation: java.lang.RuntimeException: RTE not ignored 

------------- ---------------- --------------- 
Testcase: testUnit(org.lila_project.selenium_tests.tmp.TestUntil): Caused an ERROR 
RTE not ignored 
java.lang.RuntimeException: RTE not ignored 
    at org.lila_project.selenium_tests.tmp.TestUntil$MyObject$1.<init>(TestUntil.java:42) 
    at org.lila_project.selenium_tests.tmp.TestUntil$MyObject.<init>(TestUntil.java:37) 
    at org.lila_project.selenium_tests.tmp.TestUntil$MyObject.<init>(TestUntil.java:36) 
    at org.lila_project.selenium_tests.tmp.TestUntil.testUnit(TestUntil.java:22) 

注意,作爲RuntimeException不會被忽略,將「從等待返回」不打印日誌。

2

的JavaDoc FluentWait.until()

重複應用這種情況下的輸入值給定函數,直到出現以下情況之一:

  1. 功能既不返回也不返回假,
  2. 該函數拋出一個無符號的異常,
  3. 超時到期 .......(剪斷)

由於NullPointerException表示假條件,和WebDriverWait僅忽略NotFoundException,只是刪除try/catch塊。在apply()中引發的未經檢查的無符號Exception在語義上等同於返回null,與您現有的代碼中一樣。

private static class AlertAvailable implements ExpectedCondition<Alert> { 
    @Override 
    public Alert apply(WebDriver driver) { 
     Alert result = driver.switchTo().alert(); 
     result.getText(); 
     return result; 
    } 
} 
+0

非常感謝!你已經指出我正確的方向。然而,在我的原始代碼中,NPE不會被'wait'忽略,因此,如果'alert.getText()'拋出NPE,wait就會退出。要刪除try/catch,我仍然需要'wait.ignore(NullPointerException.class)' – Alberto

+0

這是真的,很好的「catch」。 :) –