在自动化测试中,会遇到多窗口、多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. Mac OS系统下配置hosts的方法

    首先,介绍下什么是hosts Hosts是一个没有扩展名的系统文件,可以用系统自带的记事本等工具打开,作用就是将一些常用的网址域名与其对应的IP地址建立一个关联,当用户在浏览器输入一个需要登录的网址时 ...

  2. php无极限分类函数

    /** * [make_tree description] * @Author Lerko * @DateTime 2017-04-01T14:57:24+0800 * @param [type] $ ...

  3. 剑指offer5 从尾到头打印链表

    错误代码: class Solution { public: vector<int> printListFromTailToHead(ListNode* head){ vector< ...

  4. Page Object设计模式(项目整体结构)

    1. 什么是框架 1.1 定义: 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件(类)及构件(类)实例间交互的方法. 1.2 为什么要搭建自动化测试框架 自动化测试的开发, ...

  5. POJ 1949 Chores (很难想到的dp)

    传送门: http://poj.org/problem?id=1949 Chores Time Limit: 3000MS   Memory Limit: 30000K Total Submissio ...

  6. HDU 1014 Uniform Generator(模拟和公式)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1014 Uniform Generator Time Limit: 2000/1000 MS (Java ...

  7. 2018 kali linux install tools

    1.VM setup https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html VMware-Wo ...

  8. Oracle批量删除表格数据

    在开发阶段往Oracle数据库中多个表格中导入了许多测试数据,倘若一张张表执行"truncate table tablename"语句显得十分繁琐.在PL/SQL中可以用代码进行批 ...

  9. WebService 学习笔记(一、概念及定义)

    定义 WebService是一种服务导向架构(SOA service-oriented architecture)的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作. Web ...

  10. thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法

    这篇文章主要介绍了thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法,结合简单示例形式分析了thinkPHP5框架验证码相关配置.后台验证.前台刷新等操作技巧,学习thinkphp源码的朋 ...