一、元素定位方式
selenium中定位元素,通常有几种方式:
1、通过id定位:By.ID
2、通过Name定位:By.Name
3、通过元素其他属性定位,如class、type、text文本。。。。。。等等,如果要用属性定位那就需要使用Xpath或css定位器方式;本文主要介绍
By.XPATH定位
二、Xpath定位要素
xpath定位需要搞清楚xpath的原理;
xpath是通过给定的xpath路径,扫描整个页面dom结构,从而匹配到复合条件的元素,并进行操作;
xpath通常有2中方式,绝对路径和相对路径;市面上一些浏览器插件通常生成的都是绝对路径,优点是简单,无需搞懂xpath规则,小白使用;缺点是不灵活,dom结构稍有变化,xpath就会失效导致找不到元素;所以我们做ui自动化,必须搞懂xpath,采用相对路径方式;
通常有如下要素:
-
- 定位模式:绝对地址或相对地址
- 定位元素类型:input、div、a。。。。。。 符合dom的所有元素
- 元素属性:id、name、class、text。。。。。。符合dom规范的所有属性
- 元素相对位置:父级、子级、兄弟、前、后等等;在xpath中叫轴;
- 元素属性关系符:等于、包含、或者、不等于、不包含
三、定位实例讲解
案例一:
使用的方法:class定位、descendant孩子、最后一个last()
需要展开最大的层级,而且这个层级会变化,不同租户有不同层级,那么就不能写死点击2;
我们就需要点击最大的数字,怎么办?
先研究dom结构
我们发现,如果多一个层级在ul元素下就多一个li元素;那么我们可以获取最后一个li不就是最大的层级吗
chrome浏览器中调试;浏览器Console窗口可以调试xpath,格式:$x(xpath)
三步实现,先找到li的父级,再找到旗下所有li,最后取最后一个li即可
先找到li的父级://ul[@class='el-dropdown-menu el-popper']
再找到旗下所有li(孩子):descendant::li[@class='el-dropdown-menu__item']
最后一个孩子:[last()]
"//ul[@class='el-dropdown-menu el-popper']/descendant::li[@class='el-dropdown-menu__item'][last()]"
案例二、
使用方式:class、text、其他属性、descendant、and、or
需要获得所有末级项目,公司和项目随时会增加,所以不能用公司和项目名过滤,怎么办?
我们先观察dom结构的属性
通过观察我们发现:
1、即将到期列表是一个div下嵌套的table;
2、每一行记录是一个tr
3、公司的data-level=0,也有区域公司的data-level=0,末级公司=1;
4、项目的data-level=1或者2;
实现:
1、找到table列表,因为页面上列表较多,所以需要确定父级div再往下找table
//div[@id = 'appForm_Sub_subTreeGrid_ProjAuthDTO_ContainerGUID_TreeGrid_ViewContainer']/descendant::div[@class='mini-grid-rows-view']/descendant::table[@class='mini-grid-table']
2、找到table下级别为1和2的tr,但是里面可能会包含存在区域公司下的末级公司
/descendant::tr[(@data-level = 1 or @data-level = 2)
3、需要将末级公司过滤掉,我们发现只有项目才会有“即将到期”的text,所以用文本过滤
and descendant::span[text()='即将到期']
"//div[@id = 'appForm_Sub_subTreeGrid_ProjAuthDTO_ContainerGUID_TreeGrid_ViewContainer']/descendant::div[@class='mini-grid-rows-view']/descendant::table[@class='mini-grid-table']/descendant::tr[(@data-level = 1 or @data-level = 2) and descendant::span[text()='即将到期']] "
xpath 博大精深,有各种巧妙的实现方式,关键是要找到dom结构的规律和逻辑,通过更加合理的方式去找到复合自己需要的元素;
后期会逐步介绍css定位器,相比xpath效率会高一些;