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. [App Store Connect帮助]八、维护您的 App(1)App 维护概述

    您在 App Store 上发行 App 后,需要执行一些任务来回复顾客反馈并在整个产品周期内维护您的 App.您可以按任何顺序执行这些任务. 监控顾客评论.销售情况和分析 您可以在 App 页面的“ ...

  2. 安装MySQL需要注意的事项

    一.安装MySQL之后,怎样启动MySQL,以及登录.查看数据库操作? 用管理员身份运行cmd或power shell 二.当然有可能会出现不能在cmd或power shell中登录数据库账户 造成这 ...

  3. 超级实用的VSCode插件,帮你大幅提高工作效率

    Visual Studio Code是一个轻量级但功能强大的源代码编辑器,可在桌面上运行,适用于Windows,macOS和Linux. 它内置了对JavaScript,TypeScript和Node ...

  4. [Usaco2005 Dec]Knights of Ni 骑士

    Description Bessie is in Camelot and has encountered a sticky situation: she needs to pass through t ...

  5. 输入一个秒数,要求转换为XX小时XX分XX秒的格式输出出来;

    package arithmetic; import java.util.Scanner; import org.junit.Test; public class Test02 { /** * 输入一 ...

  6. 导出数据库报错 EXP-00002: 写入导出文件时出错 EXP-00000: 导出终止失败

    解决方法: 1.检查磁盘所在空间是否够用. 2.磁盘修复下 排除故障考虑的地方要全面啊.

  7. ORA-28002错误原因及解决办法

    在oracle database 11g中,默认在default概要文件中设置了“PASSWORD_LIFE_TIME=180天”所导致.密码过期后,业务进程连接数据库异常,影响业务使用.数据库密码过 ...

  8. [转]无废话SharePoint入门教程二[SharePoint发展、工具及术语]

    本文转自:http://www.cnblogs.com/iamlilinfeng/p/3186919.html 一.前言 1.由于上一篇文章的标题命名失误,此篇标题写给百度搜索”什么是SharePoi ...

  9. Spring框架学习-搭建第一个Spring项目

    步骤一:下载Spring开发包. 官网:https://spring.io/           下载地址:https://repo.spring.io/libs-release-local/org/ ...

  10. 原型模式及php实现

    原型模式: 通过复制已经存在的实例来返回新的实例,而不是新建实例,并且原型(被复制的实例)是可定制的:原型模式多用于创建复杂的或耗时的实例,这种情况下,复制一个已经存在的实例是程序运行更高效无疑是一种 ...