Selenium 系列篇(三):窗口篇
點(diǎn)擊上方“AirPython”,選擇“加為星標(biāo)”
第一時(shí)間關(guān)注 Python 技術(shù)干貨!

1. 窗口操作
Selenium 自動(dòng)化過程中,對(duì)窗口本身的操作包含:打開一個(gè)窗口、關(guān)閉一個(gè)窗口、刷新一個(gè)窗口、窗口的回退和前進(jìn)。
其中,打開一個(gè)窗口只需要使用?driver.get( url)?方法,傳入一個(gè)網(wǎng)頁地址,即可以驅(qū)動(dòng)瀏覽器打開目標(biāo)網(wǎng)址。
#?打開一個(gè)窗口網(wǎng)站
driver.get("http://www.baidu.com")在多窗口頁面切換時(shí),WebDriver 提供了 API ,包含:back()、forward()、refresh() 方便我們對(duì)瀏覽器執(zhí)行?回退、前進(jìn)、刷新頁面?的操作。
#?打開一個(gè)窗口網(wǎng)站
driver.get("http://www.baidu.com")
#?打開第二個(gè)網(wǎng)站
driver.get("http://www.google.com")
#?回退到第一個(gè)窗口網(wǎng)站
driver.back()
#?前進(jìn)到第二個(gè)窗口網(wǎng)站
driver.forward()
#?刷新當(dāng)前頁面
driver.refresh()
默認(rèn)窗體是全屏顯示,也可以?顯式指定窗口展示的寬和高。
#?設(shè)定窗口的寬為1000,高為800
driver.set_window_size(1000,?800)
為了測(cè)試報(bào)告更直觀,往往需要截圖附件,Selenium 可以隨時(shí)對(duì)某一個(gè)窗口頁面進(jìn)行?截圖。
#?保存當(dāng)前頁面為圖片
driver.save_screenshot('./temp.png')
自動(dòng)化完成之后,我們一般需要?關(guān)閉窗口,使用?close()?可以關(guān)閉當(dāng)前窗口,quit()?退出驅(qū)動(dòng)程序,關(guān)閉所有頁面。
#?關(guān)閉當(dāng)前窗口頁面
driver.close()
#?關(guān)閉所有窗口頁面
driver.quit()?2. 內(nèi)部元素操作
窗口內(nèi)部元素使用最多的操作包含:點(diǎn)擊按鈕、輸入框的清空和設(shè)置內(nèi)容。
#?點(diǎn)擊某個(gè)按鈕
driver.find_element_by_id("element_btn").click()
#?清空輸入框
driver.find_element_by_id("element_edit").clear()
#?輸入框內(nèi)設(shè)置內(nèi)容
driver.find_element_by_id("element_edit").send_keys("Python自動(dòng)化測(cè)試社區(qū)")
獲取到一個(gè)元素之后,就能拿到?元素的內(nèi)容?和?全部屬性。
#?首先查找到網(wǎng)頁元素
norm_element?=?driver.find_element_by_id("element_norm")
#?獲取元素的尺寸大小
print(norm_element.size)
#?獲取元素的所有屬性,比如:type屬性
print(norm_element.get_attribute("type"))3. 等待操作
自動(dòng)化打開一個(gè)網(wǎng)頁的時(shí)候,內(nèi)部網(wǎng)頁元素加載完全有一點(diǎn)的延遲性,因此在做 Web 端的自動(dòng)化測(cè)試的時(shí)候,一般都需要在測(cè)試 case 時(shí)加入一些等待操作。
常用等待操作有 3 種,分別是:sleep、隱式等待、顯示等待
其中,sleep(timeout)?是設(shè)定一個(gè)固定的等待時(shí)長(zhǎng),強(qiáng)行進(jìn)行等待,使用方便的同時(shí),效率最低,不建議使用。
#?強(qiáng)行等待?10s
sleep(10)隱式等待?也是設(shè)定一個(gè)固定的等待時(shí)間,對(duì)整個(gè)生命周期的元素都起作用,每一個(gè)元素都會(huì)等待加載完全,直到超過設(shè)定的等待時(shí)間。
#?隱式等待設(shè)定時(shí)長(zhǎng)為5s
driver.implicitly_wait(5)
driver.get('http://www.google.com')
#?隱式等待所有元素加載完成,直到超過設(shè)定的最長(zhǎng)時(shí)間
driver.find_element_by_id("element_id").click()顯示等待?相比隱式等待更靈活,是先設(shè)定一個(gè)條件函數(shù)和一個(gè)最長(zhǎng)等待時(shí)長(zhǎng),輪詢判斷條件函數(shù)的返回值,如果返回 True,則開始執(zhí)行后面的操作,否則會(huì)一直等待,直到超時(shí)報(bào)元素未找到異常。
Selenium 中使用?expected_conditions?指定了很多條件函數(shù)(也可以自定義條件函數(shù)),具體可以參考官網(wǎng)。
#?使用方式
#?指定超時(shí)時(shí)間和條件函數(shù)
WebDriverWait(driver,timeout).until(method)比如:下面就是輪詢等待 10s,直到頁面元素可見。
#?顯示等待?10s,直到元素出現(xiàn)
element?=?WebDriverWait(driver,?10).until(
????EC.visibility_of_element_located((By.ID,?"element_id"))
)上面的 3 種等待,顯式等待和隱式等待使用更常見;隱式等待針對(duì)全局,可以動(dòng)態(tài)的設(shè)置等待時(shí)長(zhǎng);顯式等待最靈活,可以最大程度地提高測(cè)試用例的執(zhí)行效率。
4. 內(nèi)嵌頁面
有一些復(fù)雜的網(wǎng)頁會(huì)包含 iframe HTML 內(nèi)聯(lián)框架元素,WebDriver API 是沒法直接找到 iframe 表單內(nèi)嵌頁面的元素。
如果想定位到內(nèi)嵌頁面的元素,可以使用?switch_to_frame( frame_id/frame)?切換到對(duì)應(yīng)的 iframe ,然后再去查找內(nèi)部元素。
#?使用 iframe 的 id 或者 iframe 對(duì)象切換到 iframe
driver.switch_to.frame("frame_id")
driver.switch_to.frame(target_frame)
#?然后再查找 iframe 內(nèi)部元素
driver.find_element_by_name("pwd").send_keys("******")
操作完 iframe 之后,使用?switch_to.default_content()?切換到外層頁面,繼續(xù)后面的操作。
#?切換到外層頁面
driver.switch_to.default_content()
需要注意的是,針對(duì)多層 iframe 嵌套,需要一層一層地切換 iframe,操作完對(duì)應(yīng) iframe 內(nèi)部操作之后,返回到最外層頁面。
比如:iframeA- iframeB - iframeC,要查找 iframeC 內(nèi)部元素控件
#?切換到第一層
driver.switch_to.frame("iframeA")
#?切換到第二層
driver.switch_to.frame("iframeB")
切換到第三層
edriver.switch_to.frame("iframeC")
#?操作第三層元素
....
#?切換到最外層元素
driver.switch_to.default_content()
5. 窗口切換
有時(shí)候,點(diǎn)擊網(wǎng)頁內(nèi)部某個(gè)鏈接,會(huì)打開一個(gè)新的窗口,實(shí)際上,每一個(gè)窗口都有特定的窗口句柄:window_handle。
獲取當(dāng)前窗口頁面的窗口句柄:current_window_handle。
獲取所有窗口頁面的窗口句柄:window_handles,返回值是一個(gè)窗口句柄列表。
要操作某一個(gè)窗口內(nèi)的元素,首先要使用?switch_to_window()?切換到對(duì)應(yīng)的窗口,然后才能操作內(nèi)部元素。
#?獲取當(dāng)前窗口的句柄
window_handle_main?=?driver.current_window_handle
#?跳到其他窗口界面
...
#?獲取所有的窗口句柄
window_handles?=?driver.window_handles
#?其他窗口的句柄
window_handle_other?=?None
#?遍歷找到注冊(cè)窗口句柄
for?handle?in?window_handles:
????if?handle?!=?window_handle_main:
????????#?其他窗口句柄
????????window_handle_other?=?handle
????????#?切換到第二個(gè)窗口內(nèi)
????????driver.switch_to.window(window_handle_other)
????????#?第二個(gè)窗口內(nèi)部操作
????????......
????????#?關(guān)閉當(dāng)前窗口,即第二個(gè)窗口頁面
????????driver.close()
#?切換到主窗口
driver.switch_to.window(window_handle_main)6. 特殊元素
針對(duì)網(wǎng)頁中的一些特殊網(wǎng)頁元素,比如:JS 警告對(duì)話框、下拉選項(xiàng),Selenium 都提供了對(duì)應(yīng)的 API,方便我們快速地進(jìn)行處理。
警告對(duì)話框?會(huì)在窗口上浮動(dòng)彈出一個(gè)警告對(duì)話框,WebDriver 使用?switch_to.alert()?切換到對(duì)話框本身,然后就能操作對(duì)話框了。
常見操作包含:獲取對(duì)話框文本內(nèi)容、同意對(duì)話框、關(guān)閉對(duì)話框,如果對(duì)話框內(nèi)存在輸入框的話,還可以使用 send_keys() 輸入內(nèi)容。
#?切換到對(duì)話框
dialog_alert?=?driver.switch_to.alert
#?獲取警告框的提示信息
acontent?=?dialog_alert.text
#?對(duì)話框的操作
#?操作包含?accept()、dismiss()、send_keys()
dialog_alert.accept()
下拉選項(xiàng) Select?也是比較常用的網(wǎng)頁元素,要模擬選擇某一項(xiàng)值,需要借助 WebDriver 提供的 Select 類。
Select?類可以通過?索引、文本內(nèi)容、value 屬性值?來模擬選擇下拉選項(xiàng)的某一項(xiàng)。
from?selenium.webdriver.support.select?import?Select
#?下拉選項(xiàng)元素
element_select?=?driver.find_element_by_xpath("http://select[@id='select_id']")
#?利用?Select?類進(jìn)行選擇
#?1、通過value來選擇
Select(element_select).select_by_value(element_value)
#?2、通過索引來選擇
#?Select(element_select).select_by_index(element_index)
#?3、通過內(nèi)容來選擇
Select(element_select).select_by_visible_text(element_text)

???
