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