摘要:?
之前用Selenium做UI自動化測試從初學(xué)到熟練碰到過很多問題,這里就不一一細(xì)說了,所以把最基本的操作都寫在了一起,包括:控制瀏覽器,操作元素,鼠標(biāo)事件,鍵盤事件,設(shè)置元素等待,多表單/窗口切換,警告框處理,上傳文件,操作Cookie,調(diào)用JavaScript控制瀏覽器滾動條,窗口截圖。
時間緊急,沒有仔細(xì)整理,望讀者見諒~~
目錄
1.控制瀏覽器
1.1控制瀏覽器窗口大小
1.2控制瀏覽器后退和前進(jìn)
1.3模擬刷新瀏覽器
2.元素操作
2.1常用的元素操作
2.2WebElement?接口常用方法
3.鼠標(biāo)事件
4.鍵盤事件
5.設(shè)置元素等待
5.1顯式等待
5.2隱式等待
5.3sleep?休眠方法
6.多表單切換
7.多窗口切換
8.警告框處理
9.上傳文件
9.1send_keys?實現(xiàn)上傳
9.2AutoIt?實現(xiàn)上傳
10.操作cookie
11.調(diào)用JavaScript控制瀏覽器滾動條
12.窗口截圖
1?控制瀏覽器
Selenium?主要提供的是操作頁面上各種元素的方法,但它也提供了操作瀏覽器本身的方法,比如瀏覽器的大小以及瀏覽器后退、前進(jìn)按鈕等。
1.1控制瀏覽器窗口大小
在不同的瀏覽器大小下訪問測試站點,對測試頁面截圖并保存,然后觀察或使用圖像比對工具對被測頁面的前端樣式進(jìn)行評測。比如可以將瀏覽器設(shè)置成移動端大小(480x800),然后訪問移動站點,對其樣式進(jìn)行評估;WebDriver 提供了set_window_size() 方法來設(shè)置瀏覽器的大小。
?
例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://192.168.30.180/Uet-Platform/")
#參數(shù)數(shù)字為像素點
print "設(shè)置瀏覽器寬480、高800 顯示"
driver.set_window_size(480, 800)
driver.quit()
?
在PC 端運行執(zhí)行自動化測試腳本大多的情況下是希望瀏覽器在全屏幕模式下執(zhí)行,那么可以使用maximize_window()方法,其用法與set_window_size()相同,但它不需要傳參。
1.2控制瀏覽器后退和前進(jìn)
在使用瀏覽器瀏覽網(wǎng)頁的時候,瀏覽器提供了后退和前進(jìn)按鈕,可以方便的對瀏覽過的網(wǎng)頁之間切換,那么WebDriver 也提供了對應(yīng)的back()和forward()方法來模擬后退和前進(jìn)按鈕。下面通過例子來演示這兩個方法的使用。
例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
#訪問百度首頁
first_url= 'http://www.baidu.com'
print "now access %s" %(first_url)
driver.get(first_url)
#訪問新聞頁面
second_url='http://news.baidu.com'
print "now access %s" %(second_url)
driver.get(second_url)
?
#返回(后退)到百度首頁
print "back to %s "%(first_url)
driver.back()
#前進(jìn)到新聞頁
print "forward to %s"%(second_url)
driver.forward()
driver.quit()
輸出:
now access http://www.baidu.com
now access http://news.baidu.com
back to http://www.baidu.com
forward to http://news.baidu.com
1.3模擬刷新瀏覽器
有時候需要手動的刷新(F5)的刷新頁面
…
driver.refresh() #刷新當(dāng)前頁面
…
2元素操作
2.1常用的元素操作
1、clear() 清除文本,如果是一個文件輸入框
2、send_keys(*value) 在元素上模擬按鍵輸入
3、click() 單擊元素
例子:
#coding=utf-8
from selenium import webdriver
import unittest, time, re
?
driver = webdriver.Firefox()
driver.implicitly_wait(30)
base_url ="http://192.168.30.180/Uet-Platform/masterLogin.action" ?#30測試環(huán)境
driver.get(base_url)
driver.find_element_by_id("txtUserName").clear()
driver.find_element_by_id("txtUserName").send_keys("13554797004")
?
driver.find_element_by_id("txtPassword").clear()
driver.find_element_by_id("txtPassword").send_keys("123123")
driver.find_element_by_link_text(u"登錄").click()
driver.switch_to_frame("lj_left")
driver.find_element_by_xpath("http://div[@id='left']/table/tbody/tr[6]/td").click()
driver.find_element_by_link_text(u"用戶單位管理").click()
……
說明:
clear()方法用于清除文本輸入框中的內(nèi)容,例如登錄框內(nèi)一般默認(rèn)會有“賬號”“密碼”等提示信息用于引導(dǎo)用戶輸入正確的數(shù)據(jù),如果直接向輸入框中輸入數(shù)據(jù),可能會與輸入框中的提示信息拼接,本來用戶輸入為“username”,結(jié)果與提示信息拼接為“帳號username”,從而造成輸入信息的錯誤;這個時候
可以先使用clear()方法清除輸入框內(nèi)的提示信息再進(jìn)行輸入。
send_keys()方法模擬鍵盤輸入向輸入框里輸入內(nèi)容。如上面的例子中通過這個方法向用戶名和密碼框中輸入用戶名和密碼。
click()方法可以用來單擊一個按鈕,前提是它是可以被點擊元素,它與send_keys()方法是web 頁面操作中最常用到的兩個方法。其實click()方法不僅僅用于點擊一個按鈕,還可以單擊任何可以點擊文字/圖片連接、復(fù)選框、單選框、甚至是下拉框等。
2.2WebElement?接口常用方法
1、submit()
submit()方法用于提交表單,這里特別用于沒提交按鈕的情況,例如搜索框輸入關(guān)鍵字之后的“回車”操作,那么就可以通過submit()來提交搜索框的內(nèi)容。
例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
driver.find_element_by_id('query').send_keys('hello')
#提交輸入框的內(nèi)容
driver.find_element_by_id('query').submit()
driver.quit()
有些時候submit()可以與click()方法互換來使用,submit()同樣可以提交一個按鈕。
2、?size 返回元素的尺寸。
3、text 獲取元素的文本。
4、get_attribute(name) 獲得屬性值。
5、is_displayed() 設(shè)置該元素是否用戶可見。
例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#獲得輸入框的尺寸
size=driver.find_element_by_id('kw').size
print size
#返回百度頁面底部備案信息
text=driver.find_element_by_id("cp").text
?
print text
#返回元素的屬性值,可以是id、name、type 或元素?fù)碛械钠渌我鈱傩?/b>
attribute=driver.find_element_by_id("kw").get_attribute('type')
print attribute
#返回元素的結(jié)果是否可見,返回結(jié)果為True 或False
result=driver.find_element_by_id("kw").is_displayed()
print result
driver.quit()
運行結(jié)果:
{'width': 526, 'height': 22}
?2014 Baidu 使用百度前必讀京ICP 證030173 號
True
解析:
執(zhí)行上面的程序并獲得執(zhí)行結(jié)果:size 用于獲取百度輸入框的寬、高。text 用于獲得百度底部的備案信息。get_attribute()用于獲百度輸入的type 屬性的值。is_displayed()用于返回一個元素是否可見,如果可見返回True,否則返回False。
3鼠標(biāo)事件
在現(xiàn)在的web 產(chǎn)品中,隨著前端技術(shù)的發(fā)展,頁面越來越華麗,鼠標(biāo)的操作也不單單只有單擊,現(xiàn)在頁面中隨處可以看到需要右擊、雙擊、鼠標(biāo)懸停、甚至是鼠標(biāo)拖動等操作的功能設(shè)計。在WebDriver 中這些關(guān)于鼠標(biāo)操作的方法由ActionChains 類提供。
3.1ActionChains?類提供的鼠標(biāo)操作的常用方法
1、perform() 執(zhí)行所有ActionChains 中存儲的行為
2、context_click() 右擊
3、double_click() 雙擊
4、drag_and_drop() 拖動
5、move_to_element() 鼠標(biāo)懸停
例子1:鼠標(biāo)右擊操作
對于ActionChains 類下所提供的鼠標(biāo)方法與前面學(xué)過的click()方法有所不同,那么簡單context_click()右鍵點擊一個元素。
代碼實現(xiàn):
from selenium import webdriver
#引入ActionChains 類
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get("http://yunpan.#")
....
#定位到要右擊的元素
right_click =driver.find_element_by_id("xx")
#對定位到的元素執(zhí)行鼠標(biāo)右鍵操作
ActionChains(driver).context_click(right_click).perform()
....
說明:
from selenium.webdriver import ActionChains
對于ActionChains 類下面的方法,在使用之前需要先將模塊導(dǎo)入。
ActionChains(driver)
調(diào)用ActionChains()方法,在使用將瀏覽器驅(qū)動driver 作為參數(shù)傳入。
context_click(right_click)
context_click()方法用于模擬鼠標(biāo)右鍵事件,在調(diào)用時需要傳入右鍵的元素。
perform()
執(zhí)行所有ActionChains 中存儲的行為,可以理解成是對整個操作事件的提交動作。
例子2:鼠標(biāo)懸停
鼠標(biāo)懸停彈出下拉菜單也是一個非常見的一個功能設(shè)計
move_to_element()方法可以模擬鼠標(biāo)懸停的動作,其用法與context_click()相同。
代碼實現(xiàn):
……
from selenium import webdriver
#引入ActionChains 類
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
....
#定位到要懸停的元素
above =driver.find_element_by_id("xx")
#對定位到的元素執(zhí)行懸停操作
ActionChains(driver).move_to_element(above).perform()
....
例子3:鼠標(biāo)雙擊操作
double_click(on_element)方法用于模擬鼠標(biāo)雙擊操作,用法同上。
代碼實現(xiàn):
……
from selenium import webdriver
#引入ActionChains 類
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
....
#定位到要懸停的元素
double_click = driver.find_element_by_id("xx")
#對定位到的元素執(zhí)行雙擊操作
ActionChains(driver).double_click(double_click).perform()
....
例子4:鼠標(biāo)推放操作
drag_and_drop(source, target)在源元素上按下鼠標(biāo)左鍵,然后移動到目標(biāo)元素上釋放。
source: 鼠標(biāo)拖動的源元素。
target: 鼠標(biāo)釋放的目標(biāo)元素。
代碼實現(xiàn):
……
from selenium import webdriver
#引入ActionChains 類
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
....
#定位元素的源位置
element = driver.find_element_by_name("xxx")
#定位元素要移動到的目標(biāo)位置
target = driver.find_element_by_name("xxx")
#執(zhí)行元素的拖放操作
ActionChains(driver).drag_and_drop(element,target).perform()
....
4鍵盤事件
有時候我們在測試時需要使用Tab 鍵將焦點轉(zhuǎn)移到下一個元素,Keys()類提供鍵盤上幾乎所有按鍵的方法,前面了解到send_keys()方法可以模擬鍵盤輸入,除此之外它還可以模擬鍵盤上的一些組合鍵,例:Ctrl+A、Ctrl+C 等。
4.1鍵盤操作
from selenium.webdriver.common.keys import Keys
在使用鍵盤按鍵方法前需要先導(dǎo)入keys 類包。
下面經(jīng)常使用到的鍵盤操作:
send_keys(Keys.BACK_SPACE) 刪除鍵(BackSpace)
send_keys(Keys.SPACE) 空格鍵(Space)
send_keys(Keys.TAB) 制表鍵(Tab)
send_keys(Keys.ESCAPE) 回退鍵(Esc)
send_keys(Keys.ENTER) 回車鍵(Enter)
send_keys(Keys.CONTROL,'a') 全選(Ctrl+A)
send_keys(Keys.CONTROL,'c') 復(fù)制(Ctrl+C)
send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v') 粘貼(Ctrl+V)
send_keys(Keys.F1) 鍵盤F1
……
send_keys(Keys.F12) 鍵盤F12
例子:
……
#coding=utf-8
from selenium import webdriver
#引入Keys 模塊
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#輸入框輸入內(nèi)容
driver.find_element_by_id("kw").send_keys("seleniumm")
#刪除多輸入的一個m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
#輸入空格鍵+“教程”
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys(u"教程")
#ctrl+a 全選輸入框內(nèi)容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
#ctrl+x 剪切輸入框內(nèi)容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
#ctrl+v 粘貼內(nèi)容到輸入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')
#通過回車鍵盤來代替點擊操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
driver.quit()
5設(shè)置元素等待
如今大多數(shù)的web 應(yīng)用程序使用AJAX 技術(shù)。當(dāng)瀏覽器在加載頁面時,頁面內(nèi)的元素可能并不是同時被加載完成的, 這給元素的定位添加的困難。如果因為在加載某個元素時延遲而造成ElementNotVisibleException 的情況出現(xiàn),那么就會降低的自動化腳本的穩(wěn)定性。
WebDriver 提供了兩種類型的等待:顯式等待和隱式等待。
5.1顯式等待
顯式等待使WebdDriver 等待某個條件成立時繼續(xù)執(zhí)行,否則在達(dá)到最大時長時拋棄超時異常(TimeoutException)。
例子:
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
element = WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"kw")))
element.send_keys('selenium')
driver.quit()
WebDriverWait()
它是由webdirver 提供的等待方法。在設(shè)置時間內(nèi),默認(rèn)每隔一段時間檢測一次當(dāng)前頁面元素是否存
在,如果超過設(shè)置時間檢測不到則拋出異常。具體格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver - WebDriver 的驅(qū)動程序(Ie, Firefox,Chrome 等)
timeout - 最長超時時間,默認(rèn)以秒為單位
poll_frequency - 休眠時間的間隔(步長)時間,默認(rèn)為0.5 秒
ignored_exceptions - 超時后的異常信息,默認(rèn)情況下拋NoSuchElementException 異常。
until()
WebDriverWait()一般由until()(或until_not())方法配合使用,下面是until()和until_not()方法的說明。
until(method, message=’ ’)
調(diào)用該方法提供的驅(qū)動程序作為一個參數(shù),直到返回值為Ture。
until_not(method, message=’ ’)
調(diào)用該方法提供的驅(qū)動程序作為一個參數(shù),直到返回值為False。
Expected Conditions
在本例中,我們在使用expected_conditions 類時對其時行了重命名,通過as 關(guān)鍵字對其重命名為EC,
并調(diào)用presence_of_element_located()判斷元素是否存在。
expected_conditions 類提供一些預(yù)期條件的實現(xiàn)。
title_is 用于判斷標(biāo)題是否xx。
title_contains 用于判斷標(biāo)題是否包含xx 信息。
presence_of_element_located 元素是否存在。
visibility_of_element_located 元素是否可見。
visibility_of 是否可見
presence_of_all_elements_located 判斷一組元素的是否存在
text_to_be_present_in_element 判斷元素是否有xx 文本信息
text_to_be_present_in_element_value 判斷元素值是否有xx 文本信息
frame_to_be_available_and_switch_to_it 表單是否可用,并切換到該表單。
invisibility_of_element_located 判斷元素是否隱藏
element_to_be_clickable 判斷元素是否點擊,它處于可見和啟動狀態(tài)
staleness_of 等到一個元素不再是依附于DOM。
element_to_be_selected 被選中的元素。
element_located_to_be_selected 一個期望的元素位于被選中。
element_selection_state_to_be 一個期望檢查如果給定的元素被選中。
element_located_selection_state_to_be 期望找到一個元素并檢查是否選擇狀態(tài)
alert_is_present 預(yù)期一個警告信息
除了expected_conditions 所提供的預(yù)期方法,我們也可以使用前面學(xué)過的is_displayed()方法來判斷元素是否可。
例子:
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
input_ = driver.find_element_by_id("kw")
element = WebDriverWait(driver,5,0.5).until(
lambda driver : input_.is_displayed()
)
input_.send_keys('selenium')
driver.quit()
5.2隱式等待
隱式等待是通過一定的時長等待頁面所元素加載完成。哪果超出了設(shè)置的時長元素還沒有被加載測拋NoSuchElementException 異常。WebDriver 提供了implicitly_wait()方法來實現(xiàn)隱式等待,默認(rèn)設(shè)置為0。它的用法相對來說要簡單的多。
例子:
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
input_ = driver.find_element_by_id("kw22")
input_.send_keys('selenium')
driver.quit()
implicitly_wait()默認(rèn)參數(shù)的單位為秒,本例中設(shè)置等待時長為10 秒,首先這10 秒并非一個固定的等待時間,它并不影響腳本的執(zhí)行速度。其次,它并不真對頁面上的某一元素進(jìn)行等待,當(dāng)腳本執(zhí)行到某個元素定位時,如果元素可定位那么繼續(xù)執(zhí)行,如果元素定位不到,那么它將以輪詢的方式不斷的判斷元素
是否被定位到,假設(shè)在第6 秒鐘定位到元素則繼續(xù)執(zhí)行。直接超出設(shè)置時長(10 秒)還沒定位到元素則拋出異常。
在上面的例子中,顯然百度輸入框的定位id=kw22 是有誤的,那么在超出10 秒后將拋出異常。
5.3sleep?休眠方法
有時間我們希望腳本執(zhí)行到某一位置時做固定時間的休眠,尤其是在腳本調(diào)試的過程中。那么可以使用sleep()方法,需要說明的是sleep()由Python 的time 模塊提供。
例子:
#coding=utf-8
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
sleep(2)
driver.find_element_by_id("kw").send_keys("webdriver")
driver.find_element_by_id("su").click()
sleep(3)
driver.quit()
當(dāng)執(zhí)行到sleep()方法時會固定的休眠所設(shè)置的時長,然后再繼續(xù)執(zhí)行。sleep()方法默認(rèn)參數(shù)以秒為單位,如果設(shè)置時長小于1 秒,可以用小數(shù)點表示,如:sleep(0.5)
6多表單切換
在web 應(yīng)用中經(jīng)常會遇到frame 嵌套頁面的應(yīng)用,頁WebDriver 每次只能在一個頁面上識別元素,對于frame 嵌套內(nèi)的頁面上的元素,直接定位是定位是定位不到的。這個時候就需要通過switch_to_frame()方法將當(dāng)前定位的主體切換了frame 里。
例子:
#coding=utf-8
from selenium import webdriver
import time
import os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('frame.html')
driver.get(file_path)
#切換到iframe(id = "if")
driver.switch_to_frame("if")
#下面就可以正常的操作元素了
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
driver.quit()
switch_to_frame() 默認(rèn)可以直接取表單的id 或name 屬性進(jìn)行切換。
……
#id = "if"
driver.switch_to_frame("if")
#name = "nf"
driver.switch_to_frame("nf")
……
那么如果iframe 沒有可用的id 和name 可以通過下面的方式進(jìn)行定位:
……
#先通過xpth 定位到iframe
xf = driver.find_element_by_xpath('//*[@class="if"]')
#再將定位對象傳給switch_to_frame()方法
driver.switch_to_frame(xf)
……
driver.switch_to_default_content()
如果完成了在當(dāng)前表單上的操作可以通過switch_to_default_content()方法返回到上一層單。該方法不用指定某個表單的返回,默認(rèn)對應(yīng)與它最近的switch_to_frame()方法。
7多窗口切換
有時候需要在不同的窗口切換,從而操作不同的窗口上的元素,WebDriver 提供了switch_to_window()方法可以切換到任意的窗口。
圖?多窗口
這里以百度首頁與注冊頁為例,演示在不同窗口切換。

