1. 簡介
“壓軸”原本是戲曲名詞,指一場折子戲演出的倒數第二個劇目。在現代社會中有很多應用,比如“壓軸戲”,但壓軸也是人們知識的一個盲區。“壓軸”本意是指倒數第二個節目,而不是人們常說的倒數第一個,倒數第一個節目稱“壓台”。想看“壓台篇”,敬請關注宏哥
等待壓台篇發布。當然了,宏哥不是唱戲啊,而是分享技術類文章的。好了言歸正傳回歸正題。
之前的文章中,針對元素的各種屬性,進行了相對應的操作,而且對模擬鍵盤和鼠標的操作也有簡單介紹。那么接下來由宏哥帶着各位小伙伴和童鞋們來詳細地看看selenium如何模擬操作鍵盤和鼠標;練習如何執行JavaScript、多窗口切換、處理iframe切換等知
識和內容。
2. 鍵盤事件
webdriver可以模擬常規鍵盤上所有的按鍵操作,在導入包的源碼中可以看到所有命令對應的按鍵。
以代碼的形式來展示:
# coding=utf-8🔥 # 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行 # 2.注釋:包括記錄創建時間,創建人,項目名稱。 ''' Created on 2019-12-06 @author: 北京-宏哥 QQ交流群:705269076 Project: 《手把手教你》系列練習篇之7-python+ selenium自動化測試 ''' # 3.導入模塊 import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("https://www.baidu.com") # 鍵盤事件 driver.find_element(By.ID, 'kw').send_keys("selenium&python?") time.sleep(3) driver.find_element(By.ID, 'kw').send_keys(Keys.BACK_SPACE) # 利用backspace鍵刪除字符串最后一位 time.sleep(3) driver.find_element(By.ID, 'kw').send_keys(Keys.SPACE) # 在字符串后空格鍵添加空格 driver.find_element(By.ID, 'kw').send_keys("學習") # 繼續在字符串后面添加字符串 driver.find_element(By.ID, 'kw').send_keys(Keys.ENTER) # 輸入回車enter鍵進行搜索 time.sleep(3) driver.find_element(By.ID, 'kw').send_keys(Keys.CONTROL, 'a') # 全選搜索框中的內容 driver.find_element(By.ID, 'kw').send_keys(Keys.CONTROL, 'x') # 剪切搜索框中的內容,也可以使用c進行復制 time.sleep(3) # 打開另外一個搜索網站,輸入剛剛剪切的內容 driver.get("https://www.google.com") driver.find_element(By.ID, 'lst-ib').send_keys(Keys.CONTROL, 'v') # 粘貼剛剛復制、剪切的內容 driver.find_element(By.ID, 'lst-ib').submit() # 提交搜索 time.sleep(3) """ 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) send_keys(Keys.F1) 鍵盤 F1 ... send_keys(Keys.F12) 鍵盤 F12 """ driver.quit()
3. 鼠標事件
上面的鍵盤事件比較好理解,鼠標事件的話直接看源代碼或許就有些糾結了,但是源代碼的注釋說明其實對ActionChains說明的比較清楚。
用戶操作。
在ActionChains對象上調用操作方法時,操作將存儲在ActionChains對象的隊列中。
當調用perform()時,事件將按它們排隊的順序觸發。
ActionChains可以用於鏈式或者可以將操作逐個排隊,然后執行。
無論哪種方式,動作都按照它們被調用的順序執行,一個在另一個之后執行。
這里還是以代碼展示部分功能吧:
# coding=utf-8🔥 # 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行 # 2.注釋:包括記錄創建時間,創建人,項目名稱。 ''' Created on 2019-12-06 @author: 北京-宏哥 QQ交流群:705269076 Project: 《手把手教你》系列練習篇之7-python+ selenium自動化測試 ''' # 3.導入模塊 import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() driver.get("https://www.baidu.com") time.sleep(3) # 定位元素 ele_1 = driver.find_element(By.XPATH, '//*[@id="u1"]/a[9]') ele_2 = driver.find_element(By.XPATH, '//*[@id="u1"]/a[8]') # 將鼠標懸停在元素1上3秒后再次懸停到元素2上 ActionChains(driver).move_to_element(ele_1).perform() time.sleep(3) ActionChains(driver).move_to_element(ele_2).perform() time.sleep(3) driver.quit()
上述代碼實現了在元素上進行懸停,再移動至另一元素上。
還有其他操作如下:
""" click(on_element=None) ——單擊鼠標左鍵 click_and_hold(on_element=None) ——點擊鼠標左鍵,不松開 context_click(on_element=None) ——點擊鼠標右鍵 double_click(on_element=None) ——雙擊鼠標左鍵 drag_and_drop(source, target) ——拖拽到某個元素然后松開 drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某個坐標然后松開 key_down(value, element=None) ——按下某個鍵盤上的鍵 key_up(value, element=None) ——松開某個鍵 move_by_offset(xoffset, yoffset) ——鼠標從當前位置移動到某個坐標 move_to_element(to_element) ——鼠標移動到某個元素 move_to_element_with_offset(to_element, xoffset, yoffset) ——移動到距某個元素(左上角坐標)多少距離的位置 perform() ——執行鏈中的所有動作 release(on_element=None) ——在某個元素位置松開鼠標左鍵 send_keys(*keys_to_send) ——發送某個鍵到當前焦點的元素 send_keys_to_element(element, *keys_to_send) ——發送某個鍵到指定元素 """
通過這些鍵盤和鼠標的操作,就可以做更多了
4. 執行JavaScript
前面文章介紹了ActionChains下的鼠標懸停和右鍵操作,其實ActionChains還有其他方法,你可以 action = ActionChains,通過這,先初始化一個ActionChains實例對象,然后在action后面輸入一個點號,查看支持哪些action方法。本文開始介紹如何執行JS腳本,會用兩個例子說明。
示例一,執行js腳本觸發一個alert彈出框。
相關腳本代碼如下:
4.1 代碼實現:
4.2 參考代碼:
# coding=utf-8🔥 # 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行 # 2.注釋:包括記錄創建時間,創建人,項目名稱。 ''' Created on 2019-12-05 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium自動化測試練習篇5 ''' # 3.導入模塊 import time from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(6) driver.get("https://www.baidu.com") time.sleep(1) driver.execute_script("window.alert('這是一個alert彈框。');") # 注意這里的分號是英文輸入法的分號,不能用中文
4.3 運行結果:
運行代碼后,控制台打印如下圖的結果
4.4 瀏覽器運行結果
為了看得清楚,我們這里還是不退出瀏覽器,瀏覽器運行后,如下圖:
4.5 示例二
執行js腳本來控制瀏覽器豎向滾動條
打開百度貼吧,然后拖動滾動條到左側 “地區"
4.5.1 代碼實現:
4.5.2 參考代碼:
# coding=utf-8🔥 # 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行 # 2.注釋:包括記錄創建時間,創建人,項目名稱。 ''' Created on 2019-12-05 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium自動化測試練習篇5 ''' # 3.導入模塊 import time from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(6) driver.get("https://tieba.baidu.com/index.html") time.sleep(1) target_elem = driver.find_element_by_link_text("地區") driver.execute_script("return arguments[0].scrollIntoView();",target_elem) # 用目標元素參考去拖動 #driver.execute_script("scroll(0,2400)") # 這個是第二種方法,比較粗劣,大概的拖動
4.5.3 運行結果:
運行代碼后,控制台打印如下圖的結果
4.5.4 瀏覽器運行結果
為了看得清楚,我們這里還是不退出瀏覽器,瀏覽器運行后,如下圖:
5. 多窗口之間切換
本文來介紹如何處理driver在多窗口之間切換,想一下這樣的場景,在頁面A點擊一個連接,會觸發在新Tab或者新窗口打開頁面B,由於之前的driver實例對象在頁面A,但是你接下來的腳本是操作頁面B的元素,這樣就造成了找不到元素的報錯。本來介紹selenium中switch_to.window()方法來處理這個問題。
測試場景:打開百度新聞(頁面A),點擊熱點新聞中第一個新聞鏈接(一般是國家領導人的新聞),會在第二個窗口打開這個新聞的具體詳情頁(頁面B),測試需要去判斷你點擊這個這個新聞,在打開的詳情頁是否正確。
問題拆分:
1. 我們已經知道switch_to.window()方法可以處理窗口切換的問題
2. 在頁面A跳轉到頁面B之前,我們需要用一個變量保存這個新聞的標題
3. 切換到頁面B后,我們獲取這個新聞標題,然后和前面這個變量保存的值去對比,如果相等,那么就測試通過。
我們分兩個步驟去解答這個測試需求:
1. 先實現頁面A切換到頁面B
2. 頁面A和頁面B兩個新聞標題進行對比
先看看窗口切換的腳本代碼:
5.1 代碼實現:
5.2 參考代碼:
# coding=utf-8🔥 # 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行 # 2.注釋:包括記錄創建時間,創建人,項目名稱。 ''' Created on 2019-12-06 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium自動化測試練習篇5 ''' # 3.導入模塊 import time from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.get('http://news.baidu.com') time.sleep(1) driver.find_element_by_xpath("//*[@id='pane-news']/div/ul/li[1]/strong/a").click() print (driver.current_window_handle) # 輸出當前窗口句柄 handles = driver.window_handles # 獲取當前全部窗口句柄集合 print (handles) # 輸出句柄集合 for handle in handles:# 切換窗口 if handle != driver.current_window_handle: print ('switch to second window',handle) driver.close() # 關閉第一個窗口 driver.switch_to.window(handle) #切換到第二個窗口
5.3 運行結果:
運行代碼后,控制台打印如下圖的結果
5.4 瀏覽器運行結果
為了看得清楚,我們這里還是不退出瀏覽器,瀏覽器運行后,如下圖:
代碼解釋:
1. 先打印當前窗口(頁面A)句柄,一個長字符串
2. 獲取全部窗口句柄,這里我們有兩個,打印出這兩個句柄。
3. for 循環遍歷,當發現其中一個句柄和當前句柄不相等,這里做了三件事,第一件,打印一個語句,告訴你馬上要切換到第二個窗口,第二件,關閉當前窗口,這里指頁面A,第三,切換到頁面B窗口。
這里在切換到第二個頁面時候,我關閉之前的頁面A,只是我個人測試習慣,你可以不關閉,但是你的要思路清晰,哪些元素在頁面A還是在頁面B,如果操作了頁面B后還要操作頁面A的元素,你還要切換到頁面A,為了麻煩,建議你每次切換都把前面頁面給關閉。
5.4 斷言切換的是不是你剛剛點擊的新聞
判斷在打開新頁面顯示的新聞標題是不是你剛剛點擊的新聞,腳本代碼如下:
5.4.1 代碼實現:
5.4.2參考代碼:
# coding=utf-8🔥 # 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行 # 2.注釋:包括記錄創建時間,創建人,項目名稱。 ''' Created on 2019-12-06 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium自動化測試練習篇5 ''' # 3.導入模塊 import time from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.get('http://news.baidu.com') time.sleep(1) news_link = driver.find_element_by_xpath("//*[@id='pane-news']/div/ul/li[1]/strong/a") page1_title_string = news_link.text #得到頁面A新聞標題 print('page1_title_string'+ page1_title_string) news_link.click() # 點擊新聞鏈接 time.sleep(1) handles = driver.window_handles for handle in handles:# 切換窗口(切換到搜狗) if handle != driver.current_window_handle: print ('switch to second window',handle) driver.close() # 關閉第一個窗口 driver.switch_to.window(handle) #切換到第二個窗口 page2_title_string = driver.find_element_by_xpath(".//*[@id='title_area']/h1").text # 詳情頁有一個原標題 print('page2_title_string'+ page2_title_string) try : assert page1_title_string in page2_title_string # 判斷頁面B標題是否包含頁面A標題 print ('Test Pass.') except Exception as e: print ('Test Fail')
5.4.3 運行結果:
運行代碼后,控制台打印如下圖的結果
注意:很有可能遇到,頁面A的標題是簡短,頁面B的標題是長標題,這個時候就需要采取,字符串包含的關系去斷言,我這里剛好打開的詳情頁有一個叫 “原標題:xxxx”,由於這個新聞具有時效性,等你看這篇文章,可能腳本運行不成功,需要調整下腳本,如果不
好斷言,就放棄斷言部分,本文只學窗口切換,至於測試斷言技能,需要你不斷去寫腳本,去掌握和提高的部分。
6. 小結
好了,今天的練習就到這里,希望大家好好的練習和理解。
您的肯定就是我進步的動力。如果你感覺還不錯,就請鼓勵一下吧!記得點波 推薦 不要忘記哦!!!