整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Vue进阶(七十九):使用postMessage实现

Vue进阶(七十九):使用postMessage实现父子通信

.子向父通信

parent.html

// 页面销毁前,务必去除监听器,否则会造成资源泄露!
beforeDestory () {
	window.removeEventListener('message', this.listenerFun)
}
mounted() {
	window.addEventListener('message',this.listenerFun)
}
methods: {
	listenerFun (e) {
		console.log(e.data);
    if(e.data.msg==='xxx'){
      // 业务处理逻辑
    }
	}
}

child.html

内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。

多窗口和窗体:

可以打开多个浏览器窗口,每个窗口都是独立的;

一个浏览器窗口可能包含多个标签页;每个标签页都是独立的上下文,都是独立的window对象,而且相互之间互不干扰;

但是窗口也并不总是和其他窗口完全没有关系;一个窗口或标签页中的脚本可以打开新的窗口或标签页,如此,这些多窗口或标签页就可以互相操作;

打开窗口:

window.open()方法,打开一个新的浏览器窗口、标签页,导航到一个指定的URL;

语法:window.open(url,name,features,replace);url为打开新窗口的url,name为窗口目标,features设置窗口特性参数列表,replace为Boolean值,指定是否用新窗口替换当前页面;

一般使用第一个参数,如果也省略该参数或使用空字符串,则会打开一个空页面的URL about:blank;

如果使用第二个参数,而且该参数是已有窗口或框架的名称,就会在该窗口或框架中加载指定的URL;否则弹出新窗口,并将新窗口的name命名为该参数,如果省略此参数,则会使用指定的“_blank”打开一个新的、未命名的窗口;

第二个参数也可以是:_self、_parent、_top、_blank;

窗口的名字也可作为<a>和<form>元素上target属性的值,用来表示引用的文档或提交处理的页面;

<script>
window.open("https://www.zeronetwork.cn/","myWindow");
</script>
<a href="https://www.google.cn/" target="myWindow">baidu.com</a>

窗口特性属性:

第三个参数是一个逗号分隔的设置字符串,表示在新窗口中都显示哪些特性;如果省略,则以默认的形式呈现;

  • fullscreen:yes / no,是否最大化;仅限IE;
  • height:数值,新窗口的高,不能小于100;
  • left:数值,新窗口的左坐标,不能是负值;
  • location:yes / no,是否显示地址栏;不同浏览器的默认值不同;设置为no,地址栏有可能会隐藏,也有可能会被禁用;
  • menubar:yes / no,是否显示菜单栏,默认为no;
  • resizable:yes / no,是否能改变大小,默认为no ;
  • scrollbars:yes / no,如果内容区域大于视口,是否允许滚动,默认为no;
  • status:yes / no,是否显示状态栏,默认为no;
  • toolbar:yes / no,是否显示工具栏,默认为no;
  • top:数值,新窗口的上坐标,不能是负值;
  • width:数值,新窗口的宽,不能小于100;

字符串格式为:设置使用键值对,且全部使用逗号分隔,而且不能有空格;

window.open("https://www.zeronetwork.cn/","myWindow",
            "width=400,height=400,top=50,left=50,resizable=yes");

显式指定这些特性,打开的应该是新窗口,而不是新标签页;这个参数是非标准的,而且HTML5也主张浏览器应该忽略它;

另外,出于安全考虑,浏览器包含对可能指定的功能的限制,如,通常不允许指定一个太小的或者位于屏幕之外的窗口,并且一些浏览器不允许创建一个没有状态栏的窗口;

第四个参数只有在设置了第二个参数命名的是一个已存在的窗口时才有用;它是一个布尔值,声明了由第一个参数指定的URL是替换掉窗口浏览历史的当前记录(true)还是应该在窗口浏览历史中创建一个新的记录(false),默认为false;

window.open()会返回一个window对象,用于操作新创建的窗口;该引用可以操作新窗口的内容,从而就可以在一个窗口中控制另一个窗口的内容,例如向一个新开的浏览器窗口中输出内容;

