Skip to main content
Cypress应用

within

将后续所有Cypress命令的作用域限定在该元素内。当需要操作特定元素组(如<form>)时非常有用。

.within()之后继续链式调用依赖该主题的命令是不安全的

语法

.within(callbackFn)
.within(options, callbackFn)

用法

正确用法

cy.get('.list')
.first()
.within(($list) => {}) // 获取第一个`.list`并将其作为后续命令的作用域

错误用法

cy.within(() => {}) // 错误,不能直接从'cy'链式调用
cy.getCookies().within(() => {}) // 错误,'getCookies'不返回DOM元素
cy.get('div').within(($divs) => {}) // 可能错误,因为get('div')返回多个元素

参数

callbackFn (函数)

传入一个函数,该函数的第一个参数是当前返回的主题。

options (对象)

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

选项默认值描述
logtrue命令日志中显示该命令

生成结果 了解主题管理

  • .within()返回与传入时相同的主题。
  • .within()之后继续链式调用依赖该主题的命令是不安全的

尝试在.within回调中返回不同的元素不会产生任何效果:

<div id="within-yields">
父级div
<div class="some-child">子元素</div>
</div>
cy.get('#within-yields')
.within(() => {
// 我们尝试从.within回调中返回某些内容,
// 但这不会有任何效果
return cy.contains('子元素').should('have.class', 'some-child')
})
.should('have.id', 'within-yields')

类似地,尝试通过在.within回调中使用cy.wrap命令来改变主题也不会产生任何效果:

<div id="wrap-inside-within">
父级div
<div class="some-child">子元素</div>
</div>
cy.get('#wrap-inside-within')
.within(() => {
// 返回cy.wrap(...)不会改变返回的值
// 它仍然是原始的父级DOM元素
return cy.wrap('一个新值')
})
.should('have.id', 'wrap-inside-within')

示例

表单

获取表单内的输入框并提交表单

<form>
<input name="email" type="email" />
<input name="password" type="password" />
<button type="submit">登录</button>
</form>
cy.get('form').within(($form) => {
// 如果需要,可以通过jQuery对象$form访问找到的表单

// cy.get()将仅在表单内搜索元素,
// 而不是在整个文档中
cy.get('input[name="email"]').type('john.doe@email.com')
cy.get('input[name="password"]').type('password')
cy.root().submit()
})

表格

查找包含特定单元格的行并确认行中的其他单元格

<table>
<tr>
<td>我的第一个客户</td>
<td>我的第一个项目</td>
<td>0</td>
<td>活跃</td>
<td><button>编辑</button></td>
</tr>
</table>
cy.contains('我的第一个客户')
.parent('tr')
.within(() => {
// 所有搜索自动限定在找到的tr元素内
cy.get('td').eq(1).contains('我的第一个项目')
cy.get('td').eq(2).contains('0')
cy.get('td').eq(3).contains('活跃')
cy.get('td').eq(4).contains('button', '编辑').click()
})

临时跳出作用域

你可以通过使用cy.root开始一个新的命令链,然后使用.closest命令临时跳出.within的作用域。

<section class="example">
{/* 注意表单外的输入框 */}
<input id="name" type="text" />
<form>
<input name="email" type="email" />
<input name="password" type="password" />
<button type="submit">登录</button>
</form>
</section>
cy.get('form').within(($form) => {
// 临时跳出.within的作用域
cy.root().closest('.example').find('#name').type('Joe')
// 继续使用.within的作用域
cy.get('input[name="email"]').type('john.doe@email.com')
cy.get('input[name="password"]').type('password')
cy.root().submit()
})

规则

要求 了解命令链

  • .within()需要链式调用在一个返回恰好一个DOM元素的命令之后。

断言 了解断言

  • .within()只会运行你链式调用的一次断言,不会重试

超时设置 了解超时机制

  • .within()不会超时。

命令日志

获取表单内的输入框

cy.get('.query-form').within((el) => {
cy.get('input:first')
})

上述命令将在命令日志中显示为:

命令日志 within

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

控制台日志 within

历史

版本变更
12.0.0当传入多个元素作为主题时,.within()现在会抛出错误。
5.4.0修复了返回值始终为父元素的问题
< 0.3.3添加了.within()命令

另请参阅