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")); }
最后這個方法還存在瑕疵,需要后續優化,歡迎讀者提出改進意見。