var w = window.open();  // 打开一个新的空白窗口
w.document.write("<h2>零点网络</h2>");
w.alert("详情请进入https://www.zeronetwork.cn/");
w.location = "https://www.zeronetwork.cn/";

某些浏览器在默认情况下可能不允许针对主浏览器窗口调整大小或移动,但不允许针对通过open()创建的窗口调整大小或移动,如:

var newWindow = window.open("https://www.zeronetwork.cn/","myWindow",
            "width=400,height=400,top=50,left=50,resizable=yes");
newWindow.resizeTo(600,600);
newWindow.moveTo(200,200);

注:有些浏览器默认不允许这样操作;

窗口opener属性:

opener属性是新窗口对打开它的原始窗口的引用;即指向调用window.open()的窗口或框架;但只在弹出窗口的最外层window对象(top)中有定义;

var newWindow = window.open("https://www.zeronetwork.cn/","myWindow",
            "width=400,height=400,top=50,left=50,resizable=yes");
console.log(newWindow.opener === window); // true
 
<!-- 主窗口 -->
<input type="text" id="selectCity" placeholder="选择" />
<script>
var selectCity = document.getElementById("selectCity");
selectCity.onclick = function(){
    var newWin = window.open("select.html","newWin","width=400,height=400");
}
</script>
 
<!-- 新窗口 -->
<select id="city">
    <option value="beijing">北京</option>
    <option value="nanjing">南京</option>
    <option value="anhui">安徽</option>
</select>
<script>
var city = document.getElementById("city");
city.onchange = function(){
    window.opener.document.getElementById("selectCity").value = city.options[city.selectedIndex].value;
    window.close();
}
</script>

有些浏览器(如IE8和Chrome)会在独立的进程中运行每个标签页,当一个标签页打开另一个标签页时,如果两个window对象之间需要彼此通信,那么新标签页就不能运行在独立的进程中。在Chrome中,将新创建的标签页的opener属性设置为null,即表示在单独的进程中运行新标签页。

newWindow.opener=null;

标签页之间的联系一旦切断,将没有办法恢复。

window.close()关闭窗口:

对于主窗口,如果没有得到用户的允许是不能关闭它的;但弹出窗口可以不经用户允许可以关闭自己;

窗口关闭后,窗口的引用仍然存在,可以使用window.closed属性检测,但在实际场景中没有多大用处;

function openWin(){
    var newWindow = window.open("https://www.zeronetwork.cn/","myWindow",
            "width=400,height=400,top=50,left=50,resizable=yes");
    newWindow.document.write("<h2>零点网络</h2>");
    function closeWin(){
        newWindow.close();
        //alert(newWindow.closed);
        if(newWindow.close)
            alert("已关闭");
    }
    setTimeout(closeWin,3000);
}
openWin();

注:document对象也有close()方法,为了避免混淆,所以调用close()方法时,要显式调用,即使用window.close();

安全限制:

大多数浏览器针对弹出窗口实施了多方面的安全限制,如:不允许在屏幕之外创建弹出窗口,不允许将弹出窗口移动到屏幕之外,不允许关闭状态栏等;不允许关闭地址栏,默认情况下不允许移动弹出窗口或调整其大小;或者部分浏览器不支持修改状态栏,始终显示地址栏等;

通常,对于open()方法只有当用户手动单击按钮或超链接时才会调用;如果尝试在浏览器初始载入时开启一个弹出窗口时,通常会被屏蔽;

弹出窗口屏蔽程序:

大多数浏览器都内置有弹出窗口屏蔽程序,如果没有内置,可以安装第三方实用工具;内置屏蔽会使window.open可能返回null,第三方会返回错误;通过需要检测其返回值;

// 内置的屏蔽程序
var newWin = window.open("https://www.zeronetwork.cn/","_blank");
if(newWin == null){
    alert("弹窗被阻止!");
}
 
// 第三方
var blocked = false;
try{
    var newWin = window.open("https://www.zeronetwork.cn/","_blank");
    if(newWin == null)
        blocked = true;
}catch(e){
    blocked = true;
}
if(blocked){
    alert("弹窗被屏蔽");
}

