前言

这里是清安,显示等待内容咱们本章继续,接着看。

element_to_be_selected

这个方法用来判断元素是否被选中。可以用在下拉列表,也可以用在选项框中。一起看看源码:

class element_to_be_selected(object):
    def __init__(self, element):
        self.element = element

    def __call__(self, ignored):
        return self.element.is_selected()

这里用到了.is_selected(),这个方法是用来判断是否被选中。此外,此处还必须传入的是一个元素对象。一起看看测试代码:

    def element_selected(self,*ele):
        """判断某个元素是否被选中"""
        self.wait.until(EC.element_to_be_selected(self.fox.find_element(*ele)),message="元素没有被选中,请检查元素")
if __name__ == '__main__':
    b = Brouser()
    b.get_url('https://baidu.com')
    b.fox.find_element(By.ID,'s-usersetting-top').click()
    b.fox.find_element(By.CLASS_NAME,'set').click()
    b.fox.find_element(By.ID,'s1_1').click()
    b.element_selected(By.ID,"s1_1")

老规矩,还是那个类,自行复制进去哦!此处也是切换了例子。

element_located_to_be_selected

class element_located_to_be_selected(object):
    def __init__(self, locator):
        self.locator = locator

    def __call__(self, driver):
        return _find_element(driver, self.locator).is_selected()

这个就不看测试代码了,后续源码中贴出来,跟上述的一样,只不过这里只需要传入元素即可。因为源码中自带了定位元素对象_find_element(driver, self.locator)。

element_selection_state_to_be

这些都没什么特殊的地方,大体上都类似,直接看源码:

class element_selection_state_to_be(object):
    def __init__(self, element, is_selected):
        self.element = element
        self.is_selected = is_selected

    def __call__(self, ignored):
        return self.element.is_selected() == self.is_selected

这里需要传入一个预期值,首先要明白,代码所需要的预期值是什么,是bool类型,也就是True或者False。所以我们传值的时候要带上要判断的预期值。
element_located_selection_state_to_be

        """判断元素状态符合预期"""
        self.wait.until(EC.element_selection_state_to_be(self.fox.find_element(*ele),selected), message="与预期值不匹配,请检查预期值")
if __name__ == '__main__':
    b = Brouser()
    b.get_url('http://shop.aircheng.com/simple/login')
    b.fox.find_element(By.NAME,'remember').click()
    b.element_selection_state(True,By.NAME,'remember')

element_located_selection_state_to_be
class element_located_selection_state_to_be(object):
    def __init__(self, locator, is_selected):
        self.locator = locator
        self.is_selected = is_selected

    def __call__(self, driver):
        try:
            element = _find_element(driver, self.locator)
            return element.is_selected() == self.is_selected
        except StaleElementReferenceException:
            return False

这个也是类似的,源码中带了元素对象_find_element,所以只需要传定位元素、预期值以及方法即可。

number_of_windows_to_be


这是个离谱的方法,因为,这个判断打开浏览器窗口的值是否先等的。那么为什么离谱呢,博主自测火狐浏览器,每次打开的窗口值都不同,所以这个窗口的方法,使用范围及其有限。在这里知道有这个方法即可。因为咱也不知道下一次打开的窗口号是多少。「有懂其他方法的可以私聊我,让我学习一下」

new_window_is_opened

如果说上面的那个方法是鸡肋,那么这个还有点用处。一起看看

class new_window_is_opened(object):
    def __init__(self, current_handles):
        self.current_handles = current_handles

    def __call__(self, driver):
        return len(driver.window_handles) > len(self.current_handles)

简单点,就是打开多个网页窗口后,可以使用这个方法进行判断,如果获取的全部窗口长度>传入的窗口长度,则为True反之为False

那么问题来了,如何知道传入的窗口长度,自己传入一个int的整数吗还是获取当前窗口。这就看项目来了,下面的例子是获取当前的窗口数传递的。

    def new_window(self,num):
        self.wait.until(EC.new_window_is_opened(num),message='窗口数错了')