例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
#獲得百度搜索窗口句柄
sreach_windows= driver.current_window_handle
driver.find_element_by_link_text(u'登錄').click()
driver.find_element_by_link_text(u"立即注冊").click()
#獲得當(dāng)前所有打開的窗口的句柄
all_handles = driver.window_handles
?
#進(jìn)入注冊窗口
for handle in all_handles:
if handle != sreach_windows:
driver.switch_to_window(handle)
print 'now register window!'
driver.find_element_by_name("account").send_keys('username')
driver.find_element_by_name('password').send_keys('password')
#……
#進(jìn)入搜索窗口
for handle in all_handles:
if handle == sreach_windows:
driver.switch_to_window(handle)
print 'now sreach window!'
driver.find_element_by_id('TANGRAM__PSP_2__closeBtn').click()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(5)
driver.quit()
說明:
整個腳本的處理過程:首先打開百度首頁,通過current_window_handle 獲得當(dāng)前窗口的句柄,并給變量sreach_handle。接著打開登錄彈窗,在登錄窗口上點擊“立即注冊”從而打開新的注冊窗口。通過window_handles 獲得當(dāng)前打開的所窗口的句柄,賦值給變量all_handles。
第一個循環(huán)遍歷all_handles,如果handle 不等于sreach_handle,那么一定是注冊窗口,因為腳本執(zhí)行只打開的兩個窗口。所以,通過switch_to_window()切換到注冊頁進(jìn)行注冊操作。第二個循環(huán)類似,不過這一次判斷如果handle 等于sreach_handle,那么切換到百度搜索頁,關(guān)閉之前打開的登錄彈窗,然后時行搜索操作。
在本例中所有用到的新方法:
current_window_handle 獲得當(dāng)前窗口句柄
window_handles 返回的所有窗口的句柄到當(dāng)前會話
switch_to_window()
用于切換到相應(yīng)的窗口,與上一節(jié)的switch_to_frame() 是類似,前者用于不同窗口的切換,后者用于不同表單之間的切換。
8警告框處理
在WebDriver 中處理JavaScript 所生成的alert、confirm 以及prompt 是很簡單的。具體做法是使用switch_to_alert()方法定位到alert/confirm/prompt。然后使用text/accept/dismiss/send_keys 按需進(jìn)行操做。
1、text 返回alert/confirm/prompt 中的文字信息。
2、accept 點擊確認(rèn)按鈕。
3、dismiss 點擊取消按鈕,如果有的話。
4、send_keys 輸入值,這個alert\confirm 沒有對話框就不能用了,不然會報錯。