弹出窗口通信:

主窗口向新窗口传值,直接为新窗口window对象添加成员,如:

// 主窗口
var newWin = window.open("select.html","_blank");
var person = {
    name:"wangwei",
    sex: true,
    age: 18
}
newWin.person = person;
 
// 新窗口
document.write("姓名:",person.name);
document.write("性别:",person.sex);
document.write("年龄:",person.age);

新窗口向主窗口传值,通过window.opener获取原始窗口的属性或者html元素;

<!-- 主窗口 -->
<div id="mydiv"></div>
<script>
var newWin = window.open("select.html","_blank");
function showDiv(str){
    var mydiv = document.getElementById("mydiv");
    mydiv.innerHTML = str;
}
</script>
 
<script>
// 新窗口
var str = "零点网络";
window.opener.showDiv(str);
window.close();
</script>

通过普通的get传值;

// 主窗口
function putId(id){
    window.open("select.html?id=" + encodeURIComponent(id),"putWin");
}
putId("1002");
 
// 新窗口
var id = location.search;
id = id.split("=");
console.log(id[1]);
document.write(decodeURIComponent(id[1]));

框架窗口:

如果页面使用了框架集合(包含frameset和iframe),则每个框架都由它自己的window对象表示,并存放在frames集合中;

与相互独立的标签页或窗口不同,框架窗口之间并不是相互独立的;

每个window对象都有一个name属性,其中包含框架的名称;

<frameset rows="100,*">
    <frame src="top.html" name="topFrame" />
    <frameset cols="50%,50%">
        <frame src="left.html" name="leftFrame" />
        <frame src="right.html" name="rightFrame" />
    </frameset>
</frameset>

在frames集合中,可用数字(下标从0开始,从左到右,从上到下)访问;即可以使用frames[0]表示第1个子窗口、frames[1]表示第2个子窗口;

可使用名称对框架进行访问,该名称就是该框架的name属性,如 window.frames[“topFrame”]引用;

也可以window.topFrame 使用架框的名字访问;

window.onload = function(){
    console.log(frames);
var topFrame = frames[0];
    console.log(topFrame);
    console.log(topFrame.name);
    var leftFrame = window.frames["leftFrame"];
    console.log(leftFrame.name);
    console.log(window.rightFrame.name);
}

可使用frames.length 取得框架集合长度;

如果是内联框架,那就更简单了,如:

<iframe src="right.html" name="myFrame" width="200" height="200"></iframe>
<script>
    console.log(frames);
    console.log(frames[0].name);
</script>

对于顶级窗口的window对象来说,可以看作为由若干个子窗口组成的窗口数组,也就是说可以把window对象当作为窗口的集合,如:

    console.log(window.length);
    console.log(window[0]);

但在实际场景中,最好还是使用frames来代替window,因为frames显得更清晰些;

对于<iframe>元素,如果设置了id,也可以通过document.getElementById()方法获取,如:

var myframe = document.getElementById("myframe");
console.log(myframe);
myframe.src = "one.html";

<iframe>元素有contentWindow属性,引用该窗体的window对象,所以此窗体的window对象就是:

var mywin = document.getElementById("myframe").contentWindow;
console.log(mywin);
mywin.document.write("是内联框架window对象");

可以进行反向操作,通过window对象的frameElement属性,来获取该窗体的<iframe>元素;表示顶级窗口的window对象的frameElement属性为null,窗体中的window对象的frameElement属性不是null;

var myframe = document.getElementById("myframe");
var mywin = myframe.contentWindow;
console.log(mywin.frameElement);
console.log(mywin.frameElement === myframe);
console.log(window.frameElement);
 
// 在one.html会返回<iframe id="myframe" src="one.html"></iframe>
console.log(window.frameElement);

尽管可以通过document.getElementById()和contentWindow属性来获取窗口中的子窗体的引用,但在实际场景中,用的还是比较少,主要还是使用frames属性来访问;