if __name__ == '__main__':
    b = Brouser()
    b.get_url('http://shop.aircheng.com/simple/login')
    js = "window.open('https://www.baidu.com/')"
    b.fox.execute_script(js)
    headers = b.fox.current_window_handle
    b.new_window([headers])
alert_is_present

最后介绍一下这个方法,检测alert弹窗的。

class alert_is_present(object):
    def __init__(self):
        pass

    def __call__(self, driver):
        try:
            alert = driver.switch_to.alert
            return alert
        except NoAlertPresentException:
            return False

调用这个方法后会返回检测的结果,当为True也就是返回了变量alert时,我们就可以进行点击确认等操作了。看看测试代码

    def alert_present(self):
        return self.wait.until(EC.alert_is_present(), message='没有alert')
if __name__ == '__main__':
    b = Brouser()
        from selenium.webdriver.common.action_chains import ActionChains
    b.fox.get('https://www.baidu.com')
    # 定位设置按钮
    res = b.fox.find_element_by_id('s-usersetting-top')
    # 鼠标悬停在设置的元素上
    ActionChains(b.fox).move_to_element(res).perform()
    # 点击搜索设置
    b.fox.find_element('class name', 'setpref').click()
    # 更换设置
    b.fox.find_element('id', 'nr_2').click()
    # 点击保存设置
    b.fox.find_element('link text', '保存设置').click()
    # 切换窗口
    a = b.alert_present()
    # 点击确定,确定与取消不能同时存在
    a.accept()

此处我是返回了方法的,否则,无法做点击确认等操作。

到此,显示等待基本上就已经讲完了,下面会将全部的二次封装源码贴出来,自己可以在原基础上进行改动,成为自己写的代码的基类的一部分。

二次封装WebDriverWait源码

「代码中也有部分文中所讲到的例子」

# -->>>清安<<<---
from time import sleep
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver

class Brouser:
    fox = webdriver.Firefox()
    wait = WebDriverWait(fox, 5)

    def get_url(self, url):
        self.fox.get(url)

    def title(self, value):
        """网页标题是否正确"""
        self.wait.until(EC.title_is(value), message='标题不匹配哦')

    def contains_title(self,value):
        """判断是否包含指定、特定的文本"""
        self.wait.until(EC.title_contains(value))

    def presence_located(self,value,*ele):
        """检查DOM上是否存在元素,不一定意味着元素是可见的"""
        el = self.wait.until(EC.presence_of_element_located(ele),message='没有发现期望的元素')
        el.send_keys(value)

    def visibility_located(self,value,*ele):
        """检查元素是否存在于页面和可见"""
        el = self.wait.until(EC.visibility_of_all_elements_located(ele), message='没有发现期望的元素')
        el[0].send_keys(value)

    def visibility_(self,*ele):
        """检查已知存在于页面的DOM是可见的"""
        el = self.wait.until(EC.visibility_of(self.fox.find_element(*ele)))
        el.click()

    def url_be(self,url):
        """检查当前url的期望值。url是预期的url"""
        self.wait.until(EC.url_to_be(url))

    def text_element(self,text,*ele):
        """对应的文本值是否正确"""
        self.wait.until(EC.text_to_be_present_in_element(ele, text),message='请检查定位的文本值')

    def text_element_value(self,text,*ele):
        """对应的属性值是否正确"""
        self.wait.until(EC.text_to_be_present_in_element_value(ele, text),message='请检查对应的value属性值哦')

    def frame_switch_to(self,*ele):
        """需要跑frame框架,就使用https://login.tmall.com/地址"""
        self.wait.until(EC.frame_to_be_available_and_switch_to_it(ele),message='请检查元素')

    def invisibility_element(self,*ele):
        """元素时候不可见或异常"""
        self.wait.until(EC.invisibility_of_element_located(ele), message='请检查元素是否正确')

    def element_clickable(self,*ele):
        """元素是否可以点击"""
        ele = self.wait.until(EC.element_to_be_clickable(ele),message='请检查元素是否可点击')
        ele.click()

    def staleness_(self,*ele):
        """判断元素是否从DOM中移除"""
        self.wait.until_not(EC.staleness_of(self.fox.find_element(ele)))

    def element_selected(self,*ele):
        """判断某个元素是否被选中"""
        self.wait.until(EC.element_to_be_selected(self.fox.find_element(*ele)),message="元素没有被选中,请检查元素")

    def element_located_selected(self,*ele):
        """判断某个元素是否被选中"""
        self.wait.until(EC.element_located_to_be_selected(ele), message="元素没有被选中,请检查元素")

    def element_selection_state(self,selected,*ele):
        """判断元素状态符合预期"""
        self.wait.until(EC.element_selection_state_to_be(self.fox.find_element(*ele),selected), message="与预期值不匹配,请检查预期值")

    def new_window(self,num):
        """窗口长度判断"""
        self.wait.until(EC.new_window_is_opened(num),message='窗口数错了')

    def alert_present(self):
        return self.wait.until(EC.alert_is_present(), message='没有alert')
        
