大家都知道 UI 自动化最重要的就是页面元素的定位和操作
但是现在我们会发现元素越来越难定位了,前端可能会使用流行的 VUE 框架,页面控件元素经常没有 id、name 等属性,对我们定位产生了一定的困扰,需要我们灵活运用查找方式,去解决遇到的问题。
1.下面列举一些 Cypress 提供的定位方式
首先,它提供了 3 种专有的定位器,data-*属性,即使 CSS 或 js 改变也不会影响测试,看上去很美哈
data-cy、data-test、data-testid。(个人认为这种方式极少用到,想让前端给你加上这种属性会很难。。)
``` //例如为button添加一个data-*属性 <button id="main" class="btn" data-cy="submit">ddd</button> <button class="btn" data-test="submit">ddd</button> <button class="btn" data-testid="submit">ddd</button> //定位操作这个元素 cy.get("[data-cy=submit]").click() ```
还有 id 选择器、class 选择器、attributes 属性选择器、:nth-child(n)选择器、Cypress.$ 定位器
``` //用id定位 cy.get("#id的值") //用class定位 cy.get(".class的值") //用attributes 属性定位 cy.get("button[id='main']") //查找父元素的第几个子元素 cy.get(":nth-child(1)") cy.get(':nth-child(3) > .nav-menu-item-content') ```
Cypress 的 默认定位策略优先级
data-cy > data-test > data-testid > id > class > tag > attributes > nth-child
当然我们可以人为修改顺序,例如
```javascript Cypress.SelectorPlayground.defaults({ selectorPriority: ['class','id','attributes'] }) ```
2.查找元素的方法
常用基本方法有 .get()、.find()、.contains()
``` //在DOM树中查找对应元素 cy.get(':nth-child(3) > .nav-menu-item-content').click() //用来搜索对应包含文本的DOM元素,支持正则表达式 cy.contains('商品生成').click() //其中.find()不能直接使用cy.find() //find用来在被定位的元素的后代元素中,搜索并构造一个新的对象 cy.get('.ivu-select-dropdown.ivu-cascader-transfer').find('.ivu-cascader-menu-item').eq(0).click() ```
列举一部分辅助方法
.children()获取定位定位元素的子元素,无参数代表获取所有子元素,有参数则获取指定的子元素
``` cy.get(':nth-child(3) > .nav-menu-item-content').children() cy.get(':nth-child(3) > .nav-menu-item-content').children('#id') ```
.parents()获取定位元素的所有父元素。
.parent()获取定位元素的父元素
``` cy.get(':nth-child(3) > .nav-menu-item-content').parents() cy.get(':nth-child(3) > .nav-menu-item-content').parent() ```
.first()获取子元素集的第一个子元素
.last()获取子元素集的最后一个子元素
.next()获取定位元素的下一个同级元素
.nextAll()获取定位元素的所有下一个同级元素
.nextUntil()获取定位元素的所有下一个同级元素,直到找到 Until 里的元素
.prev()获取定位元素的上一个同级元素
.prevAll()获取定位元素的所有上一个同级元素
.prevUntil()获取定位元素的所有上一个同级元素,直到找到 Until 里的元素
.siblings()获取所有同级元素
.eq()按索引查找定位元素的子元素
``` //索引从0开始,eq(0)表示 cy.get('.ivu-select-dropdown.ivu-cascader-transfer').find('.ivu-cascader-menu-item').eq(0).click() ```
3.操作元素方法
.click()点击元素,可以带参数
``` cy.contains('商品生成').click() //强制点击元素 cy.contains('商品生成').click({force: true}) //点击元素右上角 cy.contains('商品生成').click({'topRight'}) //点击元素左上角 cy.contains('商品生成').click({'topLeft'}) //点击元素正上方 cy.contains('商品生成').click({'top'}) //点击元素右侧 cy.contains('商品生成').click({'right'}) //点击元素中间 cy.contains('商品生成').click({'center'}) //点击元素左侧 cy.contains('商品生成').click({'left'}) //点击元素右下角 cy.contains('商品生成').click({'bottomRight'}) //点击元素左下角 cy.contains('商品生成').click({'bottomLeft'}) //点击元素正下 cy.contains('商品生成').click({'bottom'}) ```
.dblclick()双击元素
.rightclick()右击元素
.type()在输入框输入文本
.clear()清除输入的文本值或已有文本
``` cy.get('input[type=text]').clear() cy.get('input[type=text]').type('123456') ```
如果我们需要操作单选框或复选框,使用 .check(),取消勾选用 .uncheck()
``` <input type="radio" class="ivu-radio-input" name="ivuRadioGroup_1591061954307_27" value="accept"> //选中一个 cy.get('input[type="radio"]').check() //如果有属性value,则可以通过value的值选中/取消,一个或多个 cy.get('input[type="radio"]').check('accept') cy.get('input[type="radio"]').check(['accept','另一个值']) cy.get('input[type="radio"]').uncheck('accept') cy.get('input[type="radio"]').uncheck(['accept','另一个值']) ```
如果我们要操作 select
``` <select multiple> <option value="456">apples</option> <option value="457">oranges</option> <option value="458">bananas</option> </select> //拿文本和拿value的值效果一样 cy.get('select').select(['apples', 'bananas']) cy.get('select').select(['456', '458']) ```
触发事件,更多可以去官网查询这里不再一一列举
``` //移动光标到目标元素上 cy.get('button').trigger('mouseover') ```
4.导航相关方法
cy.go() 利用浏览器缓存访问上一页或下一页
``` //后退 cy.go('back') //下一页、前进 cy.go('forward') //通过数字控制1前进 -1后退 cy.go(-1) cy.go(1) ```
cy.reload() 刷新页面
cy.reload(true) 强制刷新页面
cy.visit() 访问网址
``` cy.visit('https://www.fewords.cn/') ```
cy.url() 获取当前页面 URL
另 我们可以设置窗口大小 cypress.json 设置如下