top对象:

可以使用top引用最顶层(外层)框架,就是浏览器窗口;使用它可以确保在一个框架中正确的访问另一个框架;

// 框架集页面
window.onload = function(){
    console.log(frames);
    console.log(top);
console.log(top === frames);  // true
console.log(top === window);  // true
    console.log(frames === window);  // true
}
// 框架页面
console.log("topFrame:",frames);
console.log("topFrame:",top);
console.log("topFrame:",top === frames);  // false

因此,使用top访问框架时,也可以如下:

    console.log(top[0].name);
    console.log(top["topFrame"].name);
    console.log(top.topFrame.name);
 
    console.log(top.frames[0].name);
    console.log(top.frames["topFrame"].name);
console.log(top.frames === frames);  // true

parent对象:

与top相对的另一个window对象是parent,其指的当前框架的直接上层框架,即父框架;

parent在不同的位置指不同的对象;在某些情况下,parent有可能等于top,但在没有框架的情况下,parent一定等于top(此时,它们都等于window),如:

<!-- frameset.html -->
<frameset rows="100,*">
    <frame src="top.html" name="topFrame" />
    <frameset cols="50%,50%">
        <frame src="left.html" name="leftFrame" />
        <frame src="right.html" name="rightFrame" />
    </frameset>
</frameset>
<!-- right.html -->
<frameset cols="50%,50%">
    <frame src="one.html" name="oneFrame" />
    <frame src="two.html" name="twoFrame" />
</frameset>

// one.html中的代码
var parentFrame = window.parent;
console.log("从one.html中访问:",parentFrame.name);  // rightFrame
parentFrame.frames[1].document.write("<h2>框架访问</h2>");
 
// top.html中的代码
var parentFrame = window.parent;
console.log("top:", parentFrame.name);
console.log("top:", parentFrame.length);
console.log("top:", parentFrame.frames.length);
console.log("top:", parentFrame === top);  // true
console.log("top:", parentFrame.frames[1].name);
parentFrame.frames[1].document.write("<h2>是left页面吗?</h2>");

注:除非最顶层的窗口是通过window.open()打开的,否则其window对象的name属性不会包含任何值;

self对象:

指向当前window自身,即self和window可以互换使用;

引入self的目的只是为了与top和parent对象对应起来;

对于顶级窗口,parent==self; // true

注:所有的这些对象都是window对象的属性,可以通过window.parent、window.top等形式访问;同时,这也意味着可以将不同层次的window对象连接起来,如:window.parent.parent.frames[0];

窗口交互:

对于一个复杂的框架,窗口之间可以相互访问,它主要包括对框架自身的引用、父窗口对子窗口的引用、子窗口对父窗口及其他窗口的引用、对顶级窗口的引用;

在使用框架的情况下,浏览器中会存在多个Global对象,即每个窗口都会有自己的执行上下文,在每个框架中定义的全局变量会自动成为框架中window对象的属性;

<!-- right.html -->
<div id="myDiv"></div>
<div id="imgDiv"></div>
<script>
function showImg(){
    var imgDiv = document.getElementById("imgDiv");
    var img = document.createElement("img");
    img.src = "images/1.jpg";
    imgDiv.appendChild(img);
}
</script>
 
// 框架集页面
window.onload = showDiv;
function showDiv(){
    var rightFrame = parent[2];
    var myDiv = rightFrame.document.getElementById("myDiv");
    myDiv.innerHTML = "<h2>零点网络</h2>";
}
 
<!-- top.html -->
<h2>Top页面</h2>
<div><button id="showBtn">显示图片</button>
    <button id="closeBtn">关闭图片</button></div>
<script>
window.onload = function(){
    var showBtn = document.getElementById("showBtn");
    var closeBtn = document.getElementById("closeBtn");
    var rightFrame = top[2];
    showBtn.onclick = rightFrame.showImg;
    closeBtn.onclick = closeImg;
}
function closeImg(){
    var rightFrame = top.rightFrame;
    var imgDiv = rightFrame.document.getElementById("imgDiv");
    imgDiv.innerHTML = "";
}
</script>

