python与selenium_强制等待、隐性等待、显性等待

结合项目说下三种等待:

第一、先建立一个概念代码有多快?
用例是登录环境,进入界面,点击上传。这一套在我们眼里看来还不得个5秒左右,但是代码0.05秒就已经跑到了点击上传了。然后代码在等页面加载。
第二,说下龟兔赛跑的故事,
龟是页面加载(页面有的地方有很多js脚本,加载起来很慢的,有的地方很快),兔是代码。预备跑:页面加载刚走了一步,代码已经到终点了。有的地方代码要想执行下一步:必须等页面加载出来才能继续。等太久,代码就抛了个异常。

1、隐性等待(代码等的是:你要点击元素所在的整个页面完全加载)
【项目里,只需要在我们封装的setup方法里写一次即可,作用是全局的】

# coding=utf-8
import unittest
from selenium import webdriver
from Common.function import config_url

#  cls.driver.implicitly_wait(10):代码等整个页面加载完成,一加载出来就过,一加载出来就过。等10秒,还不出来,抛出异常
class UnitBase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome()
        cls.driver.get(config_url())
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(10)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()

2、显性等待(代码等的是:你要点击的元素能被点击,title出来没、frame加载没,text出来了没等,)
直接看源码的翻译吧,紧接着就是经验之谈,后续慢慢补充吧

WebDriverWait(self.driver,20,0.5).until(EC.element_to_be_clickable(By.XPATH,'[]'))
# 代码每隔0.5秒查一次页面元素能不能被点击,如果能被点击,则继续,如果假,超过20秒,则抛出TimeoutException。

项目里关于显性等待都是直接封装到基础操作Base类里面,项目代码如下:

# --*--coding=utf-8--*--
from selenium.webdriver.support.select import Select
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.webdriver.common.action_chains import ActionChains


