WD.py是一個Python WebDriver客戶端,實現(xiàn)了WebDriver協(xié)議中的大部分API。 它最初是為Macaca(一個Node.js驅(qū)動的WebDriver服務器)而設(shè)計的,但也可以應用于WebDriver服務器的其他實現(xiàn),比如Selenium,Appium等。

查找元素
WebDriver的查找元素命令允許分別查找單個元素和元素集合,定位策略如下:
- 文本
- id
- XPath
- 鏈接文本
- 部分鏈接文本
- 標簽名
- 類名
- CSS選擇器
找到元素的基本方法是element(),例如查找id為“l(fā)ogin”的元素:
driver.element('id', 'login')
但是在大多數(shù)情況下,不需要使用這個基本的方法,為了方便起見,有很多擴展方法。
文本
例如,查找頁面上name屬性為“Login failed!”的元素:
driver.element_by_name('Login failed!')
id
例如,查找id為“l(fā)ogin”的元素:
driver.element_by_id('login')
XPath
XPath是XML Path的簡稱,由于HTML文檔本身就是一個標準的XML頁面,所以可以使用XPath的語法來定位頁面元素。這個方法是非常強大的元素查找方式,使用這種方法幾乎可以定位到頁面上的任意元素。
例如,查找頁面上id為“finding-elements-to-interact”的元素下的第4個table元素:
driver.element_by_xpath('//*[@id="finding-elements-to-interact"]/table[4]')
鏈接文本
這個方法比較直接,即通過超文本鏈接上的文字信息來定位元素,這種方式一般專門用于定位頁面上的超文本鏈接。
例如,查找頁面上文字為“macaca”的超文本鏈接:
driver.element_by_link_text('macaca')
部分鏈接文本
這個方法是上一個方法的擴展,當不能準確知道超鏈接上的文本信息或者只想通過一些關(guān)鍵字進行匹配時,可以使用這個方法來通過部分鏈接文字進行匹配。
例如,查找頁面上部分文字為“maca”的超文本鏈接:
driver.element_by_partial_link_text('maca')
標簽名
該方法可以通過元素的標簽名稱來查找元素,需要注意的是,這個方法搜索到的元素通常不止一個。
例如,查找頁面上的“ input”標簽:
driver.element_by_tag_name('input')
此外,WebDriver上的所有元素方法都可以在WebElement上使用,也就是從當前Web元素中查找元素:
web_element.element_by_id('ss')
類名
一般程序員或頁面設(shè)計師會給元素直接賦予一個樣式屬性或者利用css文件里的偽類來定義元素樣式,這個方法可以利用元素的css樣式表所引用的偽類名稱來進行元素查找。
例如,查找頁面上className屬性為“btn”的元素:
driver.element_by_class_name('btn')
CSS選擇器
這種元素定位方式跟XPath比較類似,但執(zhí)行速度較快,所以功能也是蠻強大的。
例如,查找頁面上樣式表為“.btn”的元素:
driver.element_by_css_selector('.btn')
異常處理
當沒有找到元素時,會引發(fā)WebDriverException異常。為了避免這種情況,可是使用element_if_exists方法,如果元素存在,則返回True,否則返回False,例如:
driver.element_by_id_if_exists('login')
也可以使用element_or_none方法,如果元素存在,則返回元素,否則返回None,例如:
driver.element_by_id_or_none('login')
此外,還有wait_for方法等待元素滿足給定條件,默認等待10秒,每個間隔1秒,斷言器函數(shù)默認為asserters.is_displayed,例如:
driver.wait_for_element_by_id('login')
按鍵輸入
當需要完成一個輸入字段的操作時,可以將一系列的按鍵行為發(fā)送給一個元素:
driver.web_element.send_keys('123456')
send_keys方法也接受一個數(shù)組,這在發(fā)送特殊鍵(不是文本的按鍵)時非常有用:
driver.web_element.send_keys([1, 2, 3, 4, 5, 6])
PC按鍵映射:
| 映射 | 按鍵 | 鍵碼 |
|---|---|---|
| \uE002 | HELP | 259 (0x00000103) |
| \uE003 | BACK_SPACE | 67 (0x00000043) |
| \uE004 | TAB | 61 (0x0000003d) |
| \uE005 | CLEAR | 28 (0x0000001c) |
| \uE007 | ENTER | 66 (0x00000042) |
| \uE008 | SHIFT | 59 (0x0000003b) |
| \uE009 | CONTROL | 113 (0x00000071) |
| \uE00A | ALT | 57 (0x00000039) |
| \uE00B | PAUSE | 121 (0x00000079) |
| \uE00C | ESCAPE | 111 (0x0000006f) |
| \uE00E | PAGE_UP | 92 (0x0000005c) |
| \uE00F | PAGE_DOWN | 93 (0x0000005d) |
| \uE010 | END | 123 (0x0000007b) |
| \uE011 | HOME | 122 (0x0000007a) |
| \uE012 | ARROW_LEFT | 21 (0x00000015) |
| \uE013 | ARROW_UP | 19 (0x00000013) |
| \uE014 | ARROW_RIGHT | 22 (0x00000016) |
| \uE015 | ARROW_DOWN | 20 (0x00000014) |
| \uE016 | INSERT | 124 (0x0000007c) |
| \uE017 | DELETE | 112 (0x00000070) |
| \uE031 | F1 | 131 (0x00000083) |
| \uE032 | F2 | 132 (0x00000084) |
| \uE033 | F3 | 133 (0x00000085) |
| \uE034 | F4 | 134 (0x00000086) |
| \uE035 | F5 | 135 (0x00000087) |
| \uE036 | F6 | 136 (0x00000088) |
| \uE037 | F7 | 137 (0x00000089) |
| \uE038 | F8 | 138 (0x0000008a) |
| \uE039 | F9 | 139 (0x0000008b) |
| \uE03A | F10 | 140 (0x0000008c) |
| \uE03B | F11 | 141 (0x0000008d) |
| \uE03C | F12 | 142 (0x0000008e) |
| \uE03D | META | 117 (0x00000075) |
Android按鍵映射:
| 映射 | 按鍵 | 鍵碼 |
|---|---|---|
| \uE101 | POWER 電源鍵 | 26 (0x0000001a) |
| \uE102 | VOLUME_UP 音量加 | 24 (0x00000018) |
| \uE103 | VOLUME_DOWN 音量減 | 25 (0x00000019) |
| \uE104 | VOLUME_MUTE 禁音 | 164 (0x000000a4) |
| \uE105 | HOME_SCREEN HOME鍵 | 3 (0x00000003) |
| \uE106 | BACK BACK鍵 | 4 (0x00000004) |
| \uE107 | MENU MENU鍵 | 82 (0x00000052) |
| \uE108 | CAMERA 拍照鍵 | 27 (0x0000001b) |
| \uE109 | CALL 電話鍵 | 5 (0x00000005) |
| \uE10A | END_CALL 結(jié)束電話鍵 | 6 (0x00000006) |
| \uE10B | SEARCH 搜索鍵 | 84 (0x00000054) |
| \uE10C | DPAD_LEFT 導航左鍵 | 21 (0x00000015) |
| \uE10D | DPAD_UP 導航上鍵 | 19 (0x00000013) |
| \uE10E | DPAD_RIGHT 導航右鍵 | 22 (0x00000016) |
| \uE10F | DPAD_DOWN 導航下鍵 | 20 (0x00000014) |
| \uE110 | DPAD_CENTER 導航確定鍵 | 23 (0x00000017) |
iOS按鍵映射:
| 映射 | 按鍵 |
|---|---|
| \uE105 | HOME_SCREEN HOME鍵 |
使用數(shù)組發(fā)送特殊鍵非常方便:
driver.web_element.send_keys([1, DELETE, 1, 2, 3, 4, 5, 6])
屏幕快照
截圖時可以返回截圖的base64編碼字符串:
base64_str = driver.take_screenshot()
或者保存截圖到給定的路徑:
driver.save_screenshot('./screen.png')
save_screenshot方法具有可選的第二個參數(shù)來決定是否由于某種原因無法保存到文件系統(tǒng)時忽略IOError。例如,沒有讀寫權(quán)限時,忽略異常信息:
driver.save_screenshot('/etc/screen.png', True)
切換環(huán)境
對于移動端測試,可能需要在Native(原生)和Webview(H5)之間切換環(huán)境,首先獲取現(xiàn)有的環(huán)境:
ctxs = driver.contexts
print(ctxs) # ['NATIVE', 'WEBVIEW_1', 'WEBVIEW_2']
然后切換到指定的環(huán)境:
driver.context = 'WEBVIEW_1'
print(driver.context) # WEBVIEW_1
執(zhí)行JS片段
在一些復雜的情況下,可能需要在頁面中插入一段JavaScript代碼,并得到想要的任何東西??梢栽谀_本中使用arguments來表示腳本之后的索引參數(shù)。
script = 'return document.querySelector(".btn").tagName === arguments[0]'
args = ['div']
result = driver.execute_script(script, *args)
上面的腳本等于JavaScript中的IIFE:
function () {
return document.querySelector(".btn").tagName === "div"
}()
WebElement方法
WebElement的實例方法主要與行為元素有關(guān),比如點擊元素、獲取標簽名或元素的內(nèi)部文本。WebElement實例是通過查找元素命令返回的,例如通過id檢索元素:
web_element = driver.element_by_id('login')
print(type(web_element) == WebElement) # True
例如點擊元素:
web_element.click()
例如獲取元素的標簽名稱:
tag_name = web_element.tag_name
例如獲取元素的內(nèi)部文本:
text = web_element.text
編碼風格
建議使用官方推薦的兩種編碼風格,第一種是使用額外的括號:
(
driver
.get('https://www.google.com')
.element_by_id('login')
.click()
)
第二種是使用反斜杠:
driver \
.get('https://www.google.com') \
.element_by_id('login') \
.click()