对于构造函数,它也是函数,所以当用构造函数和相关的原型对象定义一个自定义类时,这个类只在一个单独的窗口中定义;子窗口也可以引用这个类;

对于内置类来说,和自定义类就有所不同了;内置的类都会在所有的窗口中自动预定义,即每个窗口的window对象都包含原生类型的构造函数,因此每个框架一套自己的构造函数,这些构造函数一一对应,但并不相等;如:top.Object并不等于top.frames[0].Object,这个问题会影响到对跨框架传递的对象使用instanceof操作符;

WindowProxy对象:

window对象是客户端Javascript的全局变量;但是从技术上来看,并不是这样的;Web浏览器每次向窗口或窗体中载入新的内容,它都会开始一个新的JavaScript执行上下文,包含一个新创建的全局对象;但是当多个窗口或窗体在使用时,有一个重要的概念,尽管窗体或窗口载入了新的文档,但是引用窗体或窗口的window对象还仍然是一个有效的引用;

所以客户端Javascript有两个重要的对象;客户端全局对象处于作用域链的顶级,并且是全局变量和函数所定义的地方;事实上,全局对象会在窗口或窗体载入新内容时被替换;

而我们称之为“window对象”的对象实际上不是全局对象,而是全局对象的一个代理;每次查询或设置window对象的属性时,就会在窗口或窗体的当前全局对象上查询或设置相同的属性;

HTML5规范称这个代理对象为WindowProxy;由于它的代理行为,除了有更长的生命周期之外,代理对象表现得像真正的全局对象;如果可以比较两个对象,那么区分它们会很困难;但是事实上,没有办法可以引用到真正的客户端全局对象;全局对象处于作用域链的顶端,但是window、self、top、parent以及窗体的属性全部返回代理对象;window.open()也返回代理对象;甚至顶级函数里this的值也是代理对象,而不是真正的全局对象;


Web前端开发之Javascript-零点程序员-王唯

、介绍

selenium目前主流的web自动化测试框架;支持多种编程语言Java、pythan、go、js等;selenium 提供一系列的api 供我们使用,因此在web测试时我们要点页面中的某一个按钮,那么我们只需要获取页面,然后根据id或者name找到对应的按钮,然后执行click操作就可以完成点击这一个动作。测试点点点虽然容易复现,但做回归测试的时候会出现大量重复的工作,因此可以通过自动化,每次做回归测试我们只需要运行相关的脚本即可。Selenium2:使用Selenium自动化测试框架,主要用到Selenium Webdriver模块,能模拟提供浏览器、页面元素定位、元素操作、鼠标键盘等相关的操作和方法;

ui自动化测试主要应用在回归测试、兼容性测试、冒烟测试等测试场景;适合的是需求稳定、项目周期长、测试脚本可以复用的项目。


二、selenium安装及配置

浏览器:谷歌chrome(推荐)、火狐、IE等

驱动:chromedriver.exe(谷歌) 地址:ChromeDriver - WebDriver for Chrome - Downloads

安装selenium包:pip install selenium -U ,-U 表示已安装则更新



下载对应浏览器版本 的chromedriver.exe,否则有可能会报找不到驱动的错;把驱动包放到python的根目录下

WebDriver原理图:WebDriver是一个基于HTTP的协议,它提供了一系列的接口用于发现和控制 Web 文档中的 DOM 元素,几乎可以操作浏览器做任何事情。总的来说就是python编写代码,通过webdriver控制浏览器。


三、脚本实例

from selenium import webdriver

import time


#打开浏览器

driver=webdriver.Chrome()

#浏览器最大化

driver.maximize_window()

# 打开baidu

driver.get("http://www.baidu.com")

#打印浏览器地址

print(driver.current_url)

#打印网页标题

print(driver.title)

#暂停一会,3 秒

time.sleep(3)

#关闭当前窗口

driver.close()

#关闭整个浏览器,并且关闭驱动chromedriver

driver.quit()


