Stacey
Stacey

Reputation: 333

Lost in 'within()' in Cypress

Again I have a question regarding Cypress. I have many blocks of publication previews on the page, each block contains a header and several statuses of publication itself and its users, and I need to check the statuses of the certain blocks with the test. I can't use 'eq()' because data is dynamic and for some reasons the tests also don't run in the same order, therefore I often get the wrong publication by counting eq(). So I was trying to use 'within', but it fails.

My test:

cy.get('[data-test="list-item"]').within(() => {
      cy.get('[data-test="title-link"]')
        .contains('Empty text')
        .find('[data-test="status"]')
        .contains('Draft');
    });

I understand that my mistake is in 'contains()' because it tries to search in there, but as I mentioned above there's no other way for me to filter the elements other than by the titles. I need to check that block with title A has status 'Draft', block with title B has status 'Published' etc.

The code I'm trying to test (UPD: HTML, as react has too much unnecessary info):

<div class="list-item bg-white cursor-pointer" data-test="list-item">
<div class="content-grid grid grid-rows-1 sm:grid-cols-2">
<div>
<a data-test="title-link" class="leading-lg font-medium text-lg text-black" href="/edit/details/5ecf5deb49ec7431bca16759">Empty text</a>
</div>
<div class="text-right mt-4 sm:mt-0">
<div class="leading-caption font-medium" data-test="status">Draft</div>
<div class="mt-4" data-test="phase">
</div>
</div>
</div>
</div>

Upvotes: 2

Views: 367

Answers (1)

Richard Matsen
Richard Matsen

Reputation: 23483

If I'm following your React component structure correctly, I think you could test it like this

/*
 Specify the title-link by it's text, ensuring it's within a list-item 
*/
cy.contains('[data-test="list-item"] [data-test="title-link"]', 'Empty text')

   /*
     Now switch Cypress subject to list-item,
     using '.parents()' instead of '.parent()' 
     in case React has added some layers between title-link and list-item.
   */
   .parents('[data-test="list-item"]')

    /*
      Now restrict search to target list-item
   */
   .within(() => {

      cy.contains('[data-test="status"]', 'Draft');   

});

The command cy.contains(selector, content) has the added benefit of retying when content is async.

REF: parents()

Upvotes: 3

Related Questions