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

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

1.多windows操作。

在页面A上操作时,点击某个元素之后,可能会打开新的窗口。如果需要操作新窗口上的元素,进必须跳转到新的窗口上。

    @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);

    }

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

还有另为一种方式:

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

我们点击链接之后,打开新的窗口,就是因为这个链接中有属性 target="_blank"

所以,我们可以通过JQuery脚本来去除该元素的target的属性。去除之后再点击的时候,就不会打开新的浏览器窗口了。

这个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); }

selenium--driver.switchTo()的更多相关文章

  1. Selenium - IWebDriver.SwitchTo() frame 和 Window 的用法

    IWebDriver.SwitchTo().Frame(IWebElement frame) 如果一个页面是一个html元素, 只有一个head, 一个body, 那么使用IWebDriver.Fin ...

  2. Robot framework selenium driver download

    Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads http://npm.taobao.org/mirrors ...

  3. selenium driver版本和Chrome浏览器版本对应关系

    ChromeDriver v2.41 (2018-07-27) ---- Chrome v67-69ChromeDriver v2.40 (2018-06-07) ---- Chrome v66-68 ...

  4. selenium处理rich text(富文本框)

    WordPress 的 rich  text 采用js,先让selenium切换到iframe中 driver.switchTo().frame("content_ifr"); 然 ...

  5. selenium web driver 实现截图功能

    在验证某些关键步骤时,需要截个图来记录一下当时的情况 Webdriver截图时,需要引入 import java.io.File; import java.io.IOException; import ...

  6. selenium web driver 使用JS修改input属性

    selenium获取input时候,发现type=”hidden” 的input无法修改value,经牛人指点,可以使用js修改 首先html源文件如下,设置为text .hidden.submit ...

  7. 25+ Useful Selenium Web driver Code Snippets For GUI Testing Automation

    本文总结了使用Selenium Web driver 做页面自动化测试的一些 tips, tricks, snippets. 1. Chrome Driver 如何安装 extensions 两种方式 ...

  8. selenium web driver 配合使用testng

    首先为eclipse添加testng插件 步骤如下:help->Install New SoftWare... 2. 添加testng链接,该链接可以在这里找到 For the Eclipse ...

  9. Selenium Webdriver——操作隐藏的元素(三)switchTo().frame()

    在web 应用中经常会遇到frame 嵌套页面的应用,页WebDriver 每次只能在一个页面上识别元素,对于frame 嵌套内的页面上的元素,直接定位是定位是定位不到的.这个时候就需要通过switc ...

  10. 【Selenium】【BugList7】执行driver.find_element_by_id("kw").send_keys("Selenium"),报错:selenium.common.exceptions.InvalidArgumentException: Message: Expected [object Undefined] undefined to be a string

    [版本] selenium:3.11.0 firefox:59.0.3 (64 位) python:3.6.5 [代码] #coding=utf-8 from selenium import webd ...

随机推荐

  1. 2019.1.4 SSH框架整合步骤(一)

    SSH整合 1.三大框架整合原理 Spring与Struts2整合就是将Action对象交给Spring容器负责创建 Spring与Hibernate整合就是将sessionFactory交给Spri ...

  2. javascript返回顶部插件+源码

    javascript插件->returnTop.js: /* ** 插件名称returnTop.js ** 调用返回头部单例参数说明 ** 调用方式:turn.init(ele,speed); ...

  3. 【Java】使用Atomic变量实现锁

    Atomic原子操作 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类 Java从JDK1.5开始提供了java.uti ...

  4. #leetcode刷题之路35-搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置.你可以假设数组中无重复元素. 示例 1:输入: [1,3,5,6], 5输出: ...

  5. kali linux 安装TIM or QQ(CrossOver 安装 QQ)

    需要文件 http://www.crossoverchina.com/xiazai.html dpkg --add-architecture i386 apt-get update apt-get i ...

  6. php与java

    作者:eechen链接:https://www.zhihu.com/question/20377398/answer/141328982来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

  7. PHP程序员面试中经常被提问的问题【转载】

    1. Include 与 require的区别,require和require_once的效率哪个高? Php在遇到include时就解释一次,如果页面中出现10次include,php就解释10次, ...

  8. JavaScript 中 this 的原理

    一.问题 学习 JavaScript 其中一个标志就是理解下面两种写法,会输出有不一样的结果. var obj = { foo: function () {} }; var foo = obj.foo ...

  9. 集合之WeakHashMap

    WeakHashMap 底层数据结构是哈希表结构 依赖于键的数据结构特点 不同于HashMap,该类的键是以弱键的形式存在 当该键成为垃圾对象,会被垃圾回收期空闲的时候回收,那么改键所对应值也会被回收 ...

  10. 学习/linux/list.h_双链表实现

    linux-3.5/include/linux/list.h 使用只含指针域的双向循环链表进行链表的操作. 下面是我选取部分list.h中代码: #ifndef _LINUX_LIST_H #defi ...