WEB自动化-05-Cypress-元素交互
5 元素交互
元素识别和操作是UI自动化测试的基础,下面一起来学习一下在Cypress中的元素交互操作吧。
5.1 元素定位器选择
每一个测试用例都包含对元素的定位识别和操作等。因为一个好的测试用例,必须保证健壮和可靠的元素定位策略。在实际项目中,经常会遇到以下问题:
- 元素ID或类是动态生成
- 若使用CSS定位,而在实际开发过程中CSS或JS行为发生更改等
为避免出现以上失败情况,我们可以采取以下策略
- 不建议使用基于CSS属性的定位方式,如id, class, tag
- 不建议使用基于易发生变化的文本内容
- 添加data-*属性,使其更加容易定位元素
Cypress提供三个data-*属性,分别是data-cy、data-test、data-testid
我们来看一个示例:
<button
id="main"
class="btn btn-large"
name="submission"
role="button"
data-cy="submit"
>
Submit
</button>
我们来看看以下几种常见的元素定位方式:
定位方式 | 是否推荐 | 备注 |
---|---|---|
cy.get('button').click() | 不推荐 | 错误的定位方式,太简单,没有结合上下文 |
cy.get('.btn.btn-large').click() | 不推荐 | CSS耦合性太高 |
cy.get('#main').click() | 慎用 | 仍然依赖于CSS或JS事件(JS可以动态生成button) |
cy.get('[name=submission]').click() | 慎用 | 与HTML中name属性耦合性太高 |
cy.contains('Submit').click() | 可以使用 | 与文本内容耦合性比较高,若文本发生变化,则失败 |
cy.get('[data-cy=submit]').click() | 推荐 | 不依赖任何变更 |
data-*是Cypress提供的专有定位器,仅用于定位。且 data-*属性与元素的行为或样式无关,也就意味着即样式和行为发生变化,也不影响测试而出现失败的情况产生。更详细的文档可以查看官网介绍:https://docs.cypress.io/guides/references/best-practices#Selecting-Elements
除了Cypress专有定位选择器外,在不满足data-*选择器时,也可以使用以下几种定位选择器:
- 1、id选择器
cy.get('#main').click()
- 2、class选择器
cy.get('.btn.btn-large').click()
- 3、attributes选择器
cy.get('[name=submission]').click()
- 4、:nth-child(n)选择器
:nth-child(n)选择器匹配属于其属于父元素的第n个子元素且不管元素类型。
<form method="post" action="/post">
<p>Customer name: <input name="custname"></p>
<p>Telephone: <input type="tel" name="custtel"></p>
<p>E-mail address: <input type="email" name="custemail"></p>
<p>Delivery instructions: <textarea name="comments"></textarea></p>
<p><button>Submit order</button></p>
</form>
针对以上HTML代码片断使用nth-child(n)选择器定位代码如下所示:
cy.get('p:nth-child(1) > input').type("Surpass")
- 5、Cypress.$ 选择器
针对一些比较难定位的元素,Cypress也可以使用jQuery选择器来进行元素定位,示例代码如下所示:
/// <reference types="cypress" />
describe('测试jQuery定位器', () => {
let baseUrl="https://www.baidu.com/";
before(()=>{
cy.visit(baseUrl);
});
it('测试jQuery定位器用例-1', () => {
let searchTextA="I love",searchTextB=" Surpass",searchButtonText="百度一下";
cy.get("#kw").type(searchTextA).should("contain.value",searchTextA);
let $el=Cypress.$("#kw")
let selectorA=Cypress.SelectorPlayground.getSelector($el)
cy.get(selectorA).type(searchTextB).should("contain.value",searchTextB)
cy.get(selectorA).clear();
let $elSearch=Cypress.$("#su")
let selectorB=Cypress.SelectorPlayground.getSelector($elSearch);
cy.get(selectorB).should("contain.value",searchButtonText);
});
});
使用Cypress.$定位参考资料:https://docs.cypress.io/api/cypress-api/selector-playground-api#onElement-Callback
5.2 DOM交互
5.2.1 页面元素查找
5.2.1.1 基本方法
在Cypress常见的用于页面内元素查找的方法如下所示:
5.2.1.1.1 find方法
find主要用于查找DOM 树中被定位元素的后代,其基本语法如下所示:
.find(selector)
.find(selector, options)
示例HTML片断如下所示:
<ul id="parent">
<li class="first"></li>
<li class="second"></li>
</ul>
其用法如下所示:
cy.get('#parent').find('li')
5.2.1.1.2 get方法
get主要用于查找一个或多个DOM元素,其基本语法如下所示:
cy.get(selector)
cy.get(alias)
cy.get(selector, options)
cy.get(alias, options)
其用法如下所示:
// 查找input元素
cy.get('input').should('be.disabled')
// 查找li的第一个元素且属于ul的后代
cy.get('ul li:first').should('have.class', 'active')
// 查找dropdown-menu元素并单击
cy.get('.dropdown-menu').click()
// 查找属性为test-example的元素
cy.get('[data-test-id="test-example"]').should('have.length', 5)
// 查找href属性中包含questions的元素
cy.get('a[href*="questions"]').click()
// 支持正则,查找以local-开头的元素
cy.get('[id^=local-]')
// 支持正则,查找以-remote结尾的元素
cy.get('[id$=-remote]')
// 支持正则,查找以local-开头和以-remote结尾的元素
cy.get('[id^=local-][id$=-remote]')
5.2.1.1.3 contains方法
contains主要用于查找包含特定文本的元素,其基本语法如下所示:
.contains(content)
.contains(content, options)
.contains(selector, content)
.contains(selector, content, options)
// ---or---
cy.contains(content)
cy.contains(content, options)
cy.contains(selector, content)
cy.contains(selector, content, options)
- content
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
</ul>
其用法如下所示:
// 查找搜索到的第一个包含apples的元素
cy.contains('apples')
- value
示例HTML片断如下所示:
<div id="main">
<form>
<div>
<label>name</label>
<input name="name" />
</div>
<div>
<label>age</label>
<input name="age" />
</div>
<input type="submit" value="submit the form!" />
</form>
</div>
其用法如下所示:
cy.get('form').contains('submit the form!').click()
- Number
示例HTML片断如下所示:
<button class="btn btn-primary" type="button">
Messages <span class="badge">4</span>
</button>
其用法如下所示:
// 查找搜索到的第一个元素包含的数值
cy.contains(4)
- 正则
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
</ul>
其用法如下所示:
// 查找搜索<li>bananas</li>
cy.contains(/^b\w+/)
- selector
示例HTML片断如下所示:
<html>
<body>
<ul>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
</ul>
</body>
</html>
其用法如下所示:
// 查找搜索<ul>...</ul>
cy.contains('ul', 'apples')
- subject
示例HTML片断如下所示:
<form>
<div>
<label>name</label>
<input name="name" />
</div>
<button type="submit">Proceed</button>
</form>
其用法如下所示:
cy.get('form') // 查找搜索 <form>...</form>
.contains('form', 'Proceed') // 查找搜索 <form>...</form>
.submit() // 查找搜索 <form>...</form>
- options
示例HTML片断如下所示:
<div>Capital Sentence</div>
其用法如下所示:
cy.get('div').contains('capital sentence') // fail
cy.get('div').contains('capital sentence', { matchCase: false }) // pass
5.2.1.2 扩展方法
因WEB技术不断更新发展,导致其应用程序也不断变得复杂,单一手机的定位方法可能满足不了要求,Cypress也提供一些扩展方法,用于更加精准定位元素。如下所示:
5.2.1.2.1 children方法
children用于获取指定DOM集合页面中每个DOM的子元素,其基本语法如下所示:
.children()
.children(selector)
.children(options)
.children(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li>About</li>
<li>
Services
<ul class="secondary-nav">
<li class="services-1">Web Design</li>
<li class="services-2">Logo Design</li>
<li class="services-3">
Print Design
<ul class="tertiary-nav">
<li>Signage</li>
<li>T-Shirt</li>
<li>Business Cards</li>
</ul>
</li>
</ul>
</li>
<li>Contact</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 [
// <li class="services-1">Web Design</li>,
// <li class="services-2">Logo Design</li>,
// <li class="services-3">Print Design</li>
// ]
cy.get('ul.secondary-nav').children()
- selector
示例HTML片断如下所示:
<div>
<ul>
<li class="active">Unit Testing</li>
<li>Integration Testing</li>
</ul>
</div>
其用法如下所示:
// 查找搜索到的结果为[ <li class="active">Unit Testing</li> ]
cy.get('ul').children('.active')
5.2.1.2.2 parents方法
parents用于获取指定DOM集合页面中每个DOM的父元素,即以当元素为起点,一直到最顶级,其基本语法如下所示:
.parents()
.parents(selector)
.parents(options)
.parents(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul class="main-nav">
<li>Overview</li>
<li>
Getting started
<ul class="sub-nav">
<li>Install</li>
<li class="active">Build</li>
<li>Test</li>
</ul>
</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 [.sub-nav, li, .main-nav]
cy.get('li.active').parents()
- selector
示例HTML片断如下所示:
<ul class="main-nav">
<li>Overview</li>
<li>
Getting started
<ul class="sub-nav">
<li>Install</li>
<li class="active">Build</li>
<li>Test</li>
</ul>
</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为[.main-nav]
cy.get('li.active').parents('.main-nav')
5.2.1.2.3 parent方法
parent用于获取指定DOM集合页面中每个DOM的第一层父元素即以当元素为起点,仅向上找一级(即找到爸爸辈即可),其基本语法如下所示:
.parent()
.parent(selector)
.parent(options)
.parent(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul class="main-nav">
<li>Overview</li>
<li>
Getting started
<ul class="sub-nav">
<li>Install</li>
<li class="active">Build</li>
<li>Test</li>
</ul>
</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 .sub-nav
cy.get('li.active').parent()
- selector
示例HTML片断如下所示:
<ul class="main-nav">
<li>Overview</li>
<li>
Getting started
<ul class="sub-nav">
<li>Install</li>
<li class="active">Build</li>
<li>Test</li>
</ul>
</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为.sub-nav
cy.get('li').parent('.sub-nav')
5.2.1.2.4 siblings方法
siblings用于获取指定DOM页面中同层级元素即以当元素为起点,查找同级别元素(即找到兄弟辈即可),其基本语法如下所示:
.siblings()
.siblings(selector)
.siblings(options)
.siblings(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li>Home</li>
<li>Contact</li>
<li class="active">Services</li>
<li>Price</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为[<li>Home</li> <li>Contact</li> <li>Price</li> ]
cy.get('.active').siblings()
- selector
示例HTML片断如下所示:
<ul>
<li>Home</li>
<li>Contact</li>
<li class="active">Services</li>
<li>Price</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为<li class="active">Services</li>
cy.get('li').siblings('.active')
5.2.1.2.5 first方法
first用于获取指定DOM页面中第一个元素,其基本语法如下所示:
.first()
.first(options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li class="one">Knick knack on my thumb</li>
<li class="two">Knick knack on my shoe</li>
<li class="three">Knick knack on my knee</li>
<li class="four">Knick knack on my door</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为<li class="one">Knick knack on my thumb</li>
cy.get('li').first()
5.2.1.2.6 last方法
last用于获取指定DOM页面中最后一个元素,其基本语法如下所示:
.last()
.last(options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li class="one">Knick knack on my thumb</li>
<li class="two">Knick knack on my shoe</li>
<li class="three">Knick knack on my knee</li>
<li class="four">Knick knack on my door</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为<li class="four">Knick knack on my door</li>
cy.get('li').last()
5.2.1.2.7 next方法
next用于获取指定DOM页面中同层级元素的下一个元素,即以当前元素为起点,向下查找一个元素,其基本语法如下所示:
.next()
.next(selector)
.next(options)
.next(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li class="second">oranges</li>
<li>bananas</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为<li>bananas</li>
cy.get('.second').next()
来看看以下的示例验证程序看看会不会被绕晕,哈哈,如下所示:
<input list="fruit" />
<datalist id="fruit">
<option>Apple</option>
<option>Banana</option>
<option>Cantaloupe</option>
</datalist>
cy.get('#fruit option')
.first()
.should('have.text', 'Apple')
.next()
.should('have.text', 'Banana')
.next()
.should('have.text', 'Cantaloupe')
- selector
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
<li class="selected">pineapples</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为<li>pineapples</li>
cy.get('li').next('.selected')
5.2.1.2.8 nextAll方法
nextAll用于获取指定DOM页面中匹配元素后的所有同层级元素,即以当前元素为起点,查找后续所有同层级元素,其基本语法如下所示:
.nextAll()
.nextAll(selector)
.nextAll(options)
.nextAll(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li class="second">oranges</li>
<li>bananas</li>
<li>pineapples</li>
<li>grapes</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为[<li>bananas</li>, <li>pineapples</li>, <li>grapes</li>]
cy.get('.second').nextAll()
- selector
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
<li class="selected">pineapples</li>
<li>grapes</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 <li>pineapples</li>
cy.get('li').nextAll('.selected')
5.2.1.2.9 nextUntil方法
nextUntil用于获取指定DOM页面中指定范围内的所有同层级元素,即以当前元素为起点,向后查找,遇到until指定的元素截止前的所有同层级元素,其基本语法如下所示:
.nextUntil(selector)
.nextUntil(selector, filter)
.nextUntil(selector, filter, options)
.nextUntil(element)
.nextUntil(element, filter)
.nextUntil(element, filter, options)
- selector
示例HTML片断如下所示:
<ul>
<li id="fruits" class="header">Fruits</li>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
<li id="veggies" class="header">Vegetables</li>
<li>cucumbers</li>
<li>carrots</li>
<li>corn</li>
<li id="nuts" class="header">Nuts</li>
<li>walnuts</li>
<li>cashews</li>
<li>almonds</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 [<li>cucumbers</li>, <li>carrots</li>, <li>corn</li>]
cy.get('#veggies').nextUntil('#nuts')
5.2.1.2.10 prev方法
prev用于获取指定DOM页面中同层级元素的上一个元素,即以当前元素为起点,向上查找一个元素,其基本语法如下所示:
.prev()
.prev(selector)
.prev(options)
.prev(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li>Cockatiels</li>
<li>Lorikeets</li>
<li class="active">Cockatoos</li>
<li>Conures</li>
<li>Eclectus</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为<li>Lorikeets</li>
cy.get('.active').prev()
示例HTML片断如下所示:
<ul>
<li>Cockatiels</li>
<li>Lorikeets</li>
<li class="active">Cockatoos</li>
<li>Conures</li>
<li>Eclectus</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 <li>Cockatoos</li>
cy.get('li').prev('.active')
5.2.1.2.11 prevAll方法
prevAll用于获取指定DOM页面中匹配元素前的所有同层级元素,即以当前元素为起点,查找前面所有同层级元素,其基本语法如下所示:
.prevAll()
.prevAll(selector)
.prevAll(options)
.prevAll(selector, options)
- 不带参数
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li>oranges</li>
<li class="third">bananas</li>
<li>pineapples</li>
<li>grapes</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 [<li>apples</li>, <li>oranges</li>]
cy.get('.third').prevAll()
- selector
示例HTML片断如下所示:
<ul>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
<li class="selected">pineapples</li>
<li>grapes</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为 <li>pineapples</li>
cy.get('li').prevAll('.selected')
prevAll查找前面所有同级元素,但如果添加了selector,则代表仅选择一个
5.2.1.2.12 prevUntil方法
prevUntil用于获取指定DOM页面中指定范围内的所有同层级元素,即以当前元素为起点,向前查找,遇到until指定的元素截止前的所有同层级元素,其基本语法如下所示:
.prevUntil(selector)
.prevUntil(selector, filter)
.prevUntil(selector, filter, options)
.prevUntil(element)
.prevUntil(element, filter)
.prevUntil(element, filter, options)
- selector
示例HTML片断如下所示:
<ul>
<li id="fruits" class="header">Fruits</li>
<li>apples</li>
<li>oranges</li>
<li>bananas</li>
<li id="veggies" class="header">Vegetables</li>
<li>cucumbers</li>
<li>carrots</li>
<li>corn</li>
<li id="nuts" class="header">Nuts</li>
<li>walnuts</li>
<li>cashews</li>
<li>almonds</li>
</ul>
其用法如下所示:
// 查找搜索到的结果为[<li>cucumbers</li>, <li>carrots</li>, <li>corn</li>]
cy.get('#nuts').prevUntil('#veggies')
5.2.1.2.13 each方法
each用于遍历带有length属性的对象,如数组等,其基本语法如下所示:
.each(callbackFn)
其用法如下所示:
// 遍历每个li
cy.get('ul>li').each(() => {...})
cy.get('li')
.should('have.length', 3)
.each(($li, index, $lis) => {
return 'something else'
})
.then(($lis) => {
expect($lis).to.have.length(3) // true
})
5.2.1.2.14 eq方法
eq用于获取指定索引的元素(类似于nth-child(n)),其基本语法如下所示:
.eq(index)
.eq(indexFromEnd)
.eq(index, options)
.eq(indexFromEnd, options)
- 正向index
示例HTML片断如下所示:
<ul>
<li>tabby</li>
<li>siamese</li>
<li>persian</li>
<li>sphynx</li>
<li>burmese</li>
</ul>
其用法如下所示:
cy.get('li').eq(1).should('contain', 'siamese') // true
索引起始值为0
- 反向index
示例HTML片断如下所示:
<ul>
<li>tabby</li>
<li>siamese</li>
<li>persian</li>
<li>sphynx</li>
<li>burmese</li>
</ul>
其用法如下所示:
cy.get('li').eq(-2).should('contain', 'sphynx') // true
5.2.1.2.15 filter方法
filter用于获取匹配到的元素,其基本语法如下所示:
.filter(selector)
.filter(selector, options)
- **selector*
示例HTML片断如下所示:
<ul>
<li>Home</li>
<li class="active">About</li>
<li>Services</li>
<li>Pricing</li>
<li>Contact</li>
</ul>
其用法如下所示:
// 搜索到的结果为: <li>About</li>
cy.get('ul').find('>li').filter('.active')
- contains-按文本
示例HTML片断如下所示:
<ul>
<li>Home</li>
<li>Services</li>
<li>Advanced Services</li>
<li>Pricing</li>
<li>Contact</li>
</ul>
其用法如下所示:
// 搜索到的结果为(包含Services的元素): <li>Services</li> <li>Advanced Services</li>
cy.get('li').filter(':contains("Services")').should('have.length', 2)
- contains-非空格
示例HTML片断如下所示:
<div data-testid="testattr">
<span>Hello world</span>
</div>
其用法如下所示:
cy.get('[data-testid=testattr]').filter(':contains("Hello\u00a0world")')
5.3 可操作类型
5.3.1 click方法
click主要用于单击元素,其基本语法如下所示:
.click()
.click(options)
.click(position)
.click(position, options)
.click(x, y)
.click(x, y, options)
option常见参数如下所示:
- position(String)
center是postion的默认位置,其他有效postion有:topLeft、top、topRight、left、center、right、bottomLeft、bottom、bottomRight,其示意图如下所示:
- x(Number)
元素离左边(left)的距离,单位为像素
- y(Number)
元素离上面(top)的距离,单位为像素
- options(Object)
选项 | 默认值 | 备注 |
---|---|---|
altKey | false | 是否激活Alt键,别名为:optionKey |
ctrlKey | false | 是否激活Ctrl键,别名为:controlKey |
shiftKey | false | 是否激活Shift键 |
metaKey | false | 如果是Windwos,是否激活Win键,如果是Mac,是否激活Command键,另外为:commandKey, cmdKey |
multiple | false | 连续点击多个元素 |
force | false | 强制单击,忽略其元素状态 |
- 无参数
其用法如下所示:
cy.get('.nav > a').click()
- position
其用法如下所示:
cy.get('img').click('topRight')
- 坐标
其用法如下所示:
cy.get('#top-banner').click(15, 40)
- options
其用法如下所示:
cy.get('.close').as('closeBtn')
cy.get('@closeBtn').click({ force: true })
cy.get('#footer .next').click(5, 60, { force: true })
// 点击所有以btn开头的元素
cy.get('[id^=btn]').click({ multiple: true })
- 组合单击
在单击时,可以结合Alt、Ctrl、Shift、Win/Command键等,其用法如下所示:
// 使用Shift+Click
cy.get('li:first').click({
shiftKey: true,
})
除了使用这种来组合单击方式外,也可以type()
5.3.2 dbclick方法
dbclick主要用于双击元素,其基本语法如下所示:
.dblclick()
.dblclick(options)
.dblclick(position)
.dblclick(position, options)
.dblclick(x, y)
.dblclick(x, y, options)
option常见参数如下所示:
- position(String)
center是postion的默认位置,其他有效postion有:topLeft、top、topRight、left、center、right、bottomLeft、bottom、bottomRight,其示意图如下所示:
- x(Number)
元素离左边(left)的距离,单位为像素
- y(Number)
元素离上面(top)的距离,单位为像素
- options(Object)
选项 | 默认值 | 备注 |
---|---|---|
altKey | false | 是否激活Alt键,别名为:optionKey |
ctrlKey | false | 是否激活Ctrl键,别名为:controlKey |
shiftKey | false | 是否激活Shift键 |
metaKey | false | 如果是Windwos,是否激活Win键,如果是Mac,是否激活Command键,另外为:commandKey, cmdKey |
multiple | true | 连续点击多个元素 |
force | false | 强制单击,忽略其元素状态 |
- 无参数
其用法如下所示:
cy.get('a#nav1').dblclick()
- position
其用法如下所示:
cy.get('button').dblclick('bottom')
- 坐标
其用法如下所示:
cy.get('button').dblclick(30, 10)
- options
其用法如下所示:
cy.get('button').dblclick({ force: true })
cy.get('button').dblclick('topRight', { force: true })
cy.get('button').dblclick({ multiple: false })
- 组合单击
在双击时,可以结合Alt、Ctrl、Shift、Win/Command键等,其用法如下所示:
// 使用Shift+Click
cy.get('li:first').dblclick({
altKey: true,
})
5.3.3 rightclick方法
rightclick主要用于在元素上右击,其基本语法如下所示:
.rightclick()
.rightclick(options)
.rightclick(position)
.rightclick(position, options)
.rightclick(x, y)
.rightclick(x, y, options)
option常见参数如下所示:
- position(String)
center是postion的默认位置,其他有效postion有:topLeft、top、topRight、left、center、right、bottomLeft、bottom、bottomRight,其示意图如下所示:
- x(Number)
元素离左边(left)的距离,单位为像素
- y(Number)
元素离上面(top)的距离,单位为像素
- options(Object)
选项 | 默认值 | 备注 |
---|---|---|
altKey | false | 是否激活Alt键,别名为:optionKey |
ctrlKey | false | 是否激活Ctrl键,别名为:controlKey |
shiftKey | false | 是否激活Shift键 |
metaKey | false | 如果是Windwos,是否激活Win键,如果是Mac,是否激活Command键,另外为:commandKey, cmdKey |
multiple | false | 连续点击多个元素 |
force | false | 强制单击,忽略其元素状态 |
- 无参数
其用法如下所示:
cy.get('#open-menu').rightclick()
- position
其用法如下所示:
cy.get('#open-menu').rightclick('topRight')
- 坐标
其用法如下所示:
cy.get('#open-menu').rightclick(15, 40)
- options
其用法如下所示:
cy.get('#open-menu').rightclick({ force: true })
cy.get('#open-menu').rightclick('bottomLeft', { force: true })
cy.get('#open-menu').rightclick(5, 60, { force: true })
cy.get('.open-menu').rightclick({ multiple: true })
- 组合单击
在双击时,可以结合Alt、Ctrl、Shift、Win/Command键等,其用法如下所示:
// 使用Shift+Click
cy.get('.menu-item').rightclick({
metaKey: true,
})
5.3.4 type方法
type主要用于在元素对象输入内容,其基本语法如下所示:
.type(text)
.type(text, options)
type除了可以任意文本内容,也可以输入特定的文本,表示一些特殊的功能。如下所示:
项 | 功能描述 |
---|---|
{{} | 输入 { |
删除光标左侧字符 | |
删除光标右侧字符 | |
向上移动光标 | |
向下移动光标 | |
向左移动光标 | |
向右移动光标 | |
移动光标至行首 | |
移动光标至行尾 | |
按Enter键 | |
按ESC键 | |
在光标右侧插入字符 | |
移动光标至可输入对象的结尾处 | |
移动光标至可输入对象的开头处 | |
向下滚动 | |
向上滚动 | |
通过创建范围来全选所有文本 | |
激活Alt键 | |
激活Ctrl键 | |
如果是Windows,则激活Win键,如果是Mac,则激活Command键 | |
激活Shift键 |
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
delay | 10 | 在按下按键后的延迟时间,单位为ms |
force | false | 强制输入,忽略其元素状态 |
parseSpecialCharSequences | true | 是否解析{}中包含特定字符串 |
release | true | 是否保持长按 |
- 输入文本
其用法如下所示:
cy.get('textarea').type('Hello Surpass')
- 从datalist中选择输入
示例HTML片断如下所示:
<input list="fruit" />
<datalist id="fruit">
<option>Apple</option>
<option>Banana</option>
<option>Cantaloupe</option>
</datalist>
其用法如下所示:
cy.get('input').type('Apple')
- 使用组合键输入
其用法如下所示:
// 相当于人按Shift、Alt,再按住b键
cy.get('input').type('{shift+alt+b}hello')
- 忽略特定的字符
如果想输入{}这样的字符,可以使用选项parseSpecialCharSequences
cy.get('#code-input')
// 将不再解析{}里面的字符
.type('function (num) {return num * num;}', {
parseSpecialCharSequences: false,
})
5.3.5 clear方法
type主要用于清除输入的文本内容,其基本语法如下所示:
.clear()
.clear(options)
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
force | false | 强制清除,忽略其元素状态 |
- 无参数
其用法如下所示:
cy.get('textarea').clear().type('Hello, Surpass')
5.3.6 check方法
chekck主要用于选中单选框和复选框,其基本语法如下所示:
.check()
.check(value)
.check(values)
.check(options)
.check(value, options)
.check(values, options)
value可以是String也可以是Array,符合条件,则全部选中。
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
force | false | 强制选中,忽略其元素状态 |
- 选中复选框
cy.get('[type="checkbox"]').check()
- 选中单选框
cy.get('[type="radio"]').check()
- 根据value(String)选中
示例HTML片断如下所示:
<form>
<input type="radio" id="ca-country" value="CA" />
<label for="ca-country">Canada</label>
<input type="radio" id="us-country" value="US" />
<label for="us-country">United States</label>
</form>
其用法如下所示:
cy.get('[type="radio"]').check('US')
- 根据value(Array)选中
示例HTML片断如下所示:
<form>
<input type="checkbox" id="subscribe" value="subscribe" />
<label for="subscribe">Subscribe to newsletter?</label>
<input type="checkbox" id="acceptTerms" value="accept" />
<label for="acceptTerms">Accept terms and conditions.</label>
</form>
其用法如下所示:
cy.get('form input').check(['subscribe', 'accept'])
- 选择隐藏的Checkbox
其用法如下所示:
cy.get('.action-checkboxes')
.should('not.be.visible') // Passes
.check({ force: true })
.should('be.checked') // Passes
- 查找选中的Checkbox
示例HTML片断如下所示:
<form id="pick-fruit">
<input type="radio" name="fruit" value="orange" id="orange" />
<input type="radio" name="fruit" value="apple" id="apple" checked="checked" />
<input type="radio" name="fruit" value="banana" id="banana" />
</form>
其用法如下所示:
cy.get('#pick-fruit :checked').should('be.checked').and('have.value', 'apple')
5.3.7 uncheck方法
chekck主要用于取消选中单选框和复选框,其基本语法如下所示:
.uncheck()
.uncheck(value)
.uncheck(values)
.uncheck(options)
.uncheck(value, options)
.uncheck(values, options)
value可以是String也可以是Array,符合条件,则全部取消选中。
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
force | false | 强制取消选中,忽略其元素状态 |
- 取消选中复选框
cy.get(':checkbox').uncheck()
- 取消选中单选框
cy.get('input[type="ratio"]').uncheck()
- 根据value(String)取消选中
示例HTML片断如下所示:
<form>
<input type="radio" id="ca-country" value="CA" />
<label for="ca-country">Canada</label>
<input type="radio" id="us-country" value="US" />
<label for="us-country">United States</label>
</form>
其用法如下所示:
cy.get('[type="radio"]').uncheck('US')
- 根据value(Array)取消选中
示例HTML片断如下所示:
<form>
<input type="checkbox" id="subscribe" value="subscribe" />
<label for="subscribe">Subscribe to newsletter?</label>
<input type="checkbox" id="acceptTerms" value="accept" />
<label for="acceptTerms">Accept terms and conditions.</label>
</form>
其用法如下所示:
cy.get('form input').uncheck(['subscribe', 'accept'])
5.3.8 select方法
select主要用于选择下拉列表中一个选项,其基本语法如下所示:
.select(value)
.select(values)
.select(value, options)
.select(values, options)
value可以是String,Number也可以是Array,符合条件,则全部选中。
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
force | false | 强制选中其中一个项,忽略其元素状态 |
- 根据Text选择
示例HTML片断如下所示:
<select>
<option value="456">apples</option>
<option value="457">oranges</option>
<option value="458">bananas</option>
</select>
其用法如下所示:
cy.get('select').select('apples').should('have.value', '456')
- 根据Value选择
示例HTML片断如下所示:
<select>
<option value="456">apples</option>
<option value="457">oranges</option>
<option value="458">bananas</option>
</select>
其用法如下所示:
cy.get('select').select('456').should('have.value', '456')
- 根据Index选择
示例HTML片断如下所示:
<select>
<option value="456">apples</option>
<option value="457">oranges</option>
<option value="458">bananas</option>
</select>
其用法如下所示:
cy.get('select').select(0).should('have.value', '456')
- 选择多个项
示例HTML片断如下所示:
<select multiple>
<option value="456">apples</option>
<option value="457">oranges</option>
<option value="458">bananas</option>
</select>
其用法如下所示:
cy.get('select')
.select(['apples', 'bananas'])
.invoke('val')
.should('deep.equal', ['456', '458'])
// 或
cy.get('select')
.select([0, 1])
.invoke('val')
.should('deep.equal', ['456', '457'])
- 选择隐藏的select
示例HTML片断如下所示:
<select style="display: none;">
<optgroup label="Fruits">
<option value="banana">Banana</option>
<option value="apple">Apple</option>
</optgroup>
<optgroup></optgroup>
</select>
其用法如下所示:
cy.get('select')
.select('banana', { force: true })
.invoke('val')
.should('eq', 'banana')
- 选择disabled的select
示例HTML片断如下所示:
<select disabled>
<optgroup label="Veggies">
<option value="okra">Okra</option>
<option value="zucchini">Zucchini</option>
</optgroup>
<optgroup></optgroup>
</select>
其用法如下所示:
cy.get('select')
.select('okra', { force: true })
.invoke('val')
.should('eq', 'okra')
- 根据选中状态进行选择
示例HTML片断如下所示:
<select id="name">
<option>Joe</option>
<option>Mary</option>
<option selected="selected">Peter</option>
</select>
其用法如下所示:
cy.get('select#name option:selected').should('have.text', 'Peter')
5.3.9 trigger方法
trigger主要用于在DOM触发事件,其基本语法如下所示:
.trigger(eventName)
.trigger(eventName, position)
.trigger(eventName, options)
.trigger(eventName, x, y)
.trigger(eventName, position, options)
.trigger(eventName, x, y, options)
- 鼠标事件
// 鼠标移动到button上触发
cy.get('button').trigger('mouseover')
// 模拟长按
cy.get('.target').trigger('mousedown')
cy.wait(1000)
cy.get('.target').trigger('mouseup')
5.4 常见操作
5.4.1 visit方法
visit主要用于访问网址,其基本语法如下所示:
cy.visit(url)
cy.visit(url, options)
cy.visit(options)
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
url | null | 要访问的网址 |
method | GET | 访问网址的方法,仅限GET和POST |
body | null | 发送的请求体,如果是字符串,则不做修改,如果是一个对象,将会进行URL Encode再发送, Content-Type: application/x-www-urlencoded |
headers | {} | 发送的请求头 |
timeout | pageLoadTimeout | 页面加载超时时间 |
auth | {} | 添加基本验证请求头 |
qs | null | URL查询参数 |
常用示例如下所示:
- 常规用法
cy.visit('http://www.surpass.com')
// 添加页面加载超时时间
cy.visit('http://www.surpass.com', { timeout: 30000 })
// 添加基本验证头
cy.visit('https://www.surpass.com/', {
auth: {
username: 'surpass',
password: 'surpass',
},
})
// 以上等同于:
cy.visit('https://surpass:surpass@www.surpass.com')
// 添加查询参数
cy.visit('http://www.surpass.com/users', {
qs: {
username: 'surpass',
age:28,
},
})
// 以上等同于:
cy.visit('https://www.surpass.com?username=surpass&age=28')
- 发送表单
cy.visit({
url: 'http://www.surpass.com/login',
method: 'POST',
body: {
name: 'surpass',
email: 'surpass@surpass.com',
},
})
在实际项目中,通常主域名是不会发生变更的,一般变化较多的都是子域名。针对这种情况,Cypress可在cypress.json中配置baseUrl,在实际运行时,Cypress会自动加上。
{
"baseUrl": "http://www.surpass.com"
}
在配置好baseUrl后,在使用cy.visit()写法如下所示:
cy.visit("/register.html")
- 访问本地文件
如果不提供主机域名或baseUrl未定义时,Cypress默认会自动尝试向服务器请求并访问指定的文件。那如果要访问的是本地文件,Cypress也提供了相应的方法。如下所示:
/// <reference types="cypress" />
describe('访问本地文件场景示例', () => {
// 默认向服务器发起请求
it('访问百度', () => {
cy.visit("www.baidu.com");
cy.get("#kw").type("Surpass").should("contain.value","Surpass");
});
// 访问本地文件,注意路径的写法,以cypress.json所在的路径为根路径
it('访问本地文件用例',{baseUrl: null }, () => {
cy.visit("./cypress/integration/3-Surpass-Test-Examples/testSelect/surpass.test.html",);
cy.get(":nth-child(1) > input").type("I love surpass")
});
});
访问本地文件时,需要使用相对根目录的路径,其根目录路径为生成cypress.json所在路径
运行结果如下所示:
5.4.2 url方法
url主要用于获取当前访问页面的URL地址,其基本语法如下所示:
cy.url()
cy.url(options)
option常见参数如下所示:
选项 | 默认值 | 备注 |
---|---|---|
decode | false | 对URL进行解码 |
timeout | defaultCommandTimeout | 解析URL的超时时间 |
常用用法示例如下所示:
- 无参数
/// <reference types="cypress" />
describe("测试URL方法",()=>{
it('测试用例-1', () => {
cy.visit("https://www.baidu.com/");
cy.url().should("contain","baidu");
cy.visit("https://news.baidu.com");
cy.url().should("contain","news.baidu.com");
});
})
运行结果如下所示:
- 解析URL编码
/// <reference types="cypress" />
describe("测试URL方法",()=>{
it.only('URL解码测试用例', () => {
// 搜索关键词中使用中文汉字
let url="https://www.baidu.com/s?wd=%E6%B1%89";
cy.visit(url);
cy.url({decode:true}).should("contain","汉");
});
})
运行结果如下所示:
decode主要用于URL中包含非ASCII字符
5.4.3 title方法
title主要用于获取当前访问页面的title,其基本语法如下所示:
cy.title()
cy.title(options)
常用用法示例如下所示:
cy.visit("https://www.baidu.com/");
cy.title().should("eq","百度一下,你就知道");
5.4.4 reload方法
reload主要用于重新加载当前页面,其基本语法如下所示:
cy.reload()
cy.reload(forceReload)
cy.reload(options)
cy.reload(forceReload, options)
forceReload (Boolean):该参数主要用于判断是否从cache中加载页面,若为true,则不使用cache,重新向服务器发起请求
常用用法示例如下所示:
- 无参数
cy.visit("https://www.baidu.com/");
cy.reload();
- 使用force参数
cy.visit("https://www.baidu.com/");
cy.reload(true);
5.4.5 设置窗口大小
在Cypress运行时,默认窗口大小1000px*660px,如果想自定义窗口大小,则Cypress提供了两种设置窗口大小的方法,分别如下所示:
- 通过cypress.json设置
{
"viewportWidth": 1920,
"viewportHeight": 1080
}
- 在运行时设置设置
如果要在运行时设置窗口大小,需要使用viewport方法,,其基本语法如下所示:
cy.viewport(width, height)
cy.viewport(preset, orientation)
cy.viewport(width, height, options)
cy.viewport(preset, orientation, options)
常见参数如下所示:
- width(Number)
窗口宽度,单位为像素,其值必须为有限的非负数
- height(Number)
窗口高度,单位为像素,其值必须为有限的非负数
- preset(String)
根据现有已知设备,快速设置窗口大小,现有已知设备大小如下所示:
- orientation(String)
设置屏幕的方向,默认值为portrait(纵向),也可以设置为landscape(横向)
常用用法示例如下所示:
- 设置窗口大小
cy.viewport(1920, 1080)
- 根据preset设置窗口大小
cy.viewport('iphone-6')
- 根据屏幕方向
cy.viewport('iphone-6', 'landscape')
使用Cypress设置窗口大小时,暂时不支持设置devicePixelRatio
5.4.6 前进和后退
在Cypress中对浏览器进行前进和后退的处理,是通过go方法来实现,其前进和后退依赖是浏览历史中的URL记录,其基本语法如下所示:
cy.go(direction)
cy.go(direction, options)
常见参数如下所示:
- direction (String, Number)
表示后退主要使用back和-1
表示前进主要使用forward和1
常用用法示例如下所示:
- 前进
cy.go('forward')
cy.go(1)
- 后退
cy.go('back')
cy.go(-1)
5.4.7 元素可见/存在/不可操作
通过前面的学习,我们已经知道可以使用should进行断言,但它也同时支持判断元素是否可见、是否存在、是否可操作等。
- 元素是否可见
cy.get('nav').should('be.visible')
- 元素是否存在
cy.get('nav').should('not.exist')
cy.get('nav').should('exist')
- 元素是否可操作
cy.get(':checkbox').should('be.disabled')
5.4.8 then方法
then方法主要用于获取前一个命令的返回值,我们可以利用该特性,来获取元素的值,其基本语法如下所示:
.then(callbackFn)
.then(options, callbackFn)
以下常见的用法:
- 获取元素文本值
cy.get("#su").then(($su)=>{
let btnText=$su.attr("value");
cy.log(`按钮的文字是:${btnText}`);
});
运行结果如下所示:
5.4.9 clear方法
clear方法主要用于清除ipnut输入框和textarea中所输入的文本内容,其基本语法如下所示:
.clear()
.clear(options)
以下常见的用法:
cy.get("#kw").type("I love Surpass").clear();
// 等价于
cy.get("#kw").type("I love Surpass").type("{selectall}{backspace}")
以上仅为Cypress提供的常用方法,更多方法可以查阅官方文档 :https://docs.cypress.io/api/table-of-contents
原文地址:https://www.jianshu.com/p/9a45af9fa2be
本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:
作者: Surpassme
来源: http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接 ,否则保留追究法律责任的权利。如有问题,可发送邮件 联系。让我们尊重原创者版权,共同营造良好的IT朋友圈。