1. 程式人生 > WINDOWS開發 >【Selenium學習】WebDriverApi介面和二次開發

【Selenium學習】WebDriverApi介面和二次開發

WebDriverApi介面詳解

瀏覽器操作

1 driver.back()             # 後退
2 driver.forward()          # 前進
3 driver.refresh()          # 重新整理

視窗操作

1 driver.get_window_size()             # 獲取瀏覽器大小
2 driver.set_window_size(‘500‘,‘500‘)  # 設定瀏覽器大小
3 driver.maximize_window()             # 最大化瀏覽器
4 driver.current_window_handle()       # 返回當前操作的瀏覽器控制代碼
5 driver.window_handles()              # 返回所有開啟server的瀏覽器控制代碼

擷取當前頁面(截圖)

1 driver.get_screenshot_as_file(‘pic.png‘)  # 檔名必須以小寫的.png結尾

執行JavaScript語句

1 driver.execute_script(‘JavaScript Commond‘)
2 driver.execute_script(‘window.scrollTo(0,0);‘)  # 操作滾動條到瀏覽器最上面

Cookie操作

技術分享圖片
 1 # 根據cookieKey,獲取cookie資訊
 2 cookie = driver.get_cookie(‘cookieKey‘)
 3 
 4 # 獲取所有cookie資訊
 5 cookies = driver.get_cookies()
 6 
 7 # 新增cookie,嚴格按照格式新增,cookie的key為name,value為value
 8 driver.add_cookie({‘name‘: ‘tmp‘,‘value‘: ‘123123123‘})
 9 
10 # 刪除所有cookie資訊
11 driver.delete_all_cookies()
12 
13 # 根據cookieKey刪除對應cookie
14 driver.delete_cookie(‘UiCode‘)
技術分享圖片

瀏覽器控制代碼及切換

