How to check that element has either of classes in Cypress?

橙三吉。 提交于 2021-01-03 08:01:08

问题


We search for an invalid element as following:

const invalidClasses = '.invalid, .invalid-default';

getInvalidElement() {
    cy.get(invalidClasses)
};

Now I have another function which accepts the element and checks if it has the invalid classes:

isInvalid(selector) {
 return cy.get(selector).should('have.class','invalid');
}

How can I check that the element has any of the two classes?

I know I can do

cy.get(selector).invoke('attr','class').should('match','/invalid/');

But what if the classes were different?

(Also the conditional testing does not apply to this case, there is no logic whether it's the first of the classes or the second one, we just want more abstract class for reusing)


回答1:


Cypress .should() wraps chai assertions, so from how to do an “or” in chai should

the following html fragment

<div id="1" class="class1"></div>
<div id="2" class="class2"></div>
<div id="3" class="class1 class2"></div>
<div id="4" class="class3"></div>

can be tested like this

it('finds either class1 or class2', () => {

  cy.get('div#1')
    .should('satisfy', ($el) => {
      const classList = Array.from($el[0].classList); 
      return classList.includes('class1') || classList.includes('class2') // passes
    }) 

  cy.get('div#2')
    .should('satisfy', ($el) => {
      const classList = Array.from($el[0].classList); 
      return classList.includes('class1') || classList.includes('class2') // passes
    }) // passes

  cy.get('div#3')
    .should('satisfy', ($el) => {
      const classList = Array.from($el[0].classList); 
      return classList.includes('class1') || classList.includes('class2') // passes
    }) 

  cy.get('div#4')
    .should('satisfy', ($el) => {
      const classList = Array.from($el[0].classList); 
      return classList.includes('class1') || classList.includes('class2') // fails
    }) 

})

Notes

  • the param to the function is a jquery object, so use $el[0] to reference the element
  • $el[0].classList return a DomTokenList which is array-like, so use Array.from() to apply the Array method .includes() to it.

You can also make things a bit more generic by extracting the function,

it('finds either class1 or class2', () => {

  const hasAtLeastOneClass = (expectedClasses) => {
    return ($el) => {
      const classList = Array.from($el[0].classList); 
      return expectedClasses.some(expectedClass => classList.includes(expectedClass));
    }
  }

  cy.get('div#1').should('satisfy', hasAtLeastOneClass(['class1', 'class2']));  //passes

  cy.get('div#2').should('satisfy', hasAtLeastOneClass(['class1', 'class2']));  //passes

  cy.get('div#3').should('satisfy', hasAtLeastOneClass(['class1', 'class2']));  //passes

  cy.get('div#4').should('satisfy', hasAtLeastOneClass(['class1', 'class2']));  //fails

})



回答2:


Cypress should provides and method which takes previous subject(locator) and you can apply as many as conditions with and method.

cy.get('locator')
.should('have.class', 'validClassname')
.and('not.have.class', 'invalidClassname');

I hope this will solve your problem... Vote up this answer to reach more people.



来源:https://stackoverflow.com/questions/62004904/how-to-check-that-element-has-either-of-classes-in-cypress

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!