Cypress: lenght of an invisble array

Viewed 407

I know this will be a long questing and I do apologize for it.

TL:TR I'm starting to learn Cypress and I stumbled upon a problem. I got a list which is higly dinamic (meaning that it can and it will have zero elements from time to time) and I want know its length to make some assertions. The thing is that when it has zero elements, Cypress is falling to get this DOM element. I have no idea how to assert if the array is empty before trying to .get() it. Any clue on how to do it? Thank you in advance!

The post

I want to follow this logic To check if an item was added to the list:

  • Get array length, save it into a variable. (Need to learn how to)
  • Add an item (this hasn't been of any problem)
  • Get new array length, compare it. If new == old + 1, then it was added.

HTML5 (This code HAS an item into the list)

<section id="main" style="display: block;">
  <input id="toggle-all" type="checkbox">
  <label for="toggle-all">Mark all as complete</label>
  <ul id="todo-list">
    <li>
      <div class="view">
        <input class="toggle" type="checkbox">
        <label>a</label>
        <button class="destroy"></button>
      </div>
      <input class="edit" value="a">
    </li>
  </ul>
</section> 

HTML5 (This code HAS NOT an item into the list)

<section id="main" style="display: none;">
  <input id="toggle-all" type="checkbox">
  <label for="toggle-all">Mark all as complete</label>
  <ul id="todo-list"></ul>
</section>

Cypress

cy.get('#todo-list').find('.view').each(($el, i) =>
{
  cont = i + 1;
  cy.log(cont);
})

This approach is clearly not working for many reasons. First of all if the list has zero elements, Cypress does not find it and I cannot proceed. And if it does, later on into the '>' statement my var cont is 0. I'm sure I'm messing something up.

This is the app, so you can see the html and I can keep this post as short as I can: Todo List

I've been also trying another approach with the footer > todo-count element and it's working while the list has an element into it. My problem is again when I doesn't:

cy.get('#todo-count').then(($el1) =>{
  const prev = parseFloat($el1.text())
  cy.log(prev)

  {Here I add the item}

  cy.get('#todo-count').invoke('text').then(parseFloat).should('be.gt', prev)
})

Again, if the element is not visible Cypress will not find it. Tried if/else with $el.css('display') == 'block' and .is(":visible") but I'm not getting it.

2 Answers

I don't know what's happened to the footer and the #id-count, but don't use it. Count the elements yourself

it('adds an item to the list', () => {

  cy.get('ul').then($list => {

    const initialCount = $list.find('li').length;
    expect(initialCount).to.eq(0)

    {Here add the item}

    // const afterAddingCount = $list.find('li').length;
    // expect(afterAddingCount).to.eq(1);

    // This is better
    cy.get('ul li')
      .should('have.length', 1);    // retry on this if animation, etc
     
  })
})

it('updates the todo-count display', () => {

  // show the HTML for the footer 
  // before and after adding an item
  // then can add a test here

})

This is how I think you should test the list counter

it('updates the todo-count display', () => {

  cy.get('#footer')
    .should('have.css', 'display', 'none')

  cy.get('#todo-count')
    .should('not.exist')                    // verify counter is not present

  // {Here add the item}

  cy.get('#footer')
    .should('have.css', 'display', 'block')

  cy.get('#todo-count')
    .should('exist')                       // now the counter exists
    .invoke('text')
    .should('include', '1')                // and its value is '1'
})
Related