https://www.cnblogs.com/clairejing/p/9499223.html

在自动化测试中,会遇到多窗口、多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. Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)_python

    我们可以利用urllib来抓取远程的数据进行保存哦,以下是python3 抓取网页资源的多种方法,有需要的可以参考借鉴. 1.最简单 import urllib.request response = ...

  2. Lightoj 1054 - Efficient Pseudo Code

    题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1054 题目大意: 给出n,m,问n^m的所有因子之和是多少? 解题思路: 补 ...

  3. Oracle函数大全下载

    Oracle函数大全下载 是一个压缩包,里面是一个chm格式的帮助文档,很实用.

  4. 关于react native在window下运行安卓的时候报 could not connect to development server

    当出现这种问题是网上的解答方案都是一模一样的! 我这边先给个地址讲的是解决方案http://blog.csdn.net/qq_25827845/article/details/52974991 但是我 ...

  5. Android 在代码中安装 APK 文件

    废话不说,上代码 private void install(String filePath) { Log.i(TAG, "开始执行安装: " + filePath); File a ...

  6. InChatter系统开源聊天模块前奏曲

    最近在研究WCF,又因为工作中的项目需要,要为现有的系统增加一个聊天模块以及系统消息提醒等,因此就使用WCF做服务器端开发了一个简单的系统. 开发最初学习了东邪孤独大哥的<传说的WCF系列> ...

  7. Divide and Conquer_1.最大连续子数组

    给定一个数组,求它的一个子数组,使其求和最大. 这个问题的应用:给定一只股票很多天的价格,计算从哪天买进哪天卖出能获得最大利润. 给定 prices:100   113   98   87   65  ...

  8. swift class type isa-swizzling

    class 是引用类型,生成的实例分布在 Heap(堆) 内存区域上,在 Stack(栈)只存放着一个指向堆中实例的指针.因为考虑到引用类型的动态性和 ARC 的原因,class 类型实例需要有一块单 ...

  9. laravel学习:容器绑定与解析

    1.在服务容器中注册类(bind) $this->app->bind('sender','MailSender');//$this->app成为服务容器.   2.从服务容器生成类( ...

  10. ALTER DOMAIN - 改变一个域的定义

    SYNOPSIS ALTER DOMAIN name { SET DEFAULT expression | DROP DEFAULT } ALTER DOMAIN name { SET | DROP ...