2011-07-19 50 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”。 :) –