class Base:
    """这里封装了操作浏览器的基础操作
        """

    def __init__(self, driver, log):
        self.driver = driver

    def id(self, element):
        return self.driver.find_element_by_id(element)

    def findele(self, *element):
        """压包,和解包,示例:findele(By.Id, "xxx")
            """
        return self.driver.find_element(*element)

    def findeles(self, *element):
        """压包,和解包,例如findele(By.Id, "xxx"),返回是一个许多个元素
        """
        return self.driver.find_elements(*element)

    def clear(self, *element):
        # 清空要输入的内容,一般用于输入前置
        return self.driver.findele(*element).clear()
        
    def click(self, *element):
        """点击元素,示例:click(By.Xpath, '[xxx]')
            """
        return self.driver.findele(*element).click()

    def sendkey(self, value, *element):
        """给输入框发送内容,示例:sendkey("tfjiao", By.Xpath, '[xxx]')
            """
        self.findele(*element).send_keys(value)



    # 鼠标的一些操作
    def move_offset_click(self, canvas, *element):
        """
        移动到画布这个元素上,移动到某个位置点,并进行点击 >>> 用于画布桑画形状
        示例:move_offset_click(By.Xpath, '[xxx]', 200, 300)
        200是x坐标,300是y坐标。具体参考move_by_offset的源码
        """
        return ActionChains(self.driver).move_to_element(canvas).move_by_offset(*element).release().click().perform()

    def move_offset_click_double(self, canvas, *elenment):
        """移动到画布这个元素上,移动到某个位置点,并进行双击,跟move_offset_click方法类似 >>> 用于画布上双击结束绘画
            """
        return ActionChains(self.driver).move_to_element(canvas).move_by_offset(*elenment).release().double_click().perform()

    def move_element_click(self, *element):
        """移动到元素上,并点击。示例:move_element_click(By.Xpath, '[xxx]')
            """
        return ActionChains(self.driver).move_to_element(self.findele(*element)).release().click().perform()

    def move_element_offset_click(self, xoffset, yoffset, *element):
        """移动到元素的左侧位置,示例:move_element_offset_click(100, 200, By.Id, "xxx")
            """
        return ActionChains(self.driver).move_to_element(self.findele(*element), xoffset, yoffset).click().perform()


    # 下拉框操作的封装
    def select_value(self, id, value):
        """
        选择下拉框的元素,id是下拉框的id值,value是下拉框元素的value属性值
        注意:下拉框有时候开发会把display设置为none,这里需要js脚本打开改变属性值,后续js脚本会说到
        """
        return Select(self.findele(By.ID, id)).select_by_value(value)

    def select_text(self, id, text):
        """
        选择下拉框的元素,id是下拉框的id,text是下拉框元素显示在页面的内容
        注意:下拉框有时候开发会把display设置为none,需要js脚本处理
        """
        return Select(self.findele(By.ID, id)).select_by_visible_text(text)

    def select_index(self, id, index):
        """
        选择下拉框的元素,id是下拉框的id,index是索引值,从0开始
        注意:下拉框有时候开发会把display设置为none,需要js脚本处理
        """
        return Select(self.findele(By.ID, id)).select_by_index(index)


    # js语法的封装
    def js(self):
        """
        关于js的用法,document.querySelectorAll('css语法')基本满足了所有需要
        selenium_js定位详解:https://blog.csdn.net/weixin_45451320/article/details/115104455
        selenium_css定位详解:https://blog.csdn.net/weixin_45451320/article/details/115101192
        """
        return self.driver.execute_script('document.querySelectorAll("css语法")[1].click()')

    def js(self, str):
        return self.driver.execute_script(str)

    def click_js(self, *element):
        """
        js语法点击
        """
        return self.driver.execute_script("argument[0].click();", self.findele(*element))


    # 显性等待的封装
    def switchframe(self, element):
        """
        切换框架
        """
        return self.driver.switch_to.frame(element)

    def wait_click(self, *element):
        """
        每0.5秒检查一次元素,元素能被点击,则执行。
        示例:wait_click(By.Xpath, '[xxx]')
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.element_to_be_clickable(element))

    def wait_visibility(self, *element):
        """
        检查元素是否存在于页面和可见。可见性意味着不仅显示元素,但其高度和宽度也大于0。定位器-用于查找元素,
        一旦WebElement定位并可见,返回它
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.visibility_of_element_located(element))

    def wait_alert(self,*element):
        """
        检查是否有弹窗出现
        如果点击某个操作有弹框,用这个更快。
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.alert_is_present(element))

    def wait_title(self,*element):
        """
        检查标题是否包含区分大小写的子字符串。title是期望的title片段,当标题匹配时返回True,否则返回False
        切换浏览器界面的title时候带上这个,会更快。
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.title_contains(element))

    def wait_frame(self, *element):
        """
        期望检查给定帧是否可用于,切换到。 如果框架可用,则将给定的驱动程序切换到指定的帧。
        切换框架时候,用它更快。
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.frame_to_be_available_and_switch_to_it(element))

    def wait_text_present(self,text, *element):
        """
        期望检查给定文本是否存在于指定的元素。
        示例:wait_text_present(“xxx”, By.Id, "xxx")
        场景:用于检查text
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.text_to_be_present_in_element(element, text))

    def wait_selected(self, *element):
        """
        选择检查选择的期望。元素是WebElement对象
        """
        return WebDriverWait(self.driver, 20, 0.5).until(EC.element_to_be_selected(self.findele(element)))

    def displayed(self, *element):
        """
        检查元素是否可见,可见则通过
        """
        return self.driver.findele(*element).is_displayed()

    def enabled(self, *element):
        return self.driver.findele(*element).is_enabled()

    def url(self):
        return self.driver.current_url

    def back(self):
        self.driver.back()

    def forward(self):
        self.driver.forward()

    def quit(self):
        self.driver.quit()

3、强制等待

没啥说的,导入time模块,在你实在没法用显性等待解决,再用time.sleep(10),让它在这块强制等个10秒。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿_焦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值