關於selenium常用api的簡介與記錄

一、瀏覽器操作

1、瀏覽器最大化
driver.maximize_window() #將瀏覽器最大化顯示
2、設置瀏覽器寬、高
driver.set_window_size(480, 800)#設置瀏覽器寬480、高800顯示
3、控制瀏覽器前進、後退
driver.back()#瀏覽器後退
driver.forward()#瀏覽器前進

二、簡單對象的定位

webdriver 提供了一系列的元素定位方法,常用的有以下幾種:
  •  id
  •  name
  •  class name
  •  tag name
  •  link text
  •  partial link text
  •  xpath
  •  css selector
分別對應python webdriver 中的方法爲:
  • find_element_by_id()
  • find_element_by_name()
  • find_element_by_class_name()
  • find_element_by_tag_name()
  • find_element_by_link_text()
  • find_element_by_partial_link_text()
  • find_element_by_xpath()
  • find_element_by_css_selector()
 
1、id 和name 定位
id 和name 是我們最常用的定位方式,因爲大多數元素都有這兩個屬性,而且在對控件的id 和name
命名時一般使其有意義也會取不同的名字。通過這兩個屬性使我們找一個頁面上的屬性變得相當容易。
比如:
#id=”gs_htif0”
find_element_by_id("gs_htif0")
#name=”btnK”
find_element_by_name("btnK")
2、tag name 和class name 定位
比如:
#<div id="searchform" class="jhp_big" style="margin-top:-2px">
#<form id="tsf" οnsubmit="return name="f" method="GET" action="/search">
find_element_by_class_name("jhp_big")
find_element_by_tag_name("div")
tag name 定位應該是所有定位方式中最不靠譜的一種了,因爲在一個頁面中具有相同tag name 的元
素極其容易出現。
3、link text 與partial link text 定位
有時候需要操作的元素是一個文字鏈接,那麼我們可以通過link text 或partial link text 進行元素
定位。比如:
#<a href="http://news.baidu.com" name="tj_news">新聞</a>
#<a href="http://tieba.baidu.com" name="tj_tieba">貼吧</a>
#<a href="http://zhidao.baidu.com" name="tj_zhidao">一個很長的文字連接</a>

#通過link text 定位元素:
find_element_by_link_text("新聞")
find_element_by_link_text("貼吧")
find_element_by_link_text("一個很長的文字連接")

#通partial link text 也可以定位到上面幾個元素:
find_element_by_partial_link_text("")
find_element_by_partial_link_text("")
find_element_by_partial_link_text("一個很長的")
當一個文字連接很長時,我們可以只取其中的一部分,只要取的部分可以唯一標識元素。一般一個頁
面上不會出現相同的文件鏈接,通過文字鏈接來定位元素也是一種簡單有效的定位方式。
4、XPath 定位
XPath 是一種在XML 文檔中定位元素的語言。因爲HTML 可以看做XML 的一種實現,所以selenium 用
戶可是使用這種強大語言在web 應用中定位元素。
以下面一段html代碼爲例:
<html class="w3c">
<body>
<div class="page-wrap">
<div id="hd" name="q">
<form target="_self" action="http://www.so.com/s">
<span id="input-container">
<input id="input" type="text" x-webkit-speech="" autocomplete="off" suggestwidth="501px" >
(1)使用絕對路徑定位:
當我們所要定位的元素很難找到合適的方式時,都可以通這種絕對路徑的方式位,缺點是當元素在很
多級目錄下時,我們不得不要寫很長的路徑,而且這種方式難以閱讀和維護。
find_element_by_xpath("/html/body/div[2]/form/span/input")
(2)使用相對路徑定位:
find_element_by_xpath("//input[@id=’input’]") #通過自身的id 屬性定位
find_element_by_xpath("//span[@id=’input-container’]/input") #通過上一級目錄的id 屬性定位
find_element_by_xpath("//div[@id=’hd’]/form/span/input") #通過上三級目錄的id 屬性定位
find_element_by_xpath("//div[@name=’q’]/form/span/input")#通過上三級目錄的name 屬性定位
通過上面的例子,我們可以看到XPath 的定位方式非常靈活和強大的,XPath 可以做布爾邏輯運算,例如://div[@id=’hd’ or @name=’q’]。
當然,它的缺陷也非常明顯:
1、性能差,定位元素的性能要比其它大多數方式差;
2、不夠健壯,XPath會隨着頁面元素佈局的改變而改變;
3. 兼容性不好,在不同的瀏覽器下對XPath 的實現是不一樣的。
 

下面插播一下xpath的知識:

