所以另外更好的解决方法则是Xpath的复合条件定位,比如下面的代码,先选择class为ant-modal-root的div,然后找到它下面class为ant-modal-wrap并且style属性不含有none关键字的div,再找到该div下面按钮文本为确定的按钮

//div[@class="ant-modal-root"]/div[(@class="ant-modal-wrap") and not(contains(@style,"none"))]//button/span[text()="确 定"]

这样就不会因为弹窗层级变化导致定位失败的原因了,还达到了元素地址复用性的目的(两个弹窗共用一个Xpath元素地址)。


但如果有子弹窗的情况下,上面的写法又会失效:

airtest通过坐标点击_airtest通过坐标点击


分析上述DOM元素会发现,图片中的两个弹窗无法再通过style中是否存在none来区分了,因为他们都可见,并且分析发现只有aria-labelledby的值不一样:

airtest通过坐标点击_airtest通过坐标点击_02


我们当然可以根据不同的属性,例如上述弹窗的标题不同来区分他们,但这样每个弹窗中的按钮就都需要写一次不同的元素地址。如果为了复用性考虑,我写了如下的代码来实现:

elements=driver.find_elements(
    By.XPATH,'//div[@class="ant-modal-root"]/div[(@class="ant-modal-wrap") and not(contains(@style,'
             '"none"))]//button/span[text()="确 定"]')
 for ele in elements:
        if ele.is_displayed():
            if ele.is_enabled():
                try:
                    ele.click()
                except ElementClickInterceptedException:
                    pass

先获取可见的【确定】按钮对象,然后遍历点击,如果点击报错的话就跳过 (报错是因为有遮罩挡住就会报错,只有页面最前的元素会可点击,刚好达到我们的目的),达到了一个元素地址三个【弹窗】的复用。

但即便这样,同样存在着下面这些不足:

  1. DOM结构如果很大,执行会变慢,性能损耗;
  2. 为了复用性会有更多的代码逻辑判断,性能损耗;
  3. 页面代码发生修改可能需要重新定位元素,修改脚本或用例;
  4. 编写脚本或用例时,需要去分析DOM结构,调试代码,增加时间成本;
  5. 有iframe和多页面时需要单独切换;
  6. 有一定的学习成本;

这样分析下来,维护成本依然不低!那有没有解决方案呢?

肯定是有的,不然我也不会写这篇文章了!


二、解决方案

1. 讲解与演示

我们可以使用图像匹配来定位它,比如网易团队开源的airtest,类似于上述弹窗嵌套有多个【确定】按钮的情况,我们只需要截取一张【确定】按钮的图片,就能解决无数重复的确定按钮的定位了!哪怕页面代码进行了调整,只要你的按钮样式不变,还是原来的按钮的样子,也无须重新调整脚本和代码了!


这是我通过图像匹配的执行效果:

airtest通过坐标点击_airtest通过坐标点击_03


两个【确定】按钮完全共用的是一张图片


2. 实践教学

现在跟着我一起从0开始利用airtest写一个简单的图像识别测试脚本吧

需求

编写一个程序,它会通过图像识别执行点击百度的【新闻】,然后点击【互联网】这两步操作


具体步骤

1.先安装airtest

pip install airtest -i https://pypi.tuna.tsinghua.edu.cn/simple


2.创建一个项目,并输入如下代码:

from airtest.core.api import \*

news_path = 'news.png'
internet_path = 'internet.png'
connect_device('Windows:///')
ST.CVSTRATEGY = ["surf", "tpl"]
ST.FIND_TIMEOUT = 2
touch(Template(news_path))
touch(Template(internet_path))

3.先打开百度截取【新闻】图片,再点击新闻,截取【互联网】图片:

airtest通过坐标点击_javascript_04


截取的图片如下,命令为news.png并保存到代码所在目录

airtest通过坐标点击_Web_05


airtest通过坐标点击_自动化_06


截取的图片如下,命令为internet.png并保存到代码所在目录

airtest通过坐标点击_Web_07


4.检查目录文件命名是否与代码中一致

airtest通过坐标点击_airtest通过坐标点击_08


5.让浏览器保持百度访问

airtest通过坐标点击_自动化_09


6.执行代码然后马上切换回浏览器,执行效果如下:

airtest通过坐标点击_Web_10