presence_of_element_located对比visibility_of_element_located
一. 结论
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的校验程度轻一些,在页面跳转之后判断某种标志是否出现用这个快一些;特殊情况下校验无边框的元素也会用到这个。