1. 程式人生 > >1112UI自動化測試經驗分享-expected_conditions模組下的visibility_of()

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
歡迎關注 微信公眾號:紫雲小站