Skip to main content
Cypress应用

contains

获取包含指定文本的DOM元素。DOM元素可以包含_更多_文本但仍能匹配。此外,Cypress会优先选择某些DOM元素而非找到的最深层元素。

语法

.contains(content)
.contains(content, options)
.contains(selector, content)
.contains(selector, content, options)

// ---或---

cy.contains(content)
cy.contains(content, options)
cy.contains(selector, content)
cy.contains(selector, content, options)

用法

正确用法

cy.get('.nav').contains('About') // 获取.nav中包含'About'的元素
cy.contains('Hello') // 获取文档中第一个包含'Hello'的元素

错误用法

cy.title().contains('My App') // 错误,'title'不返回DOM元素
cy.getCookies().contains('_key') // 错误,'getCookies'不返回DOM元素

参数

content (字符串, 数字, 正则表达式)

获取包含该内容的DOM元素。

selector (字符串选择器)

指定一个选择器来筛选包含文本的DOM元素。Cypress会_忽略_其对指定选择器的默认优先级顺序。使用选择器可以返回包含特定文本的更_浅层_元素(树中更高层)。

options (对象)

传入一个选项对象以改变.contains()的默认行为。

选项默认值描述
matchCasetrue检查大小写敏感
logtrue命令日志中显示命令
timeoutdefaultCommandTimeout等待.contains()解析的超时时间
includeShadowDomincludeShadowDom配置选项值是否遍历Shadow DOM边界并在返回结果中包含Shadow DOM中的元素。

生成结果 了解主题管理

  • .contains()返回找到的新DOM元素。
  • .contains()是一个查询命令,可以安全地链式调用其他命令。

示例

内容

查找第一个包含某文本的元素

<ul>
<li>苹果</li>
<li>橙子</li>
<li>香蕉</li>
</ul>
// 返回<li>苹果</li>
cy.contains('苹果')

通过值查找input[type='submit']

获取表单元素并在其子元素中搜索内容"提交表单!"

<div id="main">
<form>
<div>
<label>姓名</label>
<input name="name" />
</div>
<div>
<label>年龄</label>
<input name="age" />
</div>
<input type="submit" value="提交表单!" />
</form>
</div>
// 返回input[type='submit']元素并点击它
cy.get('form').contains('提交表单!').click()

数字

查找第一个包含数字的元素

尽管<span>是包含"4"的最深层元素,但Cypress会因其元素优先级顺序自动返回<button>元素而非span。

<button class="btn btn-primary" type="button">
消息 <span class="badge">4</span>
</button>
// 返回<button>
cy.contains(4)

正则表达式

查找第一个文本匹配正则表达式的元素

<ul>
<li>苹果</li>
<li>橙子</li>
<li>香蕉</li>
</ul>
// 返回<li>香蕉</li>
cy.contains(/^b\w+/)

选择器

指定选择器返回特定元素

从技术上讲,下面的<html><body><ul>和第一个<li>都包含"苹果"。

通常Cypress会返回第一个<li>,因为这是包含"苹果"的_最深层_元素。

为了覆盖返回的元素,我们可以传递'ul'作为选择器。

<html>
<body>
<ul>
<li>苹果</li>
<li>橙子</li>
<li>香蕉</li>
</ul>
</body>
</html>
// 返回<ul>...</ul>
cy.contains('ul', '苹果')

保持表单作为主题

以下示例使用选择器确保<form>在后续链式调用中保持主题

<form>
<div>
<label>姓名</label>
<input name="name" />
</div>
<button type="submit">继续</button>
</form>
cy.get('form') // 返回<form>...</form>
.contains('form', '继续') // 返回<form>...</form>
.submit() // 返回<form>...</form>

如果没有显式选择器,主题会变为<button>。使用显式选择器确保链式命令的主题是<form>

大小写敏感

以下示例使用matchCase选项忽略大小写敏感。

<div>大写句子</div>
cy.get('div').contains('小写句子') // 失败
cy.get('div').contains('小写句子', { matchCase: false }) // 成功

注意事项

作用域

.contains()的行为取决于它是开始一个命令序列还是链式调用现有序列。

当开始一个命令序列时:

这会查询整个document中的内容。

cy.contains('登录')

当链式调用现有命令序列时

这会在<#checkout-container>元素内部查询。

cy.get('#checkout-container').contains('立即购买')

注意链式调用多个contains

假设一个场景:点击按钮删除用户,然后出现对话框要求确认删除。

// 这样无法按预期工作
cy.contains('删除用户').click().contains('确认删除!').click()

