I have a page with orders. Each order can have one or more items. I need to check the quantity displayed against the quantity in the mocked data.
Here is the simplified structure:
.order {
background: white;
display: flex;
flex-direction:column;
}
.order:nth-of-type(2n 2) {
background:#ccc;
}
<div >
<div >
<div >
<h3>
Item name A
</h3>
<div classname="item-quantity">
3
</div>
</div>
<div >
<h3>
Item name B
</h3>
<div classname="item-quantity">
1
</div>
</div>
<div >
<h3>
Item name C
</h3>
<div classname="item-quantity">
6
</div>
</div>
<div >
<div >
<h3>
Item name D
</h3>
<div classname="item-quantity">
3
</div>
</div>
<div >
<h3>
Item name E
</h3>
<div classname="item-quantity">
9
</div>
</div>
</div>
<div >
<div >
<h3>
Item name F
</h3>
<div classname="item-quantity">
3
</div>
</div>
<div >
<h3>
Item name G
</h3>
<div classname="item-quantity">
4
</div>
</div>
</div>
</div>
</div>
Here is the simplified row-data:
"fulfillment": [
{
"details": [
{
"quantity": 3,
"item": {
"itemName": "Item name A",
}
},
{
"quantity": 1,
"item": {
"itemName": "Item name B",
}
},
{
"quantity": 6,
"item": {
"itemName": "Item name C",
}
}
]
},
{
"details": [
{
"quantity": 3,
"item": {
"itemName": "Item name D",
}
},
{
"quantity": 9,
"item": {
"itemName": "Item name E",
}
},
]
},
{
"details": [
{
"quantity": 3,
"item": {
"itemName": "Item name F",
}
},
{
"quantity": 4,
"item": {
"itemName": "Item name G",
}
},
]
}
]
And here is the code I wrote:
it.only('Checks - right item quantity is shown', () => {
cy.get('@getResponse').then(orders => {
const order = orders.response.body.filter(el => el.orderNumber === 'XYZ')[0]
const singleFul = order.fulfillment.map(singleFulfillment => singleFulfillment.details)
console.log('singleFul', singleFul)
cy.get('.order').each(($singleFulfillment, index) => {
const singleItem = singleFul[index].map(detail => detail.quantity)
console.log('singleItemtop', singleItem)
cy.get(
'.order .ordered-item .item-quantity',
).each(($singleItemName, idx) => {
console.log("idx", idx);
console.log('singleItembottom', singleItem[idx])
cy.wrap($singleItemName).should('contain', singleItem[idx])
})
})
})
})
The problem is that the way I did it, it successfully passes the tests for the first block (first order). The rest are failing.
Here is the result of those console.logs:
singleFul: [Array(3), Array(2), Array(2)]
singleItemtop (3) [3, 1, 6]
singleItemtop (2) [3, 9]
singleItemtop (2) [3, 4]
idx 0
singleItembottom 3
idx 1
singleItembottom 1
idx 2
singleItembottom 6
idx 3
singleItembottom undefined
idx 4
singleItembottom undefined
idx 5
singleItembottom undefined
idx 6
singleItembottom undefined
It looks like that the second (inner) cy.get
is finding all the .item-quantity
that are present in the page, thus the idx
is going on and on.
I tried to use .within
too, however it doesn't give an index to correctly match singleItem at the right index.
I hope someone can help me to fix this test to make it work.
Thank you in advance
CodePudding user response:
Can you approach it from the mocked data? Should be easier.
const data = {
fulfillment: [
...
]
}
data.fulfillment.forEach(ff => {
ff.details.forEach(detail => {
const itemName = detail.item.itemName;
cy.contains('h3', itemName)
.next('.item-quantity')
.invoke('text')
.then(parseInt)
.should('eq', detail.quantity)
})
})
An alternative using Array.flatMap()
const flatData = data.fulfillment.flatMap(order => {
return order.details.flatMap(orderItem => {
return {
name: orderItem.item.itemName,
quantity: orderItem.quantity
}
})
})
/*
Yields
[
{name: 'Item name A', quantity: 3}
{name: 'Item name B', quantity: 1}
{name: 'Item name C', quantity: 6}
{name: 'Item name D', quantity: 3}
{name: 'Item name E', quantity: 9}
{name: 'Item name F', quantity: 3}
{name: 'Item name G', quantity: 4}
]
*/
cy.get('.ordered-item')
.then($items => {
return [...$items].map(item => {
const $item = Cypress.$(item)
const name = $item.find('h3').text().trim()
const quantityText = $item.find('div[classname="item-quantity"]')
.text().trim()
const quantity = parseInt(quantityText)
return {name, quantity}
})
})
.should('deep.eq', flatData)
This is a better test because it checks there are no extra items on the page, and also check the order in the data is the same as the order on the page.