Unittest:Python的单元测试框架模块,在此框架下编写具体的业务测试用例脚本,另外此框架能组织测试用例集的执行和测试场景恢复

标准库 time 模块主要提供对时间的相关操作, os.path 模块主要提供对文件路径相关的操作,logging模块主要提供对日志相关的设置 ,smtplib 模块主要负责发送邮件等

第三方模块库:HTMLTestRunner 模块主要用于生成HTML格式的可视化测试报告,xlrd模块是读取excel文件数据的模块,xlwt模块是向excel文件中写入数据的模块



四、元素定位

在测试时,浏览器 点击F12打开控制台, 即可以看到页面的所有按钮、输入框等id属性;激活元素选择器;点击对应的按钮、输入框,就可以在控制台看到对应信息;根据id属性定位元素;调用driver提供给的方法定位。

id定位:driver.find_element_by_id('id')

#打开百度,输入软件测试,点击百度一下

driver.find_element_by_id('kw').send_keys('软件测试')

driver.find_element_by_id('su').click()

name定位:el=driver.find_element_by_name('name')

#输入selenium 自动化,点击百度一下

driver.find_element_by_name('wd').send_keys('selenium自动化')

#百度一下按钮没提供名字

driver.find_element_by_id('su').click()

class定位:el=driver.find_element_by_class_name('bt_class')

tagName定位:el=driver.find_element_by_tag_name(tagName)

xpath定位(绝对路径定位):el=driver.find_element_by_xpath(xpath)

css定位:el=driver.find_element_by_css_selector(css)

link_text 定位(根据它的超链接定位):el=driver.find_element_by_link_text(linkText)

partial_link_text定位():el=driver.find_element_by_partial_link_text(linkPartText)

获取当前 页面的url:driver.current_url

获取元素的文本值:driver.find_element_by_id("iptUsername").text

浏览器窗口最大化:driver.maximize_window()

查看浏览器名字:driver.name

打开网页:driver.get("www.baidu.com")

打开浏览器:driver=webdriver.Chrome()

关闭窗口:driver.close()


五、元素操作

元素赋值: el=driver.find_element_by_id("iptUsername").send_keys('admin')

清空元素值 el.clear()

获取元素文本: el.text

获取元素指定属性的值: get_attribute(obj)

上传文件:找到 type=file 的按钮,点击按钮,然后把按钮的文字改为图片名;

driver.find_element_by_css_selector('[type="file"]').click();

driver.find_element_by_css_selector('[type="file"]').send_keys('helloword.jpg');


六、执行JavaScript操作

当webdriver 遇到无法完成的操作时,可以使用javascript来完成,webdriver提供了execute_script()接口来调用js代码。 方法:execute_script(script, *args);执行 JavaScript代码是一个非常强大的功能,可以实现WebElement 接口所有功能,甚至更多的功能。比如在web性能测试中可以调用Web API接口window.performance来测试Web性能。


#打开百度页面,把百度一下 改成 test

driver.get("http://www.baidu.com")

driver.execute_script('document.getElementById("su").value="test"')


七、窗口切换

浏览器窗口切换:

例如浏览器打开多个窗口,需要从一个窗口跳转到另一个窗口做自动化测试。要转到另一个页面才能找到元素。原理是:每个打开的窗口都有唯一的标识,叫做句柄;可以通过不同的句柄实现窗口切换。

# 当前窗口url地址:

print(driver.current_url)


#暂停一会,10 秒

time.sleep(10)


# 打印所有窗口句柄

windows=driver.window_handles

print(windows,'\n')



#切换到最后的窗口

driver.switch_to.window(windows[-1])

#打印url,核对下是不是最后的窗口;或者根据网页名等校验

print(driver.current_url)


print('\n\n')

time.sleep(3)


#切换到第二个窗口

#先获取现在的窗口

current_window=driver.current_window_handle


# 获取第二个窗口的索引(由当前窗口索引+1)

next_window_index=windows.index(current_window) + 1


# 切换到第二个窗口

driver.switch_to.window(windows[next_window_index])

