automated-testscypress

Cypress can't find an element that actually exists


During my testing inside of SAP Hybris I've met an issue with the component I believed that nothing can go wrong. Namely it is a simple component containing the Description for the item (promotion in this case).
Here is my initial cypress command:

cy.get('.ye-input-text.ye-com_hybris_cockpitng_editor_defaulttext.z-textbox')
    .should('have.value', 'All users are able to try a ZYN can as a free sample (or free gift). Limited to 1 per registered user');

With this command I've received the following issue:

enter image description here

enter image description here

Now, as much I understand it, it suggests that there are multiple elements on the page containing the same class name (which is lets say true), but in that case I would expect for example the choose multiple elements error or the one suggesting to use the .eq() command or so. Although from the error message I understand that Cypress went through all 9 elements it found with the given class name but none contained the value requested.

Here is the HTML of the element I'm referring to:

<div id="p41H029" class="yw-loceditor-row ye-validation-none z-div">
<span id="p41H129" style="display:none;" class="yw-loceditor-row-locale z-label" title="English">en</span>
<div id="p41H229" class="yw-loceditor-row-editor z-div"><div id="p41H329" class="z-div">
<input id="p41H429" class="ye-input-text ye-com_hybris_cockpitng_editor_defaulttext z-textbox" value="All users are able to try a ZYN can as a free sample (or free gift). Limited to 1 per registered user" type="text" aria-disabled="false" aria-readonly="false"></div></div></div>

Another Cypress command I've tried out is this one (but it didn't work):

cy.contains('All users are able to try a ZYN can as a free sample (or free gift). Limited to 1 per registered user')
  .parents('.yw-loceditor-row.z-div') // Go up to the parent row
  .find('input') // Then find the input
  .should('have.value', 'All users are able to try a ZYN can as a free sample (or free gift). Limited to 1 per registered user');
                });
            });

Solution

  • The short answer is, be a bit more specific in the selection of the one <input> that has this value.

    You can see in the message

    assert expected [ <input#p41H429.ye-input-text.ye-com_hybris_cockpitng_editor_defaulttext.z-textbox>, 8 more... ]

    which means there are nine elements selected in total.

    If I run a similar test, with three inputs and the value I want is on the second input, it fails when comparing the value of the first input.

    <input 
      class="ye-input-text ye-com_hybris_cockpitng_editor_defaulttext z-textbox"
      value="Some promotion"
    />
    <input
      class="ye-input-text ye-com_hybris_cockpitng_editor_defaulttext z-textbox"
      value="My specific promotion"
    />
    <input
      class="ye-input-text ye-com_hybris_cockpitng_editor_defaulttext z-textbox"
      value="Some other promotion"
    />
    
    cy.get('.ye-input-text.ye-com_hybris_cockpitng_editor_defaulttext.z-textbox')
      .should('have.value', 'My specific promotion');
    

    enter image description here

    If I make the selection more specific, by using the [value="..."] selector, so only one element is selected - it passes.

    cy.get(`.ye-input-text[value="My specific promotion"]`)
      .should('have.value', 'My specific promotion');
    

    You can also use other selectors such as eq(1) to pick just one <input> element to test.

    enter image description here


    What's the rule?

    When you use .should('have.value', ...) following a cy.get() that returns multiple elements, it's equivalent to

    cy.get(...)                     // multiple elements selected
      .invoke('val')                // extract value of only the first element 
      .should('eq', 'some value')   // test the value
    

    So only the first element gets tested, the rest are ignored.
    The above is the "standard" way to test a value of an input.