cypressassertion

How can I chain commands in a useful way?


I want to assert the following structure:

<app-toggler data-cy="toggler">
  <button id="1" data-cy="1">
    <rows data-cy="rows">
      <span>Title</span>
     </rows>
    <textarea>
      <text-rows data-cy="textarea">
        <div title="Value1" data-cy="app-textarea-val1">
          <span>Value1</span>
         </div>
         <div title="Value2" data-cy="app-textarea-val2"><!---->
          <span>Value2</span>
         </div>
         <div title="Value3" data-cy="app-textarea-val3">
          <span>Value3</span>
         </div>
        </text-rows>
       </textarea>
   </button>
   <button id="2" data-cy="2">
    <rows data-cy="rows">
      <span>Titletwo</span>
     </rows>
    <textarea>
      <text-rows data-cy="textarea">
        <div title="Value1two" data-cy="app-textarea-val1">
          <span>Value1two</span>
         </div>
         <div title="Value2two" data-cy="app-textarea-val2"><!---->
          <span>Value2two</span>
         </div>
         <div title="Value3two" data-cy="app-textarea-val3">
          <span>Value3two</span>
         </div>
        </text-rows>
       </textarea>
   </button>
 </app-toggler>

I want to know, if e.g. :

"Title, Value1, Value2, Value3"isOneOf.Buttons.Text()

examples:

"Title, Value1, Value2, Value3".isOneOf.Buttons.Text() => true "Titletwo, Value1, Value2, Value3".isOneOf.Buttons.Text() => false "Title, Value1two, Value2three, Value3four".isOneOf.Buttons.Text() => false

It's unclear to me how to chain commands in a correct and useful way to get the required information right. I hope I described it correctly.


Solution

  • For the text you basically chain .should('contain', ...).and('contain', ...) assertions, e.g

    cy.get('button#1')
      .invoke('text')
      .should('contain', 'Value1')
      .and('contain', 'Value2')
      .and('contain', 'Value3')
    

    where .invoke('text') is getting the full text of all the children of the button and using .should('contain', ...) is effectively chopping up the combined text and looking for individual values.

    If you want to be more precise, for example the text contains other text i.e Value1two contains Value1 so it's a double match, you need to work with the spans.

    const values = ['Title', 'Value1', 'Value2', 'Value3']
    cy.get('button#1')
      .find('span')
      .each(($span,i) => {
        cy.wrap($span).invoke('text').should('eq', values[i])
      })
    

    This also checks the ordering is correct.

    If you're not checking text but say title=... attributes you need to extract those instead

    const values = ['Title', 'Value1', 'Value2', 'Value3']
    cy.get('button#1')
      .find('span')
      .each(($span,i) => {
        cy.wrap($span).attr('attr', title).should('eq', values[i])
      })