Count Each Number
Every row in this table has a button that loads some count and shows it in the next cell.
<table class="as-table table table-bordered">
<thead>
<tr>
<th>Command</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td><button id="load1">Load</button></td>
<td id="count1"></td>
</tr>
<tr>
<td><button id="load2">Load</button></td>
<td id="count2"></td>
</tr>
<tr>
<td><button id="load3">Load</button></td>
<td id="count3"></td>
</tr>
</tbody>
</table>
<script>
const get = document.getElementById.bind(document)
;[1, 2, 3].forEach((k) => {
get('load' + k).addEventListener('click', () => {
setTimeout(() => {
get('count' + k).innerText = k + 4
}, 1000)
})
})
</script>
Can we iterate over the rows, clicking the "Load" buttons, and summing up the revealed numbers? The total sum should be 18.
let clicked = 0
let count = 0
// let's iterate over all buttons in the first column
cy.get('table tbody td:nth-child(1) button')
// cy.each callback receives a jQuery object
// plus its index starting with zero
.each(($button, k) => {
// wrap the jQuery button object and click on it
cy.wrap($button).click()
// the same row "k" should now have a cell with a number
cy.get('tbody tr')
.eq(k)
.contains('td', /^\d+$/)
// get the text and convert it into an integer
.invoke('text')
.then(parseInt)
// when we get something from the application
// we can use the value in cy.then callback
.then((n) => {
clicked += 1
count += n
})
})
We cannot simply use the count
and clicked
values yet. The following test code is incorrect and will not work
// 🚨 WILL NOT WORK
cy.log(`count is ${count}`)
expect(count).to.equal(18)
We MUST access the updated "clicked" and "count" values in another cy.then callback so the values are computed by the time this cy.then callback executes
cy.then(() => {
expect(count, 'count').to.equal(18)
cy.get('table tbody tr').should('have.length', clicked)
})
Tip: read the blog post Visualize Cypress Command Queue to understand how to use the local variables with Cypress commands.