1112UI自動化測試經驗分享-expected_conditions模組下的visibility_of()
這兩天在學習顯式等待,其實就是把expected_conditions模組下的幾個類實踐,去敲一下。上週六學到visibility_of()遇到些問題,今天分享下:
一)visibility_of()
這是原始碼:
class visibility_of(object): """ An expectation for checking that an element, known to be present on the DOM of a page, is visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0. element is the WebElement returns the (same) WebElement once it is visible """ def __init__(self, element): self.element = element def __call__(self, ignored): return _element_if_visible(self.element)
翻譯下注釋:visibility_of()這個類是檢查元素存在DOM頁的,要能夠看得到;可見就代表元素不僅僅只是顯示,還要求寬和高大於0;
需要傳入一個WebElement;一旦可見返回相同的WebElement;
我的總結是這個類需要傳入一個element;可見就返回這個element,不可見就返回False;
二)不存在的元素
這是一個錯誤的例子!!!
是我的思路跑偏了:visibility_of()用來判斷元素是否可見-不存在的元素肯定不可見,所以就掉到自己挖的坑裡。
正確的思路應該是:元素是否可見,1.可見 2.不可見,不可見那就是隱藏、不顯示。
先分享 這個不存在的例子
def test_57k1(self): """expected_conditions模組visibility_of(element) """ # 判斷element元素是否可見。直接傳element;如果可見就返回這個元素,不可見就返回False from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.get("https://www.baidu.com") print('開始', time.ctime()) print(EC.visibility_of(self.driver.find_element(By.CSS_SELECTOR, 'input#kw'))(self.driver)) # 傳入driver 返回一個WebElement print(EC.visibility_of(self.driver.find_element(By.CSS_SELECTOR, 'input#kw'))(self.driver).get_attribute('class')) # 成功返回一個WebElement 可獲取tag_name\\獲取class屬性值 print('1', time.ctime()) try: print(EC.visibility_of(self.driver.find_element(By.CSS_SELECTOR, 'input#kw123'))(self.driver)) # 查詢一個不存在的元素 except BaseException as e111: print(e111) # 報錯的是 no such element: Unable to locate element print('2', time.ctime()) print(WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element(By.CSS_SELECTOR, 'input#kw')))) # 顯式等待 + 判斷這個元素是否可見 print(WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element(By.CSS_SELECTOR, 'input#kw'))).tag_name) print('3', time.ctime()) try: print('ABC', time.ctime()) WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element_by_css_selector('input#kw123')), '失敗') # 一個不存在的元素 except BaseException as e222: print('BCD', time.ctime()) print(e222) # Message: no such element: Unable to locate element self.assertEqual(WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element(By.ID, 'su'))).tag_name, 'input') # 如果傳入的WebElement是找不到,定位不了的,實際用不到until方法,更不要提顯式等待的20秒 print('end', time.ctime()) time.sleep(1) self.driver.quit()
上圖的結果 可以清楚的看得到時間是不對的,按照預期,應該有一個10秒的顯式等待的查詢時間啊。我就滿腦子都是想為啥沒有查詢時間呢?百思不得其解。
想了2天,沒想通,直到被同事的一句話: 那個數字是什麼? WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element_by_css_selector(‘input#kw123’)), ‘失敗’)
這行程式碼最初msg不是‘失敗’,是我隨手打得一串數字,同事問我,我才突然醒悟:列印的msg不是那串數字,也就是說 並非是顯式等待的錯誤!
是沒找到元素的錯誤 = =
三)不顯示、隱藏的元素
這是一個正確的例子!
12306網站上有些元素是隱藏的,所以拿來做例子。
def test_57k2(self):
"""expected_conditions模組visibility_of(element) """
# 判斷element元素是否可見。直接傳element;如果可見就返回這個元素;不可見就返回 False
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get("https://www.12306.cn/index/")
print('開始', time.ctime())
# <input id="toStation" type="hidden" value="" name="to_station">
# 這個元素預設是隱藏的
print(EC.visibility_of(self.driver.find_element(By.ID, 'toStation'))(self.driver)) # 傳入driver 不可見 返回False
print('1', time.ctime())
# <input type="text" class="input error" value="" id="toStationText">
# 這個元素是可見的
print(EC.visibility_of(self.driver.find_element(By.ID, 'toStationText'))(self.driver)) # 傳入driver 如果找到就返回一個WebElement
print(EC.visibility_of(self.driver.find_element(By.ID, 'toStationText'))(self.driver).tag_name)
print('2', time.ctime())
try:
WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element(By.ID, 'toStation')), '失敗') # 這是隱藏的
except BaseException as e111:
print(e111)
print('3', time.ctime())
try:
WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element(By.ID, 'toStationText')), '失敗') # 這是顯示的
print('這是可見的')
except BaseException as e1112:
print(e1112)
print('4', time.ctime())
# id="toStation"到達地 type="hidden" 所以要先刪除屬性
sc11 = 'document.getElementById("toStation").removeAttribute("type")'
self.driver.execute_script(sc11)
time.sleep(2)
print('10', time.ctime())
# 到達地toStation 這個元素是隱藏的,強制等待的過程就看得到這個方框;
try:
WebDriverWait(self.driver, 10).until(EC.visibility_of(self.driver.find_element(By.ID, 'toStation')), '失敗') # 這次是可見的
print('這次是可見的')
except BaseException as e1111:
print(e1111)
print('11', time.ctime())
print('end', time.ctime())
time.sleep(1)
self.driver.quit()
對比兩個圖片 就可以看得到有一個元素被顯示出來了。程式碼中 最初顯式等待+判斷這個元素是否顯示,返回的是失敗;再移除type屬性後,故而元素是可見的。結果如下圖,
這個類的坑不好爬,所以不太推薦使用這個來做顯式等待的判斷條件。
交流技術 歡迎+QQ 153132336 zy
歡迎關注 微信公眾號:紫雲小站