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()
的默认行为。
选项 | 默认值 | 描述 |
---|---|---|
log | true | 在命令日志中显示该命令 |
生成结果
.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
命令时,控制台会输出以下内容:

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