selenium--driver.switchTo()

在自动化测试中,会遇到多窗口、多iframe、多alert的状况。此时,会使用driver.switchTo()来解决。javascript

下面时关于driver.switchTo()的详细介绍:css

1.多windows操做。html

在页面A上操做时,点击某个元素以后,可能会打开新的窗口。若是须要操做新窗口上的元素,进必须跳转到新的窗口上。java

    @Test
    public void fTest() throws InterruptedException {
        //launchBrowser是本身封装的方法 ,主要是为了启动浏览器驱动,打开指定url,页面加载的等待超时时间设置为3S
     //这里测试使用的是qq邮箱的登陆页面
launchBrowser("https://mail.qq.com/cgi-bin/loginpage", 3); //定位并点击“手机版”元素,打开手机版页面,此时会打开新的窗口 driver.findElement(By.partialLinkText("手机版")).click(); Thread.sleep(3000); //获取当前窗口句柄(此时是得到https://mail.qq.com/cgi-bin/loginpage页面的句柄) String currentHandle = driver.getWindowHandle(); //得到全部的窗口句柄,若是不是currentHandle,则进入 Set<String> windowHandles = driver.getWindowHandles(); for (String windowHandle : windowHandles) { if (!currentHandle.equals(windowHandle) ) { //进入到手机版页面的窗口 driver.switchTo().window(windowHandle); } } //此时才能操做手机版页面的元素 driver.findElement(By.cssSelector("a[href='http://app.mail.qq.com/cgi-bin/appdownload?check=false&stype=1&subtype=8&fr=&url=ios&downloadclick=']")).click();;

      //若是想要操做qq邮箱登陆页面的元素,此时须要退回到以前的窗口
      driver.switchTo().window(currentHandle);mysql

         
    }

上面是经过switchTo()方法,进入新的页面,并操做对应元素。jquery

还有另为一种方式:linux

<a href="http://app.mail.qq.com/" target="_blank">手机版</a>ios

咱们点击连接以后,打开新的窗口,就是由于这个连接中有属性 target="_blank"web

因此,咱们能够经过JQuery脚原本去除该元素的target的属性。去除以后再点击的时候,就不会打开新的浏览器窗口了。sql

这个qq邮箱的页面http://app.mail.qq.com/,首次执行JQuery会失败,第二次会成功。猜想多是由于第一次执行以后,会触发引入jQuery的操做。为了使代码具备通用性,直接引入jQuery。

可是不少安全性高一些的网站,会限制引入的域名地址。会形成引入JQuery失败。为了解决该问题,教你们一个万能的方法:下载某页面的JQuery源代码,放到本地文件中。封装读取并执行JQuery的帮助类。

帮助类代码:

package com.claire.jing.utils;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.openqa.selenium.JavascriptExecutor;

public class ImportJQueryUtil {
    
    public static void importJQueryUtil(JavascriptExecutor jse) {
        StringBuffer buffer = new StringBuffer();
        
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream("F:\\开发资料\\jQuery源码\\jquery-1.10.2.min.js");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        InputStreamReader reader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String temp=null;
        try {
            while ((temp = bufferedReader.readLine()) !=null) {
                buffer.append(temp);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        jse.executeScript(buffer.toString());
    }
    
    

}

使用JQuery来删除元素指定属性

@Test
    public void fTest() throws InterruptedException {
        //方式2:使用JQuery来删除target="_blank"
        //launchBrowser是本身封装的方法 ,主要是为了启动浏览器驱动,打开指定url,页面加载的等待超时时间设置为3S
        launchBrowser("https://mail.qq.com/cgi-bin/loginpage", 20);
        
        //该js脚本判断是否引入了JQuery
        String js = "return (typeof($)==\"undefined\")";
        boolean flag = (boolean)((JavascriptExecutor)driver).executeScript(js);
        
        //若是没引入,则调用帮助类,执行JQuery源码。
        //这里之因此不使用直接增长Script节点引入JQuery,是由于不少安全性高一些的网站,会限制引入的域名地址。会形成引入JQuery失败
        if (flag) {
            ImportJQueryUtil.importJQueryUtil((JavascriptExecutor)driver);            
        }
        //这里能够判断下,是否引入成功了
        //System.out.println((boolean)((JavascriptExecutor)driver).executeScript(js));
        

        
        
        //<a href="http://app.mail.qq.com/" target="_blank">手机版</a>
        //该a连接带有属性target="_blank"--拥有该属性的连接,点击后才会打开新的页面。只要经过js来移除该属性,点击以后,就不会打开新的浏览器窗口了
        String jquery = "var com=$('a[href=\"http://app.mail.qq.com/\"]');"
                + "com.removeAttr(\"target\");"
                + "com[0].click();";
        
        ((JavascriptExecutor)driver).executeScript(jquery);
        //观察一下执行结果
        Thread.sleep(4000);
        quit();
        

    }

2.Iframe

有些页面元素时包在IFrame中的,此时想要操做Iframe上的元素,必须先进入Iframe里面去。

 下面举例多层iframe嵌套的状况:

    @Test
    public void fTest() throws InterruptedException {
        launchBrowser("http://XXX/index.html", 10);
        //为了避免须要每次都登陆,能够设置添加cookie()
                driver.manage().deleteCookieNamed("JSESSIONID");
                driver.manage().addCookie(new Cookie("qqq", "BD04BA5FA2019D6C9DB28E25A5B14D85"));
                try {
                    //为了cookie使用的久一些,能够设置cookie的有效期。
                    //即便这里设置了cookie有效期,cookie也是有可能会无效的(通常状况下,会将sessionId存到cookie中):
                    //第一:服务端的session是有有效期的,若是session过时了,那么这个cookie也就无效了。
                    //第二,当服务端的内存报警时,就可能会清除session。这种状况下,你的cookie也会失效
                    //第三,当服务端重启以后,缓存和session都会清空的,你的cookie天然就失效了
                    driver.manage().addCookie(new Cookie("JSESSIONID", "FB9F06DDF0D15C491EFAD6D444893F80","/lmcanon_web_auto",(new SimpleDateFormat("yyyy-MM-dd hh:m:ss")).parse("2018-12-12 12:12:12") ));
                } catch (ParseException e) {
                    logger.error("日期转换出错");
                    e.printStackTrace();
                }
        
        driver.get("http://XXX/index.html");
        logger.info("成功打开首页");
        
        
        driver.findElement(By.cssSelector("i[class=\"Hui-iconfont menu_dropdown-arrow\"]")).click();
        logger.info("成功定位习题管理,并点击");
        
        
        //定位习题管理子标签,该标签是须要点击父标签习题管理以后,才会可见的。
        //下面使用了ExpectedConditions中提供的visibilityOfElementLocated()来判断该字标签是否可见,可见以后才对其进行点击操做
        WebDriverWait wait = new WebDriverWait(driver, 3);            
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a[data-href=\"stem-list.html\"]"))).click();
        logger.info("成功定位子元素习题管理并点击");
        