if __name__ == '__main__':
    b = Brouser()
    # b.get_url('http://shop.aircheng.com/simple/login')
    # js = "window.open('https://www.baidu.com/')"
    # b.fox.execute_script(js)
    """
    b.get_url('https://baidu.com')
    b.fox.find_element(By.ID,'s-usersetting-top').click()
    b.fox.find_element(By.CLASS_NAME,'set').click()
    b.fox.find_element(By.ID,'s1_1').click()
    b.element_selected(By.ID, "s1_1")
    b.element_located_selected(By.ID,"s1_1")"""
    # b.get_url('https://login.tmall.com/')
    # b.url_be('http://shop.aircheng.com/simple/login')
    # b.presence_located('qingan', By.NAME, 'login_info')
    # b.visibility_located('qingan',By.NAME,'password')
    # b.visibility_(By.NAME, 'remember')
    # b.text_element('新用户',By.CLASS_NAME, 'reg_btn')
    # b.text_element_value('登录',By.CLASS_NAME,'input_submit')
    """ 
    # b.frame_switch_to(By.ID,'J_loginIframe')
    # t = b.fox.find_element(By.CLASS_NAME,'forgot-password-a-link').text
    # print(t)"""
    # b.invisibility_element(By.CLASS_NAME,'ddd')
    # b.element_clickable(By.NAME, 'remember')
    # b.staleness_(By.NAME,'remember')
    # b.fox.find_element(By.NAME,'remember').click()
    # b.element_selection_state(True,By.NAME,'remember')
    # headers = b.fox.current_window_handle
    # b.new_window([headers])
    from selenium.webdriver.common.action_chains import ActionChains
    b.fox.get('https://www.baidu.com')
    # 定位设置按钮
    res = b.fox.find_element_by_id('s-usersetting-top')
    # 鼠标悬停在设置的元素上
    ActionChains(b.fox).move_to_element(res).perform()
    # 点击搜索设置
    b.fox.find_element('class name', 'setpref').click()
    # 更换设置
    b.fox.find_element('id', 'nr_2').click()
    # 点击保存设置
    b.fox.find_element('link text', '保存设置').click()
    # 切换窗口
    a = b.alert_present()
    # 点击确定,确定与取消不能同时存在
    a.accept()

在这里还是要推荐下我自己建的软件测试学习Q群:746506216,群里都是学测试的,如果你想学或者正在学习测试,欢迎你加入,大家都是测试党,不定期分享干货(只有软件测试相关的),包括我自己整理的一份2022最新的Python自动化测试进阶资料和零基础教学,欢迎进阶中和对测试感兴趣的小伙伴加入!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