圖??百度搜索保存設(shè)置彈窗
如圖?百度搜索設(shè)置的彈出的彈窗是不能通過前端工具對其進(jìn)行定位的,這個時候就可以通過switch_to_alert()方法接受這個彈窗。
例子:
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get('http://www.baidu.com')
#鼠標(biāo)懸停相“設(shè)置”鏈接
link = driver.find_element_by_link_text(u'設(shè)置')
ActionChains(driver).move_to_element(link).perform()
#打開搜索設(shè)置
driver.find_element_by_class_name('setpref').cick()
#保存設(shè)置
driver.find_element_by_css_selector('#gxszButton > a.prefpanelgo').click()
#接收彈窗
driver.switch_to_alert().accept()
driver.quit()
9上傳文件
文件上傳操作也比較常見功能之一,上傳功能操作webdriver 并沒有提供對應(yīng)的方法,關(guān)鍵上傳文件的思路。
對web 頁面的上功能,點擊“上傳”按鈕需要打開本地的Window 窗口,從窗口選擇本地文件進(jìn)行上傳,那么WebDriver 對于Windows 的控件是無能為力的
對于web 頁面的上傳功能一般會有以下幾種方式。
普通上傳:普通的附件上傳都是將本地文件的路徑作為一個值放input 標(biāo)簽中,通過form 表單提交的時候?qū)⑦@個值提交給服務(wù)器。
插件上傳:一般是指基于Flash 與JavaScript 或Ajax 等技術(shù)所實現(xiàn)的上傳功能或插件。
9.1send_keys?實現(xiàn)上傳
對于通過input 標(biāo)簽實現(xiàn)的通過上傳,可以將其看作一個輸入框,通過send_keys()傳入本地文件路徑從而模擬上傳功能。
例子:
#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
?
#打開上傳功能頁面
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
#定位上傳按鈕,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
driver.quit()
通過這種方法上傳,就繞開了操作Windows 控件的步驟。如果能找上傳的input 標(biāo)簽,那么基本都可以通過send_keys()方法向其輸入一個文件地址來實現(xiàn)上傳。
9.2AutoIt?實現(xiàn)上傳
AutoIt 目前最新是v3 版本,這是一個使用類似BASIC 腳本語言的免費軟件,它設(shè)計用于WindowsGUI(圖形用戶界面)中進(jìn)行自動化操作。它利用模擬鍵盤按鍵,鼠標(biāo)移動和窗口/控件的組合來實現(xiàn)自動化任務(wù)。
官方網(wǎng)站:https://www.autoitscript.com/site/
從網(wǎng)站上下載AutoIt 并安裝,安裝完成在菜單中會看到圖的目錄:

