当前位置: 首页 > news >正文

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秒。

相关文章:

  • python_日志相关
  • jenkins总结1 - 安装、git、allure、email插件配置
  • pytest框架_简介、pytest.main()
  • pytest框架_@pytest.fixture()
  • pytest框架_@pytest.mark.usefixtures()
  • pytest框架_conftest.py详解
  • pytest框架_@pytest.mark.parametrize()
  • pytest框架_@pytest.yield_fixture()
  • pytest框架_@pytest.mark.xfail()
  • pytest框架_@pytest.mark.skipif()
  • pytest框架_pytest.ini
  • pytest框架_测试报告(allure-pytest)
  • pytest框架_pytest_runtest_makereport实现失败截图自动加入allure
  • pytest框架_assert断言
  • python_获取共享文件里的内容
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • happypack两次报错的问题
  • MySQL-事务管理(基础)
  • SSH 免密登录
  • 分类模型——Logistics Regression
  • 前端存储 - localStorage
  • 前端路由实现-history
  • 少走弯路,给Java 1~5 年程序员的建议
  • 使用docker-compose进行多节点部署
  • 使用权重正则化较少模型过拟合
  • 再谈express与koa的对比
  • 第二十章:异步和文件I/O.(二十三)
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (6)STL算法之转换
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (第二周)效能测试
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • .Net Winform开发笔记(一)
  • .Net7 环境安装配置
  • .NET开发者必备的11款免费工具
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • @test注解_Spring 自定义注解你了解过吗?
  • [ 数据结构 - C++] AVL树原理及实现
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [COI2007] Sabor
  • [C语言]——分支和循环(4)
  • [DEBUG] spring boot-如何处理链接中的空格等特殊字符
  • [IE编程] 如何编程清除IE缓存
  • [Java][算法 双指针]Day 02---LeetCode 热题 100---04~07
  • [Java]快速入门优先队列(堆)手撕相关面试题