OR Attributes assertion
You can watch the explanation for this recipe in the video Check One Of Several Attributes Or Its Values.
One of several possible attributes
Let's confirm that an element we found has an attribute X OR has an attribute Y.
<div id="person1" data-name="A">first person</div>
<div id="person2" data-job="B">second person</div>
<!-- this element lacks the attributes we are looking for -->
<div id="person3">third person</div>
We want to confirm the given element either has the data-name
attribute or has the data-job
attribute. We can write such non-deterministic logic using should(callback)
function.
function hasAttribute($el) {
// check the presence of an attribute
// using the DOM Element "hasAttribute" method
if (
$el[0].hasAttribute('data-name') ||
$el[0].hasAttribute('data-job')
) {
// all good, the element has one of the attributes
} else {
throw new Error('Missing the required attributes')
}
}
cy.get('#person1').should(hasAttribute)
cy.get('#person2').should(hasAttribute)
// enable to see a failed assertion
// cy.get('#person3').should(hasAttribute)
One of several possible values
Let's say we are looking for an attribute, but it can have multiple values.
<div id="person1" data-name="Joe">first person</div>
We want to confirm the data-name
attribute is either "Joe" or "Mary". We can get the attribute's value using have.attr name
assertion, which yields the value, and then apply the be.oneOf
assertion.
cy.get('#person1')
.should('have.attr', 'data-name')
// yields the "data-name" attribute's value
.should('be.oneOf', ['Joe', 'Mary'])
One of several possible values with retries
Even when chaining the assertions, they still apply to the same element. Thus even if the expected value of the attribute is set later, the test still finds it correctly.
<div id="person1" data-name="Bob">first person</div>
<script>
setTimeout(() => {
document
.getElementById('person1')
.setAttribute('data-name', 'Mary')
}, 1000)
</script>
cy.get('#person1')
.should('have.attr', 'data-name')
// yields the "data-name" attribute's value
.should('be.oneOf', ['Joe', 'Mary'])