print(driver.current_url)

iframe切换:

如果元素包含在iframe中,也会导致无法找到元素!例如代码:也会找不到id为kw的input输入框;使用 driver.find_element_by_id('kw') 跑出无法找到的异常。


<iframe src="frame.html" id="myframe" name="myframe">

<input id="kw" / >

</iframe>

selenium提供了switch_to.frame()方法用于实现frame的切换,此方法接收id、name、index以及selenium的WebElement对象用来实现切换,比如上述的代码中,要切换到iframe中,则可以使用以下代码实现:

from selenium import webdriver


driver=webdriver.Chrome()

# 通过id切换iframe

driver.switch_to.frame('myframe')

# 通过name切换iframe

# driver.switch_to.frame('myframe')

# 通过index切换iframe,0代表第一个

# driver.switch_to.frame(0)

# 通过WebElement对象切换iframe

# driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))

当操作完frame中的元素后,经常需要重新切换到主界面进行其他操作,切换回主页面使用方法如下:

driver.switch_to.default_content()

若是frame里嵌套frame,这需要一层层切换下去。有多层frame,需要回到上一级的;用父frame:

driver.switch_to.parent_frame()

alert弹窗切换:

alert窗口是js提示框,不属于web界面,

#切换到alert窗口 ;获取alert 窗口

alert=driver.switch_to_alert

#获取alert的文本内容

print(alert.text)

#点击确定,关闭弹框

alert.accept()

#点击取消,关闭弹簧

alert.dismiss()

八、鼠标经过操作

selenium鼠标事件(单击/双击/右击/拖动)详细解说,selenium鼠标事件用的是ActionChains。需要import相关模块。

from selenium.webdriver.common.action_chains import ActionChains

如找到百度一下按钮,移到该位置;

from selenium.webdriver.common.action_chains import ActionChains

from selenium import webdriver


chr_driver=webdriver.Chrome()

chr_driver.maximize_window()

chr_driver.get("https://www.baidu.com/")


ele=chr_driver.find_element_by_id('su')

# 实例化,悬浮、点击,可以连续调用多个方法,是因为返回的都是self对象

ActionChains(chr_driver).move_to_element(ele).pause(0.5).click(ele).perform()

ActionChains的常用方法:

#单击鼠标左键

click(on_element=None)

#点击鼠标左键,不松开

click_and_hold(on_element=None)

#点击鼠标右键

context_click(on_element=None)

#双击鼠标左键

double_click(on_element=None)

#拖拽到某个元素然后松开

drag_and_drop(source, target)

#拖拽到某个坐标然后松开

drag_and_drop_by_offset(source, xoffset, yoffset)

#按下某个键盘上的键

key_down(value, element=None)

#松开某个键

key_up(value, element=None)

#鼠标移动到某个元素,悬浮

move_to_element(to_element)

#执行链中的所有动作

perform()

九、拖拽

如:打开百度地图拖拽、验证码验证的拖拽动作

from selenium.webdriver.common.action_chains import ActionChains


#打开浏览器

driver=webdriver.Chrome()

#浏览器最大化

driver.maximize_window()

#打开百度地图

driver.get('https://map.baidu.com/@12697919.69,2560977.31,12z')


#定位地图

mask=driver.find_element_by_id('mask')


#动作

ac=ActionChains(driver)

ac.move_to_element(mask).click_and_hold().move_by_offset(50,50).release().perform()


十、页面等待

强制等待 :time.sleep()

隐式等待:driver.implicitly_wait(t) ,隐式等待在指定的时间 t 内等待页面加载完成,如果加载完成的时间小于 t ,剩余的时间就不再等;如果时间 t 内未加载完成则报错。作用范围:全局

显式等待:WebDriverWait(driver , timeout , poll_frequency).until(element)

导入:from selenium.webdriver.support.ui import WebDriverWait

显式等待可以看做是特殊的隐式等待,在指定的时间 t 内等待指定元素加载完成,如果加载完成时间小于 t ,剩余的时间就不再等待,如果没能在 t 时间内加载完成则报错。

