presence_of_element_located對比visibility_of_element_located

測神發表於2022-01-21

  presence_of_element_located和visibility_of_element_located都是selenium裡判斷元素展示的方法,相信做ui自動化的小夥伴一定被這倆困擾過,本期做了一個方法測試。

 

結論

  先說結論:

  • presence_of_element_located: 是否載入到dom樹
  • visibility_of_element_located:是否載入到dom樹且長寬大於0。

  說明:

  • visibility_of_element_located為判斷是否"可見",可見還是不可見並不是以人眼為標準,而是頁面層級裡是否有,包括被遮罩的層級,可以理解為載入到dom樹且長寬大於0。
  • presence_of_element_located的校驗程度輕一些,在頁面跳轉之後判斷某種標誌是否出現用這個快一些;特殊情況下校驗無邊框的元素也會用到這個。

 

原始碼檢視

  不少小夥伴為一探究竟,看原始碼怎麼寫的,原始碼裡調了js,也看不出個所以然,所以還得實際測試一下。。。

 

 

 

測試兩個方法

  測試中選擇了一個可見元素,一個部分可見元素,一個隱藏(人眼看不到,被遮住)的元素進行測試。

  而 百度翻譯 網站剛好滿足這樣的場景。

 

 

  選擇彈窗為可見的元素,搜尋框為部分可見的元素,後面按鈕為看不見的元素。

  下面通過程式碼驗證:

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

bs = webdriver.Chrome()
bs.get("https://fanyi.baidu.com/#zh/en/%E4%BD%93%E9%AD%84%2C%E6%8A%80%E6%9C%AF%2C%E8%8B%B1%E8%AF%AD")

彈窗 = '//span[@class="app-guide-close"]'
半可見的輸入框 = '//textarea[@id="baidu_translate_input"]'
被遮住的按鈕 = '//span[@class="op-check"]'

# 彈窗:完全展示
try:
    x1 = WebDriverWait(bs, 3).until(
        ec.presence_of_element_located((By.XPATH, 彈窗)))
    print("彈窗載入到dom: ", x1)
    x1.click()
except TimeoutException:
    print("彈窗沒載入到dom:")

try:
    x1 = WebDriverWait(bs, 3).until(
        ec.visibility_of_element_located((By.XPATH, 彈窗)))
    print("彈窗可見: ", x1)  # 確實可見
    x1.click()
except TimeoutException:
    print("彈窗沒載入到dom:")

# 輸入框:展示了一半。本來就載入至dom了,只需測試visibility_of_element_located
try:
    x2 = WebDriverWait(bs, 3).until(
        ec.visibility_of_element_located((By.XPATH, 半可見的輸入框)))
    print("輸入框可見: ", x2)  # 此時輸入框被遮住了但還是顯示可見。由此得知,可見還是不可見並不是以人眼為標準,而是以層級裡的元素是否展示了為準。
    x2.click()
    x2.send_keys("你好世界")
except (TimeoutException, ElementClickInterceptedException):
    print("輸入框不可見或被遮住了,或不可點選")

# 對照按鈕:根本看不到。本來就載入至dom了,只需測試visibility_of_element_located
try:
    x2 = WebDriverWait(bs, 10).until(
        ec.visibility_of_element_located((By.XPATH, 被遮住的按鈕)))
    print("隱藏按鈕可見: ", x2)  # 完全遮住的元素還是可見的,說明上面推斷正確。結論在下方。
    x2.click()
except (TimeoutException, ElementClickInterceptedException):
    print("隱藏按鈕不可見或被遮住了,或不可點選")

"""
結論:
1:presence_of_element_located: 是否載入到dom樹
2:visibility_of_element_located:是否"可見",可見還是不可見並不是以人眼為標準,載入到dom樹且長寬大於0。
ui自動化中操作的元素一般都是有長寬的,所以絕大大部分情況下,用2更好。
presence_of_element_located的校驗程度輕一些,在頁面跳轉之後判斷某種標誌是否出現用這個快一些;特殊情況下校驗無邊框的元素也會用到這個。
"""

  通過測試,證實了結論中的猜想。仔細想想這也很符合邏輯,如果調整一下視窗大小、或者解析度從而隱藏了元素,從而人眼看不到,如果這種情況下程式也知道你看不到,那麼這個程式至少和瀏覽器外部環境互動了,顯然是不可能也很沒有必要的。

  最後再次說一下結論:

  • presence_of_element_located: 是否載入到dom樹
  • visibility_of_element_located:是否載入到dom樹且長寬大於0。
  • visibility_of_element_located為判斷是否"可見",可見還是不可見並不是以人眼為標準,而是頁面層級裡是否有,包括被遮罩的層級,可以理解為載入到dom樹且長寬大於0。
  • presence_of_element_located的校驗程度輕一些,在頁面跳轉之後判斷某種標誌是否出現用這個快一些;特殊情況下校驗無邊框的元素也會用到這個。

相關文章