Alert弹框是一个很烦人的控件,因为当前页面如果弹出了该弹框,你必须要处理它,不然你就不能操作页面的其它元素,下面我列出了alert弹框在多种场景下的处理办法。
明确知道系统哪个地方会弹alert
- 常规处理,该方法只是对弹出的alert弹框进行了捕获和处理
@Test(enabled = false) public void ff1() { System.setProperty(key, value); driver = new ChromeDriver(); driver.get("file:///Users/user/Documents/qiaojiafei/seleniumtest.html"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); Alert alt = driver.switchTo().alert(); alt.accept(); }
- 捕获时增加智能等待,该方法对弹出的alert弹框进行智能等待,避免了NoAlertPresentException异常的抛出
@Test(enabled = false) public void ff2() { System.setProperty(key, value); driver = new ChromeDriver(); driver.get("file:///Users/user/Documents/qiaojiafei/seleniumtest.html"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); WebDriverWait wait = new WebDriverWait(driver, 10); try { Alert alert = wait.until(new ExpectedCondition<Alert>() { @Override public Alert apply(WebDriver driver) { try { return driver.switchTo().alert(); } catch (NoAlertPresentException e) { return null; } } }); alert.accept(); } catch (NullPointerException e) { /* Ignore */ System.out.println("ff2 nullpoint"); } }
- 捕获和处理alert时都增加判断,使用selenium自带的ExpectedConditions
@Test(enabled = false) public void ff3() { System.setProperty(key, value); driver = new ChromeDriver(); driver.get("file:///Users/user/Documents/qiaojiafei/seleniumtest.html"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); boolean flag = false; Alert alert = null; try { new WebDriverWait(driver, 10).until(ExpectedConditions .alertIsPresent()); alert = driver.switchTo().alert(); flag = true; // alert.accept(); } catch (NoAlertPresentException NofindAlert) { // TODO: handle exception NofindAlert.printStackTrace(); // throw NofindAlert; } if (flag) { alert.accept(); } }
以上的几种方法都是自己知道哪个地方要弹alert,所以在代码的某处对alert进行捕获,但是有时候我们并不知道哪个地方会弹alert弹框,这样就会导致我们没有进行捕获代码抛出了
UnexpectedAlertBehaviour异常,下面我们来看下怎么解决这个问题。
不清楚系统哪个地方会弹alert
- 对整个正常代码进行异常捕获,写进try里,然后catchUnexpectedAlertBehaviour
@Test(enabled = false) public void ff4() { System.setProperty(key, value); driver = new ChromeDriver(); driver.get("file:///Users/user/Documents/qiaojiafei/seleniumtest.html"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); try { System.out.println("ff4正常处理代码1"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); } catch (UnhandledAlertException e) { // TODO: handle exception driver.switchTo().alert().accept(); System.out.println("ff4进入UnhandledAlertException异常"); } System.out.println("ff4正常处理代码2"); }
这样写,代码量大的话,需要都加,代码会很冗余,不建议使用
- 实现事件监听接口WebDriverEventListener,alert一般是在click事件之后触发的,所以在afterClickOn方法中对alert进行捕获
@Override public void afterClickOn(WebElement arg0, WebDriver arg1) { // TODO Auto-generated method stub boolean flag = false; Alert alert = null; try { new WebDriverWait(arg1, 10).until(ExpectedConditions .alertIsPresent()); alert = arg1.switchTo().alert(); flag = true; // alert.accept(); } catch (NoAlertPresentException NofindAlert) { // TODO: handle exception NofindAlert.printStackTrace(); // throw NofindAlert; } if (flag) { alert.accept(); } }
- 在初始化webdriver时对alert弹框进行全局设置
@Test(enabled = false) public void ff5() { System.setProperty(key, value); DesiredCapabilities dc = new DesiredCapabilities(); dc.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); driver = new ChromeDriver(dc); driver.get("file:///Users/user/Documents/qiaojiafei/seleniumtest.html"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); }
- 实现ITestListener接口,对代码可能会抛出的UnexpectedAlertBehaviour异常进行捕获
1.新建AlertListner类实现ITestListener,并重写onTestFailure方法
@Override public void onTestFailure(ITestResult result) { // TODO Auto-generated method stub System.out.println("into failure test"); Throwable throwable = result.getThrowable(); if(throwable instanceof UnhandledAlertException) { System.out.println("get UnhandledAlertException la"+throwable.toString()); AlertListnerTest tb = (AlertListnerTest) result.getInstance(); WebDriver driver = tb.getDriver(); Alert alert = null; boolean flag = false; try { new WebDriverWait(driver,10).until(ExpectedConditions.alertIsPresent()); alert = driver.switchTo().alert(); flag = true; //alert.accept(); } catch (NoAlertPresentException NofindAlert) { // TODO: handle exception System.out.println("进入onfail 异常catch"); NofindAlert.printStackTrace(); //throw NofindAlert; } if(flag) { alert.accept(); } }
2.再建一个测试类,在类前面一行加入监听@Listeners({ com.elong.air.tools.AlertListner.class }) ,测试类只需要写正常代码,不需要对可能会弹alert的弹框进行处理。
@Test public void ff6() { System.out.println("jinru ff6test"); System.setProperty(key, value); driver = new ChromeDriver(); driver.get("file:///Users/user/Documents/qiaojiafei/seleniumtest.html"); driver.findElement(By.xpath("//*[@id='alert']/input")).click(); driver.findElement(By.xpath("//*[@id='alert']/input")); }
最后这个方法还存在瑕疵,需要后续优化,欢迎读者提出改进意见。