圖??AutoIt 菜單
AutoIt Windows Info 用于幫助我們識Windows 控件信息。
Compile Script to.exe 用于將AutoIt 生成exe 執(zhí)行文件。
Run Script 用于執(zhí)行AutoIt 腳本。
SciTE Script Editor 用于編寫AutoIt 腳本。
下面以操作upload.html 上傳彈出的窗口為例講解AutoIt 實現(xiàn)上傳過程。
1、首先打開AutoIt Windows Info 工具,鼠標(biāo)點擊Finder Tool,鼠標(biāo)將變成一個小風(fēng)扇形狀的圖標(biāo),按住鼠標(biāo)左鍵拖動到需要識別的控件上。

圖?AutoIt Windows Info 識別“文件名”輸入框控件

圖?AutoIt Windows Info 識別“打開”按鈕控件
如圖,通過AutoIt Windows Info 獲得以下信息。
窗口的title 為“選擇要加載的文件”,標(biāo)題的Class 為“#32770”。
文件名輸入框的class 為“Edit”,Instance 為“1” ,所以ClassnameNN 為“Edit1”。
打開按鈕的class 為“Button”,Instance 為“1” ,所以ClassnameNN 為“Button1”。
2、根據(jù)AutoIt Windows Info 所識別到的控件信息打開SciTE Script Editor 編輯器,編寫腳本。
;ControlFocus("title","text",controlID) Edit1=Edit instance 1
ControlFocus("選擇要加載的文件", "","Edit1")
; Wait 10 seconds for the Upload window to appear
WinWait("[CLASS:#32770]","",10)
; Set the File name text on the Edit field
ControlSetText("選擇要加載的文件", "", "Edit1", "D:\\upload_file.txt")
Sleep(2000)
; Click on the Open button
ControlClick("選擇要加載的文件", "","Button1");
說明:
ControlFocus()方法用于識別Window 窗口。WinWait()設(shè)置10 秒鐘用于等待窗口的顯示,其用法與WebDriver 所提供的implicitly_wait()類似。ControlSetText()用于向“文件名”輸入框內(nèi)輸入本地文件的路徑。這里的Sleep()方法與Python 中time 模塊提供的Sleep()方法用法一樣,不過它是以毫秒為單位,Sleep(2000)表示固定休眠2000 毫秒。ControlClick()用于點擊上傳窗口中的“打開”按鈕。
AutoIt 的腳本已經(jīng)寫好了,可以通過菜單欄“Tools”-->“Go” (或按鍵盤F5)來運行一個腳本吧!
注意在運行時上傳窗口當(dāng)前處于打開狀態(tài)。
3、腳本運行正常,將其保存為upfile.au3,這里保存的腳本可以通過Run Script 工具將其打開運行,
但我們的目的是希望這個腳本被Python 程序調(diào)用,那么就需要將其生成exe 程序。打開Compile Script to.exe
工具,將其生成為exe 可執(zhí)行文件。如下圖

