1

I'm trying to understand how do i return a boolean from cypress page object?

Use case:

I am trying to check if an element is present on the page. If so, return a boolean.

Code:

class DataTable {
  constructor() {
     return this;
  }

  has(fieldName) {
    // HOW DO I RETURN A BOOLEAN HERE?
    return cy.get('.view-and-field-name').contains(fieldName)
  }
}

Mainpage.spec.js

const dataTable = new DataTable();
expect(dataTable.has(field.fieldName)).to.be.true;

I'd appreciate some insights on what I am doing wrong.

Thank you for the time.

TechnoCorner
  • 4,879
  • 10
  • 43
  • 81

3 Answers3

2

According to this post, and according to cypress suggestions for custom commands and page objects I suggest the next custom command:

Cypress.Commands.add("validateIfElementExistsInDom", (selector) => {
    cy.get('body')
        .then($body => {
            expect($body.find(selector).length > 0).to.be.true
        })
    
})

And you can use it in the test like :

cy.validateIfElementExistsInDom(fieldName)
    

And a general return boolean function example:

Cypress.Commands.add("validateIfElementExistsInDomAsBoolean", (selector) => {
   return cy.get('body')
        .then($body => {
            return cy.wrap($body.find(selector).length > 0) //Cy wrap is needed so the function is chainable
        })
})

//in test code
cy.validateIfElementExistsInDomAsBoolean(fieldName)
    .then(boolean => expect(boolean).to.be.true)

Rosen Mihaylov
  • 1,363
  • 2
  • 10
2

The expect() on Mainpage has already been executed internally in cy.get('.view-and-field-name').contains(fieldName), so it is redundant.

If dataTable.has(field.fieldName) fails, the test stops there - it will never pass out a false value.

If you want has(fieldName) to pass out a boolean, you need to switch to jquery inside, e.g

has(fieldName) {
  const jquerySelector = `.view-and-field-name:contains(${fieldName})`;
  return Cypress.$(jquerySelector);
}

But it is much simpler to go with Cypress commands and use

const dataTable = new DataTable();
dataTable.has(field.fieldName);

Personally, I'd ditch the page object and just use the command directly in the test.

Ackroydd
  • 1,482
  • 1
  • 13
  • 14
1

cy.get is not a synchronous function due to the retry-ability strategy, so there is no way to return Boolean directly.

If necessary, you can use variant of should with callback.

In your case, a simpler variant with exist is suitable (or be.visible, possibly more accurate for your case):

class DataTable {
  has(fieldName) {
    return cy.get('.view-and-field-name').contains(fieldName);
  }
}

const dataTable = new DataTable();
dataTable.getField(field.fieldName).should('exist');
z1ne2wo
  • 278
  • 1
  • 7