skip to Main Content

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.

2

Answers


  1. If you wanted to check if all 3 possible values are existent, no matter the order, AFAIS the simplest attempt would be just checking for existence:

    cy.get('.wrapper a[title="value 1"]');
    cy.get('.wrapper a[title="value 2"]');
    cy.get('.wrapper a[title="value 3"]');
    

    I never used cypress though and i´m not sure if thats actually what you are looking for.

    Login or Signup to reply.
  2. 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'])
      })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search