因为第二个.contains()链式调用了返回<button>的命令,Cypress会在<button>内部查找新内容。

换句话说,Cypress会在包含"删除用户"的<button>中查找内容:"确认删除!",这不是我们想要的。

正确做法是再次调用cy,这会自动创建一个新的链式作用域到document

cy.contains('删除用户').click()
cy.contains('确认删除!').click()

<pre>标签中的前导、尾随和重复空格不会被忽略

与其他标签不同,<pre>不会忽略前导、尾随或重复空格,如下所示:

<!--测试代码-->
<h2>其他标签</h2>
<p>你好,世界!</p>

<h2>Pre标签</h2>
<pre> 你好, 世界 !</pre>

渲染结果:

pre标签的结果

为了反映这种行为,Cypress也不会忽略它们。

// 上述代码的测试结果

cy.get('p').contains('你好,世界!') // 成功
cy.get('p').contains(' 你好, 世界 !') // 失败

cy.get('pre').contains('你好,世界!') // 失败
cy.get('pre').contains(' 你好, 世界 !') // 成功

不间断空格

你可以在cy.contains()中使用空格字符来匹配HTML中使用不间断空格实体&nbsp;的文本。

<span>你好&nbsp;世界</span>
// 找到span元素
cy.contains('你好 世界')

提示: 阅读关于对包含不间断空格实体的文本进行断言的更多信息,请参见如何获取元素的文本内容?

单个元素

仅返回_第一个_匹配的元素

<ul id="header">
<li>欢迎,简·莱恩</li>
</ul>
<div id="main">
<span>这些用户与简·莱恩有10个连接</span>
<ul>
<li>贾马尔</li>
<li>帕特丽夏</li>
</ul>
</div>

以下示例会返回#header中的<li>,因为这是_第一个_包含文本"简·莱恩"的元素。

// 返回#header li
cy.contains('简·莱恩')

如果想选择<span>,可以在.contains()之前缩小返回的元素范围。

// 返回<span>
cy.get('#main').contains('简·莱恩')

默认的<input type="submit">标签

<input type="submit">省略value属性时,会使用默认标签,这可能与地区相关。 更多信息见MDN。

此时value为空字符串,Cypress无法通过用户代理显示的标签以编程方式筛选元素。这可能导致在使用cy.contains()与提交按钮时出现意外失败。

解决方案是:

 // 断言空字符串
cy.get('input').should('have.value', '')

// ---或---

// 如果可能,设置`value`属性
<input type=submit value="提交" />

优先级

元素优先级顺序

.contains()默认优先选择树中更高层的元素,当它们是:

  • input[type='submit']
  • button
  • a
  • label

如果向.contains()传递选择器参数,Cypress会忽略此元素优先级顺序。

优先选择<button>而非其他更深层的元素

尽管<span>是包含"搜索"的最深层元素,Cypress会返回<button>元素而非span。

<form>
<button>
<i class="fa fa-search"></i>
<span>搜索</span>
</button>
</form>
// 返回<button>
cy.contains('搜索').children('i').should('have.class', 'fa-search')

优先选择<a>而非其他更深层的元素

尽管<span>是包含"退出登录"的最深层元素,Cypress会返回锚元素而非span。

<nav>
<a href="/users">
<span>用户</span>
</a>
<a href="/signout">
<span>退出登录</span>
</a>
</nav>
// 返回<a>
cy.get('nav').contains('退出登录').should('have.attr', 'href', '/signout')

优先选择<label>而非其他更深层的元素

尽管<span>是包含"年龄"的最深层元素,Cypress会返回<label>元素而非<span>

<form>
<label>
<span>姓名:</span>
<input name="name" />
</label>
<label>
<span>年龄:</span>
<input name="age" />
</label>
</form>
// 返回label
cy.contains('年龄').find('input').type('29')

规则

要求 了解命令链

  • .contains()可以链式调用cy或返回DOM元素的命令。

断言 了解断言

  • .contains()会自动重试直到元素在DOM中存在。
  • .contains()会自动重试直到所有链式断言通过。

超时设置 了解超时机制

  • .contains()可能因等待元素存在于DOM中而超时。
  • .contains()可能因等待添加的断言通过而超时。

命令日志

元素包含文本"新用户"

cy.get('h1').contains('新用户')

以上命令会在命令日志中显示为:

命令日志contains

点击命令日志中的contains命令时,控制台会输出以下内容:

console.log contains

历史记录

版本变更
5.2.0添加includeShadowDom选项。
4.0.0添加对matchCase选项的支持。

另请参阅