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>
窗口特性屬性:
第三個參數是一個逗號分隔的設置字符串,表示在新窗口中都顯示哪些特性;如果省略,則以默認的形式呈現;
字符串格式為:設置使用鍵值對,且全部使用逗號分隔,而且不能有空格;
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自動化測試主要應用在回歸測試、兼容性測試、冒煙測試等測試場景;適合的是需求穩定、項目周期長、測試腳本可以復用的項目。
瀏覽器:谷歌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');
當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)
使用場景:通常是斷言失敗,有錯誤的時候保存截圖,方便還原現場。
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對象隊列。當你使用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 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)
連接數據庫,把所有的測試用例運行結果輸入數據庫,然后讀取數據庫,生成測試報告;如:項目的總測試用例數、成功用例數、失敗用例數、跳過數;每個模塊的測試用例數、成功用例數、失敗用例數、跳過數;
*請認真填寫需求信息,我們會在24小時內與您取得聯系。