I'm trying to test whether an attribute that is shared by 3 elements has one of several values. Here's the html:
<div class="wrapper">
<a title="value 1"</a>
<a title="value 2"</a>
<a title="value 3"</a>
</div>
I need a way to assert that the title
attribute of all three elements will have one of the 3 values, because their order might change in the future but I just need to make sure that they're there.
Here's what I've tried but didn't work for me:
cy.get('.wrapper')
.children().as('socialLinks');
cy.get('@socialLinks')
.should('have.attr', 'title').as('title');
expect('@title').to.contain.oneOf('value 1', 'value 2', 'value 3');
I suspect it might need a for-loop
but I can't wrap my head around how to approach it.
A for-loop is possible but can cause problems in a Cypress test (search SO questions for some examples).
There is the .each()
command which performs the for-loop in a Cypress-friendly way
cy.get('.wrapper').children()
.each(($el) => {
const title = $el.attr('title')
expect(title).to.be.oneOf(['value 1', 'value 2', 'value 3'])
})
But if the values are loaded from an API, you should replace the expect()
with a should()
to make sure the test retries until loading is complete.
cy.get('.wrapper').children()
.each(($el) => {
cy.wrap($el).invoke('attr', 'title')
.should('be.oneOf', ['value 1', 'value 2', 'value 3'])
})