技術分享圖片
 1 print(driver.window_handles)    # 獲取所有開啟server的瀏覽器控制代碼,返回的是一個list
 2 bl = driver.find_element_by_css_selector(‘[href="/new-index/"]‘)
 3 bl.click()                      # 點選連線開啟一個新的頁面
 4 print(driver.window_handles)    # 再次獲取所有開啟server的瀏覽器控制代碼
 5 handes = driver.window_handles
 6 driver.switch_to.window(handes[1])  # 切換瀏覽器控制代碼到新開啟的這個頁面
 7 cl = driver.find_element_by_css_selector(‘#newtag‘)
 8 cl.send_keys(‘AAAA‘)
 9 driver.close()     # 關閉當前指標指向控制代碼的頁面
10 driver.switch_to.window(handes[0])  # 手動將瀏覽器指標切換回之前的頁面
11 driver.find_element_by_css_selector(‘#i1‘).send_keys(‘EEEE‘)
12 driver.quit()      # 關閉所有頁面
技術分享圖片

關閉與退出

1 driver.close()   # 關閉當前頁面,關閉頁面後如果指標切換了,必須手動切回來
2 driver.quit()    # 關閉所有頁面,退出驅動

ElementApi介面

技術分享圖片
 1 # 根據標籤屬性名稱,獲取屬性value
 2 element.get_attribute(‘style‘)
 3  
 4 # 向輸入框輸入字串 如果input的type為file型別 可以輸入檔案絕對路徑上傳檔案
 5 element.send_keys()
 6  
 7 # 清除文字內容
 8 element.clear()
 9  
10 # 滑鼠左鍵點選操作
11 element.click()
12  
13 # 通過屬性名稱獲取屬性
14 element.get_property(‘id‘)
15  
16 # 返回元素是否可見 True or False
17 element.is_displayed()
18  
19 # 返回元素是否被選中 True or False
20 element.is_selected()
21  
22 # 返回標籤元素的名字
23 element.tag_name
24  
25 # 獲取當前標籤的寬和高
26 element.size
27  
28 # 獲取元素的文字內容
29 element.text
30  
31 # 模仿回車按鈕 提交資料
32 element.submit()
33  
34 # 獲取當前元素的座標
35 element.location
36  
37 # 擷取圖片
38 element.screenshot()
技術分享圖片

彈框處理

1 driver.find_element_by_css_selector(‘#confirm‘).click()  # 點選按鈕,彈出彈框
2 print(driver.switch_to.alert.text)  # 列印彈框返回的文字文字
3 driver.switch_to.alert.accept()     # 確認
4 driver.switch_to.alert.dismiss()    # 取消

常見異常

技術分享圖片
 1 NoSuchElementException:沒有找到元素
 2  
 3 NoSuchFrameException:沒有找到iframe
 4  
 5 NoSuchWindowException:沒找到視窗控制代碼handle
 6  
 7 NoSuchAttributeException:屬性錯誤
 8  
 9 NoAlertPresentException:沒找到alert彈出框
10  
11 ElmentNotVisibleException:元素不可見
12  
13 ElementNotSelectableException:元素沒有被選中
14  
15 TimeoutException:查詢元素超時

ActionChainsApi介面詳解

  UI自動化測試過程中,經常遇到那種,需要滑鼠懸浮後,要操作的才會元素出現的這種場景,那麼我們就要模擬滑鼠懸浮到某一個位置,做一系列的連貫操作,Selenium給我們提供了ActionChains模組。

引入方式

1 from selenium.webdriver.common.action_chains import ActionChains

move_to_element

技術分享圖片
 1 # 滑鼠移動到某一個元素上,結束elementObj
 2 ActionChains(driver).move_to_element(e)
 3 
 4 # 滑鼠移動到制定的座標上,引數接受x,y
 5 ActionChains(driver).move_by_offset(e[‘x‘],e[‘y‘])
 6 
 7 例:
 8 # 滑鼠懸浮操作
 9 from selenium.webdriver.common.action_chains import ActionChains
10 fl = driver.find_element_by_css_selector(‘#a‘)  # 獲取滑鼠要懸浮的元素
11 dis1 = driver.find_element_by_css_selector(‘#dis1‘)  # 獲取要點選的按鈕
12 ActionChains(driver).move_to_element(fl).click(dis1).perform() # 鏈式程式設計,可以一直點下去
技術分享圖片 技術分享圖片
 1 from selenium.webdriver.common.action_chains import ActionChains
 2 from selenium import webdriver
 3 import time
 4 driver = webdriver.Chrome()
 5 driver.maximize_window()
 6 driver.get(‘http://ui.imdsx.cn/uitester/‘)
 7 time.sleep(2)
 8 driver.execute_script(‘window.scrollTo(0,0);‘)
 9 time.sleep(1)
10 a = driver.find_element_by_id(‘a‘).location  # 獲取元素座標,返回的是一個字典
11 # {‘x‘: 716,‘y‘: 112}
12 dis = driver.find_element_by_id(‘dis1‘)
13 ActionChains(driver).move_by_offset(a[‘x‘],a[‘y‘]).double_click(dis).perform()
技術分享圖片

  實際上ActionChains這個模組的實現的核心思想就是,當你呼叫ActionChains的方法時,不會立即執行,而是會將所有的操作按順序存放在一個List裡,當你呼叫perform()方法時,佇列中的時間會依次執行。

drag_and_drop

技術分享圖片
 1 # 將source元素拖放至target元素處,引數為兩個elementObj
 2 ActionChains(driver).drag_and_drop(source=source,target=target)
 3 
 4 # 將一個source元素 拖動到針對source坐上角坐在的x y處 可存在負寬度的情況和負高度的情況
 5 ActionChains(driver).drag_and_drop_by_offset(source,x,y)
 6 
 7 # 這種也是拖拽的一種方式,都是以源元素的左上角為基準,移動座標
 8 ActionChains(driver).click_and_hold(dom).move_by_offset(169,188).release().perform()
 9 
10 例子:
11 # 拼圖,拖動圖片到指定位置
12 from selenium.webdriver.common.action_chains import ActionChains
13 gl = driver.find_element_by_css_selector(‘[href="/move/"]‘)
14 gl.click()
15 handes = driver.window_handles
16 driver.switch_to.window(handes[1])
17 source = driver.find_element_by_css_selector(‘#dragger‘)
18 target = driver.find_element_by_css_selector(‘#i1‘)
19 source1 = driver.find_element_by_css_selector(‘#dragger1‘)
20 target1 = driver.find_element_by_css_selector(‘#i2‘)
21 source2 = driver.find_element_by_css_selector(‘#dragger2‘)
22 target2 = driver.find_element_by_css_selector(‘#i3‘)
23 source3 = driver.find_element_by_css_selector(‘#dragger3‘)
24 target3 = driver.find_element_by_css_selector(‘#i4‘)
25 # drag_and_drop 拖拽
26 ActionChains(driver).drag_and_drop(source,target).drag_and_drop(source1,target1).drag_and_drop(source2,target2).drag_and_drop(source3,target3).perform()
技術分享圖片

click

技術分享圖片
 1 # 單擊事件,可接受elementObj
 2 ActionChains(driver).click()
 3  
 4 # 雙擊事件,可接受elementObj
 5 ActionChains(driver).double_click()
 6  
 7 # 點選滑鼠右鍵
 8 ActionChains(driver).context_click()
 9  
10 # 點選某個元素不鬆開,接收elementObj
11 ActionChains(driver).click_and_hold()
12  
13 # # 某個元素上鬆開滑鼠左鍵,接收elementObj
14 ActionChains(driver).release()
技術分享圖片

key_up與key_down

  有時我們需要模擬鍵盤操作時,那麼就需要用到ActionChains中的key操作了,提供了兩個方法,key_down與key_up,模擬按下鍵盤的某個鍵子,與鬆開某個鍵子,接收的引數是按鍵的Keys與elementObj。可以與send_keys連用(例:全選、複製、剪下、貼上)

1 # key_down 模擬鍵盤摁下某個按鍵 key_up 鬆開某個按鍵,與sendkey連用完成一些操作,每次down必須up一次否則將出現異常
2 ActionChains(driver).key_down(Keys.CONTROL,dom).send_keys(‘a‘).send_keys(‘c‘).key_up(Keys.CONTROL)3     .key_down(Keys.CONTROL,dom1).send_keys(‘v‘).key_up(Keys.CONTROL).perform()

Keys 實際是Selenium提供的一個鍵盤事件模組,在模擬鍵盤事件時需要匯入Keys模組

引入方式

1 from selenium.webdriver.common.keys import Keys

Switch與SelectApi介面詳解

  我們在UI自動化測試時,總會出現新建一個tab頁面、彈出一個瀏覽器級別的彈框或者是出現一個iframe標籤,這時我們用WebDriver提供的Api介面就無法處理這些情況了。需要用到Selenium單獨提供的模組switch_to模組

SwitchToWindows

1 handles = driver.window_handles
2  
3 # SwitchToWindows接受瀏覽器TAB的控制代碼
4 driver.switch_to.window(handles[1])

例子:

技術分享圖片
 1 # 瀏覽器控制代碼及指標切換
 2 print(driver.window_handles)    # 獲取所有開啟server的瀏覽器控制代碼,返回的是一個list
 3 bl = driver.find_element_by_css_selector(‘[href="/new-index/"]‘)
 4 bl.click()                      # 點選連線開啟一個新的頁面
 5 print(driver.window_handles)    # 再次獲取所有開啟server的瀏覽器控制代碼
 6 handes = driver.window_handles
 7 driver.switch_to.window(handes[1])  # 切換瀏覽器控制代碼到新開啟的這個頁面
 8 cl = driver.find_element_by_css_selector(‘#newtag‘)
 9 cl.send_keys(‘AAAA‘)
10 driver.close()     # 關閉當前指標指向控制代碼的頁面
11 driver.switch_to.window(handes[0])  # 手動將瀏覽器指標切換回之前的頁面
12 driver.find_element_by_css_selector(‘#i1‘).send_keys(‘EEEE‘)
13 driver.quit()      # 關閉所有頁面
技術分享圖片

SwitchToFrame

技術分享圖片
 1 # SwitchToFrame支援id、name、frame的element
 2  
 3 # 接受定位到的iframe的Element,這樣就可以通過任意一種定位方式進行定位了
 4 frameElement = driver.find_element_by_name(‘top-frame‘)
 5 driver.switch_to.frame(frameElement)
 6  
 7 # 通過fame的name、id屬性定位
 8 driver.switch_to.frame(‘top-frame‘)
 9  
10 # 當存在多層iframe巢狀時,需要一層一層的切換查詢,否則將無法找到
11 driver.switch_to.frame(‘top-frame‘)
12 driver.switch_to.frame(‘baidu-frame‘)
13  
14 # 跳轉到最外層的頁面
15 driver.switch_to.default_content()
16  
17 # 多層Iframe時,跳轉到上一層的iframe中
18 driver.switch_to.parent_frame()
技術分享圖片

例子:

技術分享圖片
 1 # 多層iframe切換,需要一層一層進入,但是能從任意一層切換到最外層
 2 # 切換到top-frame
 3 driver.switch_to.frame(‘top-frame‘)
 4 import time
 5 time.sleep(1)
 6 # 輸入newtag文案
 7 driver.find_element_by_css_selector(‘#newtag‘).send_keys(‘XXXX‘)
 8 # 切換到baidu-frame
 9 driver.switch_to.frame(‘baidu-frame‘)
10 time.sleep(1)
11 # 輸入kw文案
12 driver.find_element_by_css_selector(‘#kw‘).send_keys(‘YYYY‘)
13 # 返回上一層frame,即top-frame
14 driver.switch_to.parent_frame()
15 # 清空top-frame的輸入
16 driver.find_element_by_css_selector(‘#newtag‘).clear()
17 # 再切換到baidu-frame
18 driver.switch_to.frame(‘baidu-frame‘)
19 # 再清空baidu-frame的輸入
20 driver.find_element_by_css_selector(‘#kw‘).clear()
21 # 切換到最外層frame
22 driver.switch_to.default_content()
23 # 輸入i1文案
24 driver.find_element_by_css_selector(‘#i1‘).send_keys(‘NNNN‘)
技術分享圖片

SwitchToAlert

技術分享圖片
 1 # alert 實際上也是Selenium的一個模組
 2 from selenium.webdriver.common.alert import Alert
 3  
 4 # 也可以通過Webdriver的switch_to來呼叫
 5  
 6 # 點選確認按鈕
 7 driver.switch_to.alert.accept()
 8  
 9 # 如果是確認彈框,相當於點選需要和X按鈕
10 driver.switch_to.alert.dismiss()
11  
12  
13 # 如果alert上有文字框時,可以輸入文字。(注: 沒遇到過)
14 driver.switch_to.alert.send_keys()
15  
16 # 返回Alert上面的文字內容
17 text = driver.switch_to.alert.text
技術分享圖片

例子:

1 # 彈框處理
2 driver.find_element_by_css_selector(‘#confirm‘).click()  # 點選按鈕,彈出彈框
3 print(driver.switch_to.alert.text)  # 列印彈框返回的文字文字
4 driver.switch_to.alert.accept()     # 確認
5 driver.switch_to.alert.dismiss()    # 取消

Select

  在UI自動化測試過程中,經常會遇到一些下拉框,如果我們基於Webdriver操作的話就需要click兩次,而且很容易出現問題,實際上Selenium給我們提供了專門的Select(下拉框處理模組)。

技術分享圖片
 1 # 通過select選項的索引來定位選擇對應選項(從0開始計數)
 2 Select(s).select_by_index(5)
 3  
 4 # 通過選項的value屬性值來定位
 5 Select(s).select_by_value(‘2‘)
 6  
 7 # 通過選項的文字內容來定位
 8 Select(s).select_by_visible_text(‘牡丹江‘)
 9  
10 # 返回第一個選中的optionElement物件
11 Select(s).first_selected_option
12  
13 # 返回所有選中的optionElement物件
14 Select(s).all_selected_options
15  
16 # 取消所有選中的option
17 Select(s).deselect_all()
18  
19 # 通過option的index來取消對應的option
20 Select(s).deselect_by_index(1)
21  
22 # 通過value屬性,來取消對應option
23 Select(s).deselect_by_value(‘‘)
24  
25 # 通過option的文字內容,取消對應的option
26 Select(s).deselect_by_visible_text(‘‘)
技術分享圖片

例子:

技術分享圖片
1 # 點選下拉選單再點選一個值
2 from selenium.webdriver.support.select import Select
3 driver.get(‘http://ui.imdsx.cn/html/‘)
4 driver.execute_script(‘window.scrollTo(0,1500);‘)
5 select = driver.find_element_by_xpath(‘//select[1]‘)
6 # 例項化select,接收一個select標籤,如果不是select標籤則拋異常
7 Select(select).select_by_value(‘2‘)  # 通過select標籤的option中的value的值定位
8 Select(select).select_by_index(‘2‘)  # 通過select標籤的option中的下標定位,從0開始
技術分享圖片

如果一個標籤下還有子集,可以繼續在這個標籤小查詢,如下:

技術分享圖片
1 driver.get(‘http://ui.imdsx.cn/html/‘)
2 driver.execute_script(‘window.scrollTo(0,1500);‘)
3 select = driver.find_element_by_xpath(‘//select[1]‘)
4 # 獲取select標籤下所有的option的元素
5 options = select.find_elements_by_tag_name(‘option‘)
6 for opt in options:
7     print(opt.get_attribute(‘value‘))  # 迴圈獲取select(‘//select[1]‘)標籤下的option的value屬性
8     print(opt.get_attribute(‘index‘))  # 迴圈獲取select(‘//select[1]‘)標籤下的option的下標

二次開發

技術分享圖片
 1 #!/usr/bin/env python
 2 # encoding: utf-8
 3 import unittest
 4 
 5 import json
 6 from selenium.webdriver.common.keys import Keys
 7 from selenium.webdriver.support.select import Select
 8 from uitester.common.logger import *
 9 from selenium import webdriver
10 from selenium.webdriver.support.wait import WebDriverWait
11 from selenium.webdriver.common.by import By
12 from selenium.webdriver.chrome.options import Options
13 from selenium.webdriver import ActionChains
14 from selenium.webdriver.support import expected_conditions as EC
15 from selenium.common.exceptions import *
16 
17 
18 class BasePage(object):
19     # Page基類,所有其他Page全部繼承此類,負責元素和driver方法的封裝
20     def __init__(self,driver):
21         self.driver = driver
22         self.mgr_info = {}
23         self.agent_info = {}
24         self.read_config()
25         self.mgr_version = self.mgr_info.get(stable_platform_ver,‘‘)
26         mgr_version_split = self.mgr_version.split(.)
27         # 方便版本比較,e.g. 3216
28         self.mgr_version_format = int(mgr_version_split[0] + mgr_version_split[1] + mgr_version_split[2][:2])
29 
30     def read_config(self):
31         # 方便適配版本
32         # uitester會以包的形式被引用
33         # config_path = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))),‘config.json‘))
34         for name in os.listdir("C:\\jenkins\\workspace\\"):
35             if agent_ in name:
36                 agent_name = name
37                 break
38         config_path = os.path.join(rC:\Jenkins\workspace\{}.format(agent_name),config.json)
39         if os.path.exists(config_path):
40             with open(config_path) as f:
41                 config_content = eval(f.read())
42                 config_content = json.loads(json.dumps(config_content))
43                 self.mgr_info = config_content[mgr_cfg]
44                 self.agent_info = config_content[agent_cfg]
45         else:
46             LOG_DEBUG(配置檔案config.json不存在!)
47 
48     def find_element(self,loc,strict=False,timeout=10):
49         """
50 
51         :param loc:
52         :param strict: type: bool e.g.True:若找不到元素直接拋錯,False:若找不到元素,日誌列印報錯,不拋錯
53         :return:
54         """
55         try:
56             WebDriverWait(self.driver,timeout,0.5).until(EC.presence_of_element_located(loc))
57         except Exception as e:
58             LOG_DEBUG([1] 頁面未找到元素,loc: {}.format(loc))
59         try:
60             WebDriverWait(self.driver,0.5).until(EC.visibility_of_element_located(loc))
61             return self.driver.find_element(*loc)
62         except Exception as e:
63             LOG_DEBUG([1] ERROR [find_element]: {}.format(e))
64             LOG_DEBUG([1] 頁面未找到元素,loc: {}.format(loc))
65         self.refresh()
66         time.sleep(8)
67         try:
68             WebDriverWait(self.driver,0.5).until(EC.presence_of_element_located(loc))
69         except Exception as e:
70             LOG_DEBUG([2] 頁面未找到元素,loc: {}.format(loc))
71         try:
72             WebDriverWait(self.driver,0.5).until(EC.visibility_of_element_located(loc))
73             return self.driver.find_element(*loc)
74         except Exception as e:
75             LOG_DEBUG([2] ERROR [find_element]: {}.format(e))
76             LOG_DEBUG([2] 頁面未找到元素,loc: {}.format(loc))
77             if strict:
78                 raise e
79 
80     def find_elements(self,timeout=10):
81         try:
82             WebDriverWait(self.driver,0.5).until(EC.presence_of_element_located(loc))
83         except Exception as e:
84             LOG_DEBUG(ERROR [find_element]: {}.format(e))
85             LOG_DEBUG(頁面未找到元素: {}.format(loc))
86         try:
87             WebDriverWait(self.driver,0.5).until(EC.visibility_of_element_located(loc))
88             return self.driver.find_elements(*loc)
89         except Exception as e:
90             LOG_DEBUG(ERROR [find_elements]: {}.format(e))
91             LOG_DEBUG(頁面未找到元素: {}.format(loc))
92             if strict:
93                 raise e
94 
95     def clear(self,loc=None,ele=None,strict=False):
96         if not (loc or ele):
97             LOG_ERROR(loc: {},ele: {},請至少輸入一個有效引數!.format(loc,
View Code