        //想要点击“添加习题”按钮,发现该按钮在iframe中,必须先进入iframe才能定位并操做该元素
        WebElement IframeElement = waitElement(By.cssSelector("iframe[src='stem-list.html']"));
        driver.switchTo().frame(IframeElement);
        logger.info("成功进入第一层Iframe,并进入");
        
        driver.findElement(By.cssSelector("a[class=\"btn btn-primary radius\"]")).click();
        logger.info("成功定位第一层frame内的添加习题按钮并点击");
        
        //嵌套iframe状况,想要点击添加习题弹窗上的元素,就必须进入第二层iframe
        //进入第二层Iframe
        //首先定位第二层iframe <iframe scrolling="auto" allowtransparency="true" id="layui-layer-iframe2" name="layui-layer-iframe2" onload="this.className='';" class="" frameborder="0" src="./stemAndItem-add.html" style="height: 467px;"></iframe>
        WebElement iframe2 = driver.findElement(By.id("layui-layer-iframe2"));
        driver.switchTo().frame(iframe2);
        logger.info("成功进入第二层iframe");
        
        //定位第二层iframe的元素
        //<select class="select valid" name="subjectType" aria-required="true" aria-invalid="false"><option value="0">--请选择--</option><option value="1">软件测试基础</option><option value="2">mysql数据库</option><option value="3">linux</option><option value="4">java</option></select>
        WebElement subjectType = driver.findElement(By.cssSelector("select[name=\"subjectType\"]"));
        Select select = new Select(subjectType);
        select.selectByIndex(2);
        logger.info("成功定位第二层iframe内的题目领域元素,并选择为mysql数据库");
        
        
        //退出当前iframe-----注意:下面方法是退回到的top window 层
        driver.switchTo().defaultContent();
        logger.info("成功退回到first frame.");
        
        //操做topWindow上的元素,证实成功退回
        driver.findElement(By.cssSelector("i[class=\"Hui-iconfont menu_dropdown-arrow\"]")).click();
        logger.info("成功定位习题管理,并点击");
        
        
    }

 

3.alert操做

其实如今前台系统中的alert页面愈来愈少了。由于它的体验不是很好。可是在一些后台系统中,仍是会遇到alert操做。Alert弹窗分三种,Alert,prompt(须要输入内容的弹窗),confirm


1. alert() 弹出个提示框 (肯定) 
警告消息框 alert 方法有一个参数,即但愿对用户显示的文本字符串。该字符串不是 HTML 格式。该消息框提供了一个“肯定”按钮让用户关闭该消息框,而且该消息框是模式对话框,也就是说,用户必须先关闭该消息框而后才能继续进行操做。

 

2. confirm() 弹出个确认框 (肯定,取消) 
确认消息框 使用确认消息框可向用户问一个“是-或-否”问题,而且用户能够选择单击“肯定”按钮或者单击“取消”按钮。confirm 方法的返回值为 true 或 false。该消息框也是模式对话框:用户必须在响应该对话框(单击一个按钮)将其关闭后,才能进行下一步操做。

 

3. prompt() 弹出个输入框(肯定,取消)。

若是用户单击提示框的取消按钮,则返回 null。若是用户单击确认按钮,则返回输入字段当前显示的文本。

在用户点击肯定按钮或取消按钮把对话框关闭以前,它将阻止用户对浏览器的全部输入。在调用 prompt() 时,将暂停对 JavaScript 代码的执行,在用户做出响应以前,不会执行下一条语。

 

    @Test
    public void fTest() throws InterruptedException {
    
        launchBrowser("D:\\javascript\\Untitled-3.html", 10);
        
        WebDriverWait wait = new WebDriverWait(driver, 3);
        Alert alert2 = wait.until(ExpectedConditions.alertIsPresent());
        System.out.println(alert2.getText());
        //取消
        alert2.dismiss();
        //肯定
        alert2.accept();
        //输入内容
        alert2.sendKeys("hello");
        Thread.sleep(4000);        
        
    }
本站公众号
   欢迎关注本站公众号,获取更多信息