Reputation: 2743
I have some divs that render this way:
<div class="customer-data-column">
<h3>Title:</h3>
<div>Name Lastname</div>
<div>123 Address xxx yyy</div>
<div>Chicago XY 33056</div>
<div>Country name</div>
</div>
This content is generated by:
{customerData.replaceAll("/r", "").split("\n").map(item => <div key={item}>{item}</div>)}
This data is coming from redux. In console log (from redux data) the address appears this way:
Name Lastname\n123 Address xxx yyy\nChicago XY 33056\nCountry name
I want to check in Cypress if this address is correct, the same that is in redux.
I need some way that merges the content of the divs into one string, and adds the \n
between each div.
I thought I could start this way:
cy.get('.customer-data-column').should($title => {
const store = Cypress.store.getState();
const reduxPath = store.customerData;
expect("not sure what to put here... how to merge").to.equals(reduxPath)
Can anyone please help?
=== EDIT
I made it almost work this way: I added a class to the inner divs, so they render this way:
<div class="customer-data-column">
<h3>Title:</h3>
<div class="address-row">Name Lastname</div>
<div class="address-row">123 Address xxx yyy</div>
<div class="address-row">Chicago XY 33056</div>
<div class="address-row">Country name</div>
</div>
And the test:
cy.get('.address-row').then($divList => {
const textArray = Cypress.$.makeArray($divList).map(el => el.innerText)
const actual = textArray.join(textArray, '\n') // use join to array of strings into single string
expect(actual).to.eql(billToAddress)
})
However it still fails with such message:
assert expected Name LastnameName Lastname,23 Address xxx yyy,Chicago XY 33056,Country name23 Address xxx yyyName Lastname,23 Address xxx yyy,Chicago XY 33056,Country name7th FloorName Lastname,23 Address xxx yyy,Chicago XY 33056,Country nameBrooklyn NY 11210Name Lastname,23 Address xxx yyy,Chicago XY 33056,Country nameCountry name to deeply equal Name Lastname\n23 Address xxx yyy\n7th Floor\nBrooklyn NY 11210\nCountry name
Edit 2: The solution that I found and works is this one:
.then(users => {
const billToAddress = users.response.body.filter(el => el.orderNumber === '3-331877')[0]
.billTo
cy.get('.address-row').each((item, index) => {
cy.log(cy.wrap(item).should('contain.text', billToAddress.split('\n')[index]))
})
})
Of course if somebody has a better way for achieving this test, I am open to learn more and code better.
Upvotes: 2
Views: 610
Reputation: 32062
If you make an array of the store data, an .each()
loop can compare them.
const store = Cypress.store.getState()
const reduxData = store.customerData // expect 'Name Lastname\n123 Address xxx yyy\nChicago XY 33056\nCountry name'
const reduxDataArray = reduxData.split('\n')
cy.contains('.customer-data-column', 'Title:')
.find('div') // only divs inside '.customer-data-column'
.each(($div, index) => {
expect($div.text()).to.eq(reduxDataArray[index])
})
From other comment, it looks like cy.get('.custom-data-column')
isn't strong enough to isolate this HTML you need to work on.
Perhaps cy.contains('.customer-data-column', 'Title:')
is better.
All text at once
In this particular case you can test all text at once by globally removing \n
const store = Cypress.store.getState()
const reduxData = store.customerData // expect 'Name Lastname\n123 Address xxx yyy\nChicago XY 33056\nCountry name'
const reduxAllTexts = reduxData.replace(/\n/g, '')
cy.contains('.customer-data-column', 'Title:')
.find('div')
.invoke('text')
.should('eq', reduxAllTexts)
Upvotes: 2
Reputation: 7165
If the Cypress function yields multiple elements, we can join the text of those elements to create your string.
cy.get('.custom-data-column').find('div').then(($divList) => {
const store = Cypress.store.getState();
const reduxPath = store.customerData;
const textArray = $divList.map((x) => x.text()); // get the text values as an array
const actual = textArray.join(textArray, '\n'); // use join to array of strings into single string
expect(actual).to.eql(reduxPath);
});
Upvotes: 0