(1)路徑表達式:
表達式
描述
nodename
選取此節點的所有子節點。
/
從根節點選取。
//
從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。
.
選取當前節點。
..
選取當前節點的父節點。
@
選取屬性。
實例
在下面的表格中,我們已列出了一些路徑表達式以及表達式的結果:
路徑表達式
結果
bookstore
選取 bookstore 元素的所有子節點。
/bookstore
選取根元素 bookstore。
註釋:假如路徑起始於正斜槓( / ),則此路徑始終代表到某元素的絕對路徑!
bookstore/book
選取屬於 bookstore 的子元素的所有 book 元素。
//book
選取所有 book 子元素,而不管它們在文檔中的位置。
bookstore//book
選擇屬於 bookstore 元素的後代的所有 book 元素,而不管它們位於 bookstore 之下的什麼位置。
//@lang
選取名爲 lang 的所有屬性。
實例
在下面的表格中,我們列出了帶有謂語的一些路徑表達式,以及表達式的結果:
路徑表達式
結果
/bookstore/book[1]
選取屬於 bookstore 子元素的第一個 book 元素。
/bookstore/book[last()]
選取屬於 bookstore 子元素的最後一個 book 元素。
/bookstore/book[last()-1]
選取屬於 bookstore 子元素的倒數第二個 book 元素。
/bookstore/book[position()<3]
選取最前面的兩個屬於 bookstore 元素的子元素的 book 元素。
//title[@lang]
選取所有擁有名爲 lang 的屬性的 title 元素。
//title[@lang='eng']
選取所有 title 元素,且這些元素擁有值爲 eng 的 lang 屬性。
/bookstore/book[price>35.00]
選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大於 35.00。
/bookstore/book[price>35.00]/title
選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大於 35.00。
(2)選取未知節點
XPath 通配符可用來選取未知的 XML 元素。
通配符
描述
*
匹配任何元素節點。
@*
匹配任何屬性節點。
node()
匹配任何類型的節點。
實例
在下面的表格中,我們列出了一些路徑表達式,以及這些表達式的結果:
路徑表達式
結果
/bookstore/*
選取 bookstore 元素的所有子元素。
//*
選取文檔中的所有元素。
//title[@*]
選取所有帶有屬性的 title 元素。
 
5、CSS 定位
CSS(Cascading Style Sheets)是一種語言,它被用來描述HTML 和XML 文檔的表現。CSS 使用選擇器來爲頁面元素綁定屬性。這些選擇器可以被selenium 用作另外的定位策略。CSS 可以比較靈活選擇控件的任意屬性,一般情況下定位速度要比XPath 快,但對於初學者來說比較難以學習使用,下面我們就詳細的介紹CSS 的語法與使用:
例如下面一段代碼:
<div class="formdiv"><form name="fnfn"><input name="username" type="text"></input><input name="password" type="text"></input><input name="continue" type="button"></input><input name="cancel" type="button"></input><input value="SYS123456" name="vid" type="text"><input value="ks10cf6d6" name="cid" type="text"></form><div class="subdiv"><ul id="recordlist"><p>Heading</p><li>Cat</li><li>Dog</li><li>Car</li><li>Goat</li></ul></div></div>
通過CSS 語法進行匹配的實例:
關於自動化的定位問題:
自動化測試的元素定位一直是困擾自動化測試新手的一個障礙,因爲我們在自動化實施過程中會碰到
各式各樣的對象元素。雖然XPath 和CSS 可以定位到複雜且比較難定位的元素,但相比較用id 和name 來
說增加了維護成本和學習成本,相比較來說id/name 的定位方式更直觀和可維護,有新的成員加入的自動
化時也增加了人員的學習成本。所以,測試人員在實施自動化測試時一定要做好溝通,規範前端開發人員
對元素添加id/name 屬性,或者自己有修改HTML 代碼的權限。

三、操作測試對象

一般來說,所有有趣的操作與頁面交互都將通過WebElement 接口,包括上一節中介紹的對象定位,
以及本節中需要介紹的常對象操作。
webdriver 中比較常用的操作元素的方法有下面幾個:
  • clear 清除元素的內容,如果可以的話
  • send_keys 在元素上模擬按鍵輸入
  • click 單擊元素
  • submit 提交表單
例如:
driver.find_element_by_id("user_name").clear()
driver.find_element_by_id("user_name").send_keys("username")
driver.find_element_by_id("user_pwd").clear()
driver.find_element_by_id("user_pwd").send_keys("password")
driver.find_element_by_id("dl_an_submit").click()
#通過submit() 來提交操作
#driver.find_element_by_id("dl_an_submit").submit()
  • clear() 用於清除輸入框的默認內容
  • send_keys("xx") 用於在一個輸入框裏輸入xx 內容
  • click() 用於單擊一個按鈕、連接等
  • submit() 提交表單
1、WebElement 接口常用方法
WebElement 接口除了我們前面介紹的方法外,它還包含了別一些有用的方法。下面,我們例舉例幾
個比較有用的方法。
  • size #返回元素的尺寸
  • text #獲取元素的文本
  • get_attribute(name) #獲得屬性值
  • is_displayed() #檢查該元素是否用戶可見
例如:
size=driver.find_element_by_id("kw").size#返回百度輸入框的寬高
text=driver.find_element_by_id("cp").text #返回百度頁面底部備案信息
#返回元素的屬性值,可以是id、name、type 或元素擁有的其它任意屬性
attribute=driver.find_element_by_id("kw").get_attribute('type')
#返回元素的結果是否可見,返回結果爲True 或False
result=driver.find_element_by_id("kw").is_displayed()

四、鼠標事件

 
前面例子中我們已經學習到可以用 click()來模擬鼠標的單擊操作,而我們在實際的 web 產品測試中發現,有關鼠標的操作,不單單隻有單擊,有時候還要和到右擊,雙擊,拖動等操作,這些操作包含在ActionChains 類中。
ActionChains 類鼠標操作的常用方法:
  • context_click() 右擊
  • double_click() 雙擊
  • drag_and_drop() 拖動
  • move_to_element() 鼠標懸停在一個元素上
  • click_and_hold() 按下鼠標左鍵在一個元素上
1、右擊操作
#引入 ActionChains 類fromselenium.webdriver.common.action_chainsimport ActionChains
...
#定位到要右擊的元素
right =driver.find_element_by_xpath("xx")
#對定位到的元素執行鼠標右鍵操作
ActionChains(driver).context_click(right).perform()
ActionChains 用於生成用戶的行爲;所有的行爲都存儲在 actionchains 對象中。通過 perform()執行存儲的行爲。

2、鼠標雙擊操作
#引入 ActionChains 類fromselenium.webdriver.common.action_chainsimport ActionChains
...
#定位到要雙擊的元素
double =driver.find_element_by_xpath("xxx")
#對定位到的元素執行鼠標雙擊操作
ActionChains(driver).double_click(double).perform()
3、鼠標拖放操作
drag_and_drop(source, target)
在源元素上按下鼠標左鍵,然後移動到目標元素上釋放。
source: 鼠標按下的源元素。
target: 鼠標釋放的目標元素。
#引入 ActionChains 類fromselenium.webdriver.common.action_chainsimport ActionChains
...
#定位元素的原位置
element = driver.find_element_by_name("xxx")
#定位元素要移動到的目標位置
target = driver.find_element_by_name("xxx")
#執行元素的移動操作
ActionChains(driver).drag_and_drop(element, target).perform()
4、鼠標移動上元素上
#引入 ActionChains 類fromselenium.webdriver.common.action_chainsimport ActionChains
...
#定位到鼠標移動到上面的元素
above = driver.find_element_by_xpath("xxx")
#對定位到的元素執行鼠標移動到上面的操作
ActionChains(driver).move_to_element(above).perform()
5、按下鼠標左鍵
#引入 ActionChains 類fromselenium.webdriver.common.action_chainsimport ActionChains
...
#定位到鼠標按下左鍵的元素
left=driver.find_element_by_xpath("xxx")
#對定位到的元素執行鼠標左鍵按下的操作
ActionChains(driver).click_and_hold(left).perform()

五、鍵盤事件

from selenium.webdriver.common.keys import Keys #在使用鍵盤按鍵方法前需要先導入 keys 類包。

下面經常使用到的鍵盤操作:
  • 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') 複製(Ctrl+C)
  • send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
  • send_keys(Keys.CONTROL,'v') 粘貼(Ctrl+V)

六、獲取頁面的title和url

有時間需要通過頁面的title和url去判斷頁面的狀態。比如測試登錄是否成功和重定向是否成功。
#獲得前面 title,打印
title = driver.title
print title

#獲得前面 URL,打印
now_url = driver.current_url
print now_url

 七、設置等待時間

有時候爲了保證腳本運行的穩定性,需要腳本中添加等待時間。
設置等待時間有以下幾種方法:
  • sleep(): 設置固定休眠時間。 python 的 time 包提供了休眠方法 sleep() , 導入 time包後就可以使用 sleep()進行腳本的執行過程進行休眠。
  • implicitly_wait():是 webdirver 提供的一個超時等待。隱的等待一個元素被發現,或一個命令完成。如果超出了設置時間的則拋出異常。
  • WebDriverWait():同樣也是 webdirver 提供的方法。在設置時間內,默認每隔一段時間檢測一次當前頁面元素是否存在,如果超過設置時間檢測不到則拋出異常。
1、sleep()休眠方法
當執行到sleep()方法時會固定休眠一定的時長,然後再往下執行。sleep()方法以秒爲單位,假如休眠時間小於 1 秒,可以用小數表示。
import time
....
time.sleep(5)
time.sleep(0.5)
當然,也可以直接導入 sleep()方法,使腳本中的引用更簡單
from time import sleep
....
sleep(3)
sleep(30)
2、implicitly_wait()
隱式等待是通過一定的時長等待頁面上某元素加載完成。如果超出了設置的時長元素還沒被加載,則拋出NoSuchElementException異常。implicitly_wait()方法比 sleep() 更加智能,後者只能選擇一個固定的時間的等待,前者可以在一個時間範圍內智能的等待。以秒爲單位。注意:它並不針對頁面上的某一個元素進行等待,而是從你設定這個隱式等待開始的所有需要定位的元素。當腳本執行到某個元素定位時,如果元素可以定位,則繼續執行;如果元素定位不到,則它將以輪詢的方式不斷判斷元素是否定位到。超過設定時間拋出異常
 
#添加智能等待30秒
driver.implicitly_wait(30)
3、WebDriverWait()
詳細格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None),參數解釋如下:
  • driver - WebDriver 的驅動程序(Ie, Firefox, Chrome 或遠程)
  • timeout - 最長超時時間,默認以秒爲單位
  • poll_frequency - 休眠時間的間隔(步長)時間,默認爲 0.5 秒
  • ignored_exceptions - 超時後的異常信息,默認情況下拋 NoSuchElementException 異常。
from selenium.webdriver.support.ui import WebDriverWait
....
element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id(“someId”))

is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).until_not(lambda x: x.find_element_by_id(“someId”).is_displayed())
WebDriverWai()一般由 unit()或 until_not()方法配合使用,下面是 unit()和 until_not()方法的說明:
until(method, message=’’)
調用該方法提供的驅動程序作爲一個參數,直到返回值不爲False。
until_not(method, message=’’)
調用該方法提供的驅動程序作爲一個參數,直到返回值爲 False。

 八、定位一組對象

需要獲取頁面上的一組元素是的方法:
#find_elements 用於獲取一組元素。find_elements_by_id(‘xx’)
find_elements_by_name(‘xx’)
find_elements_by_class_name(‘xx’)
find_elements_by_tag_name(‘xx’)
find_elements_by_link_text(‘xx’)
find_elements_by_partial_link_text(‘xx’)
find_elements_by_xpath(‘xx’)
find_elements_by_css_selector(‘xx’)
 
 可以使用for... in ...對這一組元素進行遍歷
for checkbox in checkboxes:
checkbox.click()
我們獲取到一組元素之後也可以使用pop()方法獲得這一組元素中的第幾個,然後再對該元素進行操作:
find_elements_by_id(‘xx’).pop().click()
  • pop()或pop(-1)默認獲取一組元素中的最後一個
  • pop(0)   默認獲取一組元素的第一個元素
  • pop(1)   默認獲取一組元素的第二個元素
  • ......以此類推

九、層級定位

在實際的項目測試中,經常會有這樣的需求:頁面上有很多個屬性基本相同的元素 ,現在需要具體
定位到其中的一個。由於屬性基本相當,所以在定位的時候會有些麻煩,這時候就需要用到層級定位。先
定位父元素,然後再通過父元素定位子孫元素。
比如下拉列表,我們可以先點擊彈出下拉框然後再定位下拉列表中的選項
#點擊 Link1 鏈接(彈出下拉列表)
driver.find_element_by_link_text('Link1').click()
#在父親元件下找到 link 爲 Action 的子元素
menu =
driver.find_element_by_id('dropdown1').find_element_by_link_text('Another
action')

十、多表單切換

在 web 應用中經常會出現 frame/iframe 表單內嵌套的應用,WebDriver只能在一個頁面上進行元素識別定位,對於frame/iframe表單內嵌頁面上的元素無法直接定位。這是需要通過switch_to.frame()方法將當前定位的主體切換爲frame/iframe表單的內嵌頁面中。
driver.switch_to_frame("f2")
switch_to.frame()默認可以直接去表單的id或name屬性。如果沒有這兩個屬性,可以通過其他方式定位,比如:
#先通過xpath定位到iframe
xf=driver.find_element_by_xpath('/*[@class="if"]')
#再將定位對象傳給switch_to.frame()方法
driver.switch_to.frame()
如果完成了在當前表單上的操作,則可以通過switch_to.parent_content()方法跳出當前一集表單。該方法默認對應於離他最近的switch_to.frame()。如果要跳出最外層的頁面使用switch_to.default_conent().

十一、多窗口切換

1、相關方法
current_window_handle:獲得當前窗口句柄
window_handles:返回所有窗口的句柄到當前對話
switch_to.window(窗口句柄):切換到對應的窗口。
nowhandle=driver.current_window_handle
driver.find_element_by_link_text(u"發表話題").click()
time.sleep(3)
#由於發表新話題會新窗口打開,所以要指向新窗口,即發話題窗口
allhandles=driver.window_handles
for handle in allhandles:
if(handle!=nowhandle):
driver.switch_to.window(handle)

 十二、警告窗處理

處理javascript所生成的alert、confirm、prompt,可以使用switch_to_alert()方法定位到alert/confirm/prompt,然後使用text/accept/dismiss/send_keys等方法進行操作
  • text     返回 alert/confirm/prompt 中的文字信息。
  • accept      點擊確認按鈕。
  • dismiss     點擊取消按鈕,如果有的話。
  • send_keys     輸入值,這個 alert\confirm 沒有對話框就不能用了,不然會報錯。

十三、上傳文件

 1、查找到input標籤,通過send_keys添加文件路徑
#通過查找到input標籤,然後send進去
driver.find_element_by_id("coverImgSrc").send_keys(u"%s"%tds["coverImgSrc"])
2、使用AutoIt識別flash控件和windows控件實現自動上傳文件

十四、調用javascript

當 webdriver 遇到沒法完成的操作時,筆者可以考慮借用 JavaScript 來完成。使用webdriver 提供的execute_script() 接口用來調用 js 代碼。比如要操作頁面上隱藏的元素,可以用javascript來把它設置爲可見然後進行操作
比如下面這段代碼:
使用javascript:
……
#修改元素的屬性
js = 'document.querySelectorAll("select")[0].style.display="block";'
driver.execute_script(js)

sel = driver.find_element_by_tag_name('select')
Select(sel).select_by_value('opel')

……

十五、控制瀏覽器滾動條

一般用到操作滾動條的會兩個場景:
  • 註冊時的法律條文的閱讀,判斷用戶是否閱讀完成的標準是:滾動條是否拉到最下方。
  • 要操作的頁面元素不在視覺範圍,無法進行操作,需要拖動滾動條
用於標識滾動條位置的代碼:
<body οnlοad= "document.body.scrollTop=0 ">
<body οnlοad= "document.body.scrollTop=100000 ">
如果滾動條在最上方的話, scrollTop=0 , 那麼要想使用滾動條在最可下方, 可以 scrollTop=100000 ,
這樣就可以使滾動條在最下方。
#將頁面滾動條拖到底部
js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
time.sleep(3)
#將滾動條移動到頁面的頂部
js1="var q=document.documentElement.scrollTop=0"
driver.execute_script(js1)
time.sleep(3)

十六、獲取元素對象的屬性值

有時候我們定位頁面上的元素髮現常用的id、name等屬性是相同的。這個時候我們只能通過常規的定位方法定位出一組元素,然後觀察通過元素的屬性可以定位出單個元素。可使用.get_attribute()方法。
比如:
# 選擇頁面上所有的 tag name 爲 input 的元素
inputs = driver.find_elements_by_tag_name('input')
#然後循環遍歷出 屬性data-node值 爲594434493的元素,單擊勾選for input in inputs:
if input.get_attribute('data-node') == '594434493':
input.click()
……

 十七、獲取驗證碼問題

關於驗證碼的處理,網上有幾種說法:
1、測試時先去掉驗證碼
2、使用驗證碼識別技術
3、使用cookies記錄登錄用戶名密碼,下次自動登錄免去驗證碼輸入環節
我們自己內部的處理方式是內部提供一個接口獲得驗證碼,然後通過js代碼把獲取的驗證碼填寫進去:
#自動獲取驗證碼並填寫
js="$.getJSON('http://xxx.xxx.com/util/getCode.jsonp?callback=?',function(data){$('.imgcode').val(data.code);})"
driver.execute_script(js)
發佈了40 篇原創文章 · 獲贊 48 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章