WEB自动化-05-Cypress-元素交互

5 元素交互

    元素识别和操作是UI自动化测试的基础,下面一起来学习一下在Cypress中的元素交互操作吧。

5.1 元素定位器选择

    每一个测试用例都包含对元素的定位识别和操作等。因为一个好的测试用例,必须保证 健壮和可靠的元素定位策略 。在实际项目中,经常会遇到以下问题:

  • 元素ID或类是动态生成
  • 若使用CSS定位,而在实际开发过程中CSS或JS行为发生更改等

    为避免出现以上失败情况,我们可以采取以下策略

  • 不建议使用基于CSS属性的定位方式,如id, class, tag
  • 不建议使用基于易发生变化的文本内容
  • 添加 data-* 属性,使其更加容易定位元素

Cypress提供三个data-*属性,分别是 data-cydata-testdata-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&nbsp;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有: topLefttoptopRightleftcenterrightbottomLeftbottombottomRight ,其示意图如下所示:

0501Postion示意图.png
  • 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有: topLefttoptopRightleftcenterrightbottomLeftbottombottomRight ,其示意图如下所示:

0501Postion示意图.png
  • 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有: topLefttoptopRightleftcenterrightbottomLeftbottombottomRight ,其示意图如下所示:

0501Postion示意图.png
  • 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除了可以任意文本内容,也可以输入特定的文本,表示一些特殊的功能。如下所示:

功能描述
{{} 输入 {
{backspace} 删除光标左侧字符
{del} 删除光标右侧字符
{upArrow} 向上移动光标
{downArrow} 向下移动光标
{leftArrow} 向左移动光标
{rightArrow} 向右移动光标
{home} 移动光标至行首
{end} 移动光标至行尾
{enter} 按Enter键
{esc} 按ESC键
{insert} 在光标右侧插入字符
{moveToEnd} 移动光标至可输入对象的结尾处
{moveToStart} 移动光标至可输入对象的开头处
{pageDown} 向下滚动
{pageUp} 向上滚动
{selectAll} 通过创建范围来全选所有文本
{alt} 激活Alt键
{ctrl} 激活Ctrl键
{meta} 如果是Windows,则激活Win键,如果是Mac,则激活Command键
{shift} 激活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所在路径

    运行结果如下所示:

0502访问本地文件.png

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");
    });
})

    运行结果如下所示:

0503cy.url无参数测试.png
  • 解析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","汉");
    });
})

    运行结果如下所示:

0504cy.url.decode.png

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运行时,默认窗口大小 1000px660px* ,如果想自定义窗口大小,则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)

    根据现有已知设备,快速设置窗口大小,现有已知设备大小如下所示:

0505现有已知设备窗口大小.png
  • 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
    表示前进主要使用 forward1

    常用用法示例如下所示:

  • 前进
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}`);
});

    运行结果如下所示:

0506获取按钮文字.png

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容