我有一个数组,其中的项目是一堆按钮元素。我想调用一个按钮,然后等待一个元素(位于 dom 中)被加载。
加载该元素后,只有我想进入下一个迭代(单击下一个按钮/元素)
在我当前的实现中,一次单击所有按钮。但我希望一次单击一个按钮。
cy.document().then(document => {
const arra = [...document.querySelectorAll('.instances__action')];
for (let i = 1; i <= arra.length; i++) {
let state = document.querySelector(
`#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i}) > td:nth-child(3) > span`
).innerText;
document
.querySelector(
`#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i}) > td:nth-child(7) > div > button.ant-btn.ant-btn-primary.ant-btn-sm`
)
.click();
cy.wait(2000);
cy.waitUntil(() => {
cy.get(
`#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody > tr:nth-child(${i +
1}) > td:nth-child(3) > span`
).contains('Finished');
});
}
});
});
最佳答案
@jmargolisvt 是正确的,如果您更改 .click()
操作 Cypress 命令,您应该获得正确的操作顺序。
命令执行顺序和测试循环
这样想 - 上面的测试代码作为正常的 javascript 运行,并且每个 cy.X()
命令将命令放入队列中。保证命令按队列顺序顺序运行,但不与测试代码同步。
所以,cy.wait(2000)
不会减慢 for 循环,它会暂停队列执行。
等待断言
另请注意,命令具有内置的断言等待,因此您可能不需要 cy.wait()
或cy.waitUntil()
在这种情况下。您可以使用 timeout
控制最长等待时间选项。
循环
如果将内部部分转换为命令,for 循环将正常工作,但您也可以将循环本身转换为 cy.get().each() IMO 中的命令更加简洁。
测试异步内容
最后,更喜欢cy.contains('mySelector', 'myContent')
命令 cy.get('mySelector').contains('myContent')
等待异步内容时的命令。
原因是 cy.get('mySelector').contains('myContent')
只等待元素 mySelector
,但它已经在 DOM 中了。如果内容是异步更改的,该命令将立即测试旧内容(假设为空)并导致测试失败。
const tbodySelector = '#root > section > section > main > div > div > section.instances > div > div > div > div > div > div > table > tbody';
const buttonSelector = 'td:nth-child(7) > div > button.ant-btn.ant-btn-primary.ant-btn-sm';
const spanSelector = 'td:nth-child(3) > span'
cy.get('.instances__action').each(($el, i) => {
cy.get(`${tbodySelector} > tr:nth-child(${i+1}) > ${buttonSelector}`)
.click();
cy.contains(
`${tbodySelector} > tr:nth-child(${i+1}) > ${spanSelector}`,
'Finished',
{ timeout: 2000 } // increase timeout if a longer wait is required
);
});
注意 jQuery 的 :nth-child(index)
选择器从索引 1 开始,但是 .each(($el, i) =>
具有从零开始的索引,因此必须使用 i+1
在这些选择器中。
这是我用来测试的模拟 DOM。在一个干净的 Cypress 项目中,将其放入文件夹 <project root>/app
中.
<table>
<tbody>
<tr class="instances__action">
<td>
<button id="myBtn1"></button>
</td>
<td>
<span id="mySpan1"></span>
</td>
</tr>
<tr class="instances__action">
<td>
<button id="myBtn2"></button>
</td>
<td>
<span id="mySpan2"></span>
</td>
</tr>
</tbody>
</table>
<script>
document.getElementById("myBtn1").addEventListener("click", function() {
setTimeout(() => {
document.getElementById("mySpan1").innerHTML = "Finished";
}, 1000)
});
document.getElementById("myBtn2").addEventListener("click", function() {
setTimeout(() => {
document.getElementById("mySpan2").innerHTML = "Finished";
}, 500)
});
</script>
请注意,上面的嵌套已被简化,因此我适本地更改了选择器内容。
测试上述 HTML 片段
it('clicks buttons and waits for finished flag', () => {
cy.visit('app/iterate-table-buttons.html')
const tbodySelector = 'tbody';
const buttonSelector = 'td:nth-child(1) > button';
const spanSelector = 'td:nth-child(2) > span'
cy.get('.instances__action').each(($el, i) => {
console.log(`starting #${i}`)
cy.get(`${tbodySelector} > tr:nth-child(${i+1}) > ${buttonSelector}`)
.then(() => console.log(`clicking #${i}`))
.click();
cy.contains(
`${tbodySelector} > tr:nth-child(${i+1}) > ${spanSelector}`,
'Finished',
{ timeout: 2000 } // increase timeout if a longer wait is required
)
.then(() => console.log(`asserting #${i}`))
});
})
柏树原木
这就是 Cypress 日志的样子。
全绿色,并且可以看到只有在完成文本出现后才会发生点击。
- 访问 app/iterate-table-buttons.html
- 获取.instances__action
- 获取 tbody > tr:nth-child(1) > td:nth-child(1) > 按钮
- 点击
- 包含 tbody > tr:nth-child(1) > td:nth-child(2) > span,已完成
- 获取 tbody > tr:nth-child(2) > td:nth-child(1) > 按钮
- 点击
- 包含 tbody > tr:nth-child(2) > td:nth-child(2) > span,已完成
控制台日志
这就是控制台日志的样子。
循环在命令队列开始之前就执行完成,但这没关系,因为命令仍然按正确的顺序执行。
从 #0 开始
开始#1
点击#0
断言#0
点击#1
断言 #1
关于javascript - Cypress 等待 for 循环内加载元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60788843/