1.简介
上一篇讲解和分享了如何获取浏览器窗口的句柄,那么今天这一篇就是讲解获取后我们要做什么,就是利用获取的句柄进行浏览器窗口的切换来分别定位不同页面中的元素进行操作。
2.为什么要切换窗口?
Selenium在当前页面打开了新的窗口,此时就需要跳转到新的窗口去,就需要把窗口进行切换。宏哥这里简单举例一个测试场景,你在页面A点击一个连接,会在新的tab窗口打开页面B,这个时候,你在页面B点击一个连接,会在新的tab窗口打开页面C。这种情况,在测试中经常遇到,自动化中,webdriver是如何处理的呢。这里就需要用到今天讲解和分享的知识了。
3.获取窗口句柄方法
获取所有(set<String>):
//获取所有打开窗口句柄,返回的是set类型
Set<String> handles = driver.getWindowHandles();
获取当前(String类型):
//获取当前窗口句柄,返回的是string类型
String handle = driver.getWindowHandle();
窗口切换方法:
//窗口切换方法,需传入想要切换窗口的句柄 driver.switchTo().window();
switch_to_window(window_name):
将定位的页面转到指定的window_name页面(window_name:指定页面窗口的handle)
4.项目实战1
我们先来看一个实例,在京东首页,点击手机,会在新的页面显示手机通讯的页面,在手机页面点击小米,会在新的窗口打开显示小米手机的页面。这个过程,刚好是页面A到页面B再到页面C。我们先抛开其他的,就是先实现driver在页面A切换到页面B,然后切换到页面C这个过程如何实现,在webdriver中提供了一个switch.to.window(handle)的方法。参数handle就是前面文章中提到的获取窗口句柄的值。
4.1代码设计
4.2参考代码
package lessons; import java.util.Set; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; /** * @author 北京-宏哥 * *《手把手教你》系列技巧篇(二十二)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换上卷(详细教程) * * 2021年8月27日 */ public class SwitchWinId { public static void main(String [] args) throws InterruptedException { System.setProperty("webdriver.gecko.driver", ".\Tools\chromedriver.exe"); //指定驱动路径 WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); driver.get("https://www.jd.com/"); Thread.sleep(1000); //点击京东左侧菜单中的 手机 WebElement phone_link = driver.findElement(By.linkText("手机")); phone_link.click(); Thread.sleep(1000); //切换至新窗口 //首先,我们要先获取到一个主句柄,作为灯塔,防止"迷路" String nowhandle = driver.getWindowHandle(); //接着我们要获取所有的句柄信息,并赋值给 handles //String[] handles=new String[driver.getWindowHandles().size()]; Set<String> handles = driver.getWindowHandles(); System.out.println("切换前的title:"+driver.getTitle()); //使用for循环,遍历所有的handles,以便判断 for (String handle:handles){ if(handle!=nowhandle) driver.switchTo().window(handle); } //让我们打印一下切换后窗口的 title System.out.println("切换后的title:"+driver.getTitle()); WebElement xiaomi_link = driver.findElement(By.linkText("小米")); xiaomi_link.click(); Thread.sleep(1000); } }
4.3.运行代码
1.运行代码,右键Run AS->java Application,控制台输出,如下图所示:
2.运行代码后电脑端的浏览器的动作,如下小视频所示:
上面在获取handles过程写了一个for循环,for循环的句柄和当前driver的句柄不相等,那么就调用切换窗口的方法,切换到第二个窗口,然后开始操作第二个窗口的元素,如果没有切换这一步骤,就操作第二个窗口的元素,则会报错找不到元素。其实除了这一种方法,还有其他的方法。例如:获取handles过程写了一个for循环,for循环的句柄和当前driver的句柄相等,那么就continue,也就是结束单循环,什么也不做。如果不是,那么就调用切换窗口的方法,切换到第二个窗口。
4.4方法二
4.4.1参考代码
package lessons; import java.util.ArrayList; import java.util.Set; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; /** * @author 北京-宏哥 * *《手把手教你》系列技巧篇(二十二)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换上卷(详细教程) * * 2021年8月27日 */ public class SwitchWinId { public static void main(String [] args) throws InterruptedException { System.setProperty("webdriver.gecko.driver", ".\Tools\chromedriver.exe"); //指定驱动路径 WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); driver.get("https://www.jd.com/"); Thread.sleep(1000); //点击京东左侧菜单中的 手机 WebElement phone_link = driver.findElement(By.linkText("手机")); phone_link.click(); Thread.sleep(1000); // 获取当前页面句柄 String handle = driver.getWindowHandle(); // 获取所有页面的句柄,并循环判断不是当前的句柄 for (String handles : driver.getWindowHandles()) { if (handles.equals(handle)) continue; driver.switchTo().window(handles); } WebElement xiaomi_link = driver.findElement(By.linkText("小米")); xiaomi_link.click(); Thread.sleep(1000); } }
5.项目实战2
可能有人就会提出,如果我需要第二个切换到第三个呢,假如说,在判断第三个句柄不等于第二个,那么driver会不会默认切换到第三个窗口还是切换到第一个呢。如果真要这么做,需要用到ArrayList,然后用到迭代,可能稍微变得复杂。为了避免这种复杂情况出现,我推荐这样做,只需要把上面代码中的continue语句改成driver.close(),前面文章介绍过,close是关闭当前页面。如果是页面A点击链接打开页面B,那么这个过程关闭的就是页面A,同时把driver切换到页面B。如果有第三个,从第二个页面到第三个页面也是用这样切换方法。这里永远就两个页面之间处理的关系。一般来说,自动化也是尽量在一个页面做完相关测试,才会切换到其他页面。
5.1代码设计
5.2参考代码
package lessons; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; /** * @author 北京-宏哥 * *《手把手教你》系列技巧篇(二十二)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换上卷(详细教程) * * 2021年8月27日 */ public class SwitchWinId { public static void main(String [] args) throws InterruptedException { System.setProperty("webdriver.gecko.driver", ".\Tools\chromedriver.exe"); //指定驱动路径 WebDriver driver = new ChromeDriver(); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); driver.get("https://www.jd.com/"); Thread.sleep(1000); //点击京东左侧菜单中的 手机 WebElement phone_link = driver.findElement(By.linkText("手机")); phone_link.click(); Thread.sleep(1000); // 获取当前页面句柄 String handle = driver.getWindowHandle(); // 获取所有页面的句柄,并循环判断不是当前的句柄 for (String temphandle : driver.getWindowHandles()) { if (!temphandle.equals(handle)) driver.close(); driver.switchTo().window(temphandle); } WebElement xiaomi_link = driver.findElement(By.linkText("小米")); xiaomi_link.click(); Thread.sleep(1000); } }
5.3运行代码
1.运行代码,右键Run AS->java Application,控制台输出,如下图所示:
2.运行代码后电脑端的浏览器的动作,如下小视频所示:
上面实现了页面A,切换到页面B,同时关闭页面A,页面B点击触发页面C,这个过程还需要用for循环判断一次。所以关于这块,宏哥建议你单独写成一个方法,例如静态方法,直接调用这个,就代码看起来很舒服。关于这个,在下卷中宏哥会介绍的,当然了在框架设计中如果用到的话也会封装一个方法进行调用。
6.小结
好了,今天关于窗口切换就分享到这里,感谢你耐心的阅读。