圖??Compile Script to.exe 生成exe 程序
點擊“Browse”選擇upfile.au3 文件,點擊“Convert”按鈕將其生成為upfile.exe 程序。
4、下面就是通過自動化測試腳本調(diào)用upfile.exe 程序?qū)崿F(xiàn)上傳了。
例子:
#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
#打開上傳功能頁面
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
#點擊打開上傳窗口
driver.find_element_by_name("file").click()
#調(diào)用upfile.exe 上傳程序
os.system("D:\\upfile.exe")
driver.quit()
通過Python 的os 模塊的system()方法可以調(diào)用exe 程序并執(zhí)行。
10操作cookie
有時候我們需要驗證瀏覽器中是否存在某個cookie,因為基于真實的cookie 的測試是無法通過白盒和集成測試完成的。WebDriver 提供了操作Cookie 的相關(guān)方法可以讀取、添加和刪除cookie 信息。
10.1操作cookie方法
webdriver 操作cookie 的方法有:
1、get_cookies() 獲得所有cookie 信息
2、get_cookie(name) 返回有特定name 值有cookie 信息
3、add_cookie(cookie_dict) 添加cookie,必須有name 和value 值
4、delete_cookie(name) 刪除特定(部分)的cookie 信息
5、delete_all_cookies() 刪除所有cookie 信息
下面通過get_cookies()來獲取當(dāng)前瀏覽器的cookie 信息。
程序?qū)崿F(xiàn):
#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("http://www.youdao.com")
# 獲得cookie 信息
cookie= driver.get_cookies()
#將獲得cookie 的信息打印
print cookie
driver.quit()
執(zhí)行結(jié)果:
>>> ============= RESTART ===============
>>>
[{u'domain': u'.youdao.com',
u'secure': False,
u'value': u'aGFzbG9nZ2VkPXRydWU=',
u'expiry': 1408430390.991375,
u'path': u'/',
u'name': u'_PREF_ANONYUSER__MYTH'},
{u'domain': u'.youdao.com',
u'secure': False,
u'value': u'1777851312@218.17.158.115',
u'expiry': 2322974390.991376,
u'path': u'/', u'name':
u'OUTFOX_SEARCH_USER_ID'},
{u'path': u'/',
u'domain': u'www.youdao.com',
u'name': u'JSESSIONID',
u'value': u'abcUX9zdw0minadIhtvcu',
u'secure': False}]
通過打印結(jié)果可以看出,cookie 是以字典的形式進(jìn)行存放的,知道了cookie 的存放形式,那么我們就可以按照這種形式向瀏覽器中寫入cookie 信息。
例子:
#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
?
#向cookie 的name 和value 添加會話信息。
driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbbbb'})
#遍歷cookies 中的name 和value 信息打印,當(dāng)然還有上面添加的信息
for cookie in driver.get_cookies():
print "%s -> %s" % (cookie['name'], cookie['value'])
driver.quit()
執(zhí)行結(jié)果:
>>> ======================= RESTART ======================
>>>
YOUDAO_MOBILE_ACCESS_TYPE -> 1
_PREF_ANONYUSER__MYTH -> aGFzbG9nZ2VkPXRydWU=
OUTFOX_SEARCH_USER_ID -> -1046383847@218.17.158.115
JSESSIONID -> abc7qSE_SBGsVgnVLBvcu
key-aaaaaaa -> value-bbbbbb
從打印結(jié)果可以看到最后一條cookie 信息是在腳本執(zhí)行過程中通add_cookie()方法添加的。通過遍歷得到的所cookie 信息從而找到key 為“name”和“value”的特定cookie 的value。
那么在什么情況下會用到cookie 的操作呢?例如開發(fā)人員開發(fā)一個功能,當(dāng)用戶登錄后,會將用戶的用戶名寫入瀏覽器cookie,指定的key 為“username”,那么我們就可以通過get_cookies() 找到useranme,打印vlaue,如果找不到username 或?qū)?yīng)的value 為空,那么說明保存瀏覽器的cookie 是有問題的。
delete_cookie() 和delete_all_cookies() 的使用也很簡單,前者通過name 值到一個特定的cookie 將其刪除,后者直接刪除瀏覽器中的所有cookies()信息。
11調(diào)用JavaScript控制瀏覽器滾動條
WebDiver 不能操作本地Windows 控件,但對于瀏覽器上的控件也不是都可以操作的。比哪瀏覽器上的滾動條,雖然WebDriver 提供操作瀏覽器的前進(jìn)和后退按鈕,但對于滾動條并沒有提供相應(yīng)用的方法。那么在這種情況下就可以借助JavaScript 方法來控制瀏覽器滾動條。WebDriver 提供了execute_script()方法來執(zhí)行JavaScript 代碼。
一般用到操作滾動條的會兩個場景:
(1)注冊時的法律條文的閱讀,判斷用戶是否閱讀完成的標(biāo)準(zhǔn)是:滾動條是否拉到最下方。
(2)要操作的頁面元素不在視覺范圍,無法進(jìn)行操作,需要拖動滾動條。
用于標(biāo)識滾動條位置的代碼
例子:
……
……
?
document.body.scrollTop
網(wǎng)頁被卷去的高。scrollTop 設(shè)置或獲取滾動條與最頂端之間的距離。如果想讓滾動條處于頂部,那么可以設(shè)置scrollTop 的值為0,如果想讓滾動條處于最底端,可以將這個值設(shè)置的足夠大,大個窗口的高度即可。scrollTop 的值以像素為單位。
例子:
#coding=utf-8
from selenium import webdriver
import time
#訪問百度
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
#搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
#將頁面滾動條拖到底部
js="document.documentElement.scrollTop=10000"
driver.execute_script(js)
time.sleep(3)
#將滾動條移動到頁面的頂部
js_="document.documentElement.scrollTop=0"
driver.execute_script(js_)
time.sleep(3)
driver.quit()
通過瀏覽器打開百度進(jìn)行搜索,搜索的一屏無法完全顯示將會出現(xiàn)滾動條。這個時候就可以通過JavaScript 代碼控制滾動條在任意位置,需要改變的就是scrollTop 的值。通過execute_script()方法來執(zhí)行這段JavaScript 代碼。