方法:WebDriverWait(driver , timeout , poll_frequency)

driver:表示浏览器对象,timeout:表示超时时间,poll_frequency:扫描间隔时间一般0.5秒,扫描一次页面。

element: 指定加载的元素


十一、截图

driver.save_screeshot(file) :file ,图片在本地保存的路径及名字;

如: driver.save_screeshot('./首页.jpg')

driver.get_screenshot_as_file(file)

使用场景:通常是断言失败,有错误的时候保存截图,方便还原现场。


十二、调用js代码

excute_script(js)

如:为只读元素设定值;设定日期;

js='document.getElementById("date").value=2022-05-27'

driver.execute_script(js)


十三、警告框处理

警告框的三种类型:

alert:只有确定按钮;

confirm:有确定和取消按钮

prompt:可以输入内容;

方法:

swtch_to.alert.text:获取警告框中的文本信息

swtch_to.alert.accept():在警告框中点击确定

swtch_to.alert.dismiss():在警告框中点击取消

swtch_to.alert.send_keys(value):在警告框中输入内容


#打印警告框中的文本信息

print(swtch_to.alert.text)

#在警告框中点击确定

driver.swtch_to.alert.accept()

#在警告框中点击取消

driver.swtch_to.alert.dismiss()

#在警告框中输入内容 100块

driver.swtch_to.alert.send_keys('100块')


十四、下拉框

导入模块:from selenium.webdriver.support.select import select

假设下拉框为 s ;选择下拉框中的选项 Select(s).方法()

方法:

options :返回下拉框中的所有选项

select_by_index():通过索引选择

select_by_value():通过选项的value属性值选择

select_by_visible_text():通过选项的文本值选择


#定位下拉框,内容是省份

s=driver.find_element_by_id('province')

#获取下拉框里的所有选项内容

opt=Select(s).options

#通过索引选择;若是通过value选择,则html代码要写有value属性

Select(s).select_by_index(-1)



十五、ActionChains 动作链

ActionChains 可以帮助模拟鼠标操作;如单击、双击、点击鼠标右键、拖拽等等。使用actionchains对象方法,行为事件是存储在actionchains对象队列。当你使用perform(),事件按顺序执行。

调用方法有两种:

#链式写法

ActionChains(driver).click(click_btn).double_click(doubleclick_btn).perform()


#分步写法

ActionChains(driver).click(click_btn)

ActionChains.double_click(doubleclick_btn)

ActionChains.perform()

ActionChains常用方法:

click(on_element=None) ——单击鼠标左键


click_and_hold(on_element=None) ——点击鼠标左键,不松开


context_click(on_element=None) ——点击鼠标右键


double_click(on_element=None) ——双击鼠标左键


drag_and_drop(source, target) ——拖拽到某个元素然后松开


drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开


key_down(value, element=None) ——按下某个键盘上的键


key_up(value, element=None) ——松开某个键


move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标


move_to_element(to_element) ——鼠标移动到某个元素


move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置


perform() ——执行链中的所有动作


release(on_element=None) ——在某个元素位置松开鼠标左键


send_keys(*keys_to_send) ——发送某个键到当前焦点的元素


send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素



十六、table表格处理

table表格代码如下:

<table border="1">

<tr>

<td>row 1, cell 1</td>

<td>row 1, cell 2</td>

</tr>

<tr>

<td>row 2, cell 1</td>

<td>row 2, cell 2</td>

</tr>

</table>

获取表格里的内容,通过 table->tr->td 层层获取

#获取table

table=driver.find_elements_by_id('table')


#获取 tr

tr=table.find_elements_by_tag_name('tr')


#获取td

td=tr[1].find_elements_by_tag_name('td')


#输出内容

print(td[1].text)

十七、生产报告

连接数据库,把所有的测试用例运行结果输入数据库,然后读取数据库,生成测试报告;如:项目的总测试用例数、成功用例数、失败用例数、跳过数;每个模块的测试用例数、成功用例数、失败用例数、跳过数;