有時候滾動條不僅上下有,如上圖,其它左右也有,那么可以通過下面JavaScript 代碼來實現(xiàn)上下與左右滾動條的任意推動。
例子:
……
#window.scrollTo(左邊距,上邊距);
window.scrollTo(0,450);
……
js=" window.scrollTo(200,1000);"
driver.execute_script(js)
用法與同上,通過execute_script()調(diào)用此代碼,修改scrollTo()的參數(shù)即可。
當(dāng)然,JavaScript 的作用不僅于此,它同樣可操作頁面上的元素或讓,或讓這個元素隱藏。
12窗口截圖
自動化腳本是交給工具去執(zhí)行,有時候打印的錯誤信息并不十分明確,如果在腳本執(zhí)行出錯的時候?qū)Ξ?dāng)前窗口截圖保存,那么通過圖片信息會更只觀幫助我們找到腳本出錯的原因。Webdriver 提供了截圖函數(shù)get_screenshot_as_file()來截取當(dāng)前窗口。
例子:
#coding=utf-8
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
try:
driver.find_element_by_id('kw_error').send_key('selenium')
driver.find_element_by_id('su').click()
except :
driver.get_screenshot_as_file("D:\\baidu_error.jpg")
driver.quit()
在本例中用到了Python 的異常處理,要本例中百度輸入框的id=kw_error 會定位不到元素,那么try就會捕捉到這個異常,從而執(zhí)行except,在except 中執(zhí)行g(shù)et_screenshot_as_file()對當(dāng)前窗口進(jìn)行截圖,這里需要指定圖片的保存路徑及文件名,并且關(guān)閉當(dāng)前驅(qū)動。
腳本運行完成打開D 盤就可以找到baidu_error.jpg 圖片文件了。