How to proper Conditional Testing

283 Views Asked by At

I just want to ask how to properly conditional testing? I have this code here

    cy.get('[data-slug="add-to-any"] > .plugin-title > strong').then(($slug) => {
      if (expect($slug).not.to.exist){
         //It will passed
      }else if (expect($slug).to.exist){
        cy.get('#deactivate-add-to-any').should('not.exist')
      }

I assert the element to not.to.exist, but it gives me this error

Expected to find element: [data-slug="add-to-any"] > .plugin-title > strong, but never found it.

I am really lost what assertions I need to use.

2

There are 2 best solutions below

1
On BEST ANSWER

The ideal way (if it works in your scenario) is to shift the last selector inside the .then()

cy.get('[data-slug="add-to-any"] > .plugin-title')
  .then(($pluginTitle) => {

    const $slug = $pluginTitle.find('strong');  // this finds with jQuery 
                                                // which won't fail the test 
                                                // if not found

    if ($slug.length === 0) {  // not found

    } else {
      cy.get('#deactivate-add-to-any').should('not.exist')
    }
  })

It's not 100% fool-proof, if $slug is loaded asynchronously (say via fetch) it won't be there immediately and the test might pass when in fact the $slug turns up 100 ms after the test runs.

You need to understand the way the app works to really be sure.


Cypress docs show this pattern, using <body> as the "stable" element (always present after page load).

cy.get('body').then($body => {
  const slug = $body.find('[data-slug="add-to-any"] > .plugin-title > strong')
  if ($slug.length) {
      ...

It's less than ideal because the page might have <body> but still be fetching elements inside it.

Best practice IMO is to try the immediate parent element of the conditional one. If that is also conditional, move up the element tree until you find an element that is stable/present at that point in you test.

Or add a guard condition that waits for page fetch to complete. A cy.intercept() is useful for that, or even just this

cy.get('[data-slug="add-to-any"] > .plugin-title')
  .should('be.visible')            // retries until .plugin-title is showing
  .then(($pluginTitle) => {
    const $slug = $pluginTitle.find('strong')
    if ($slug.length === 0) {  
      ...
1
On

Simple example

cy.get("body").then($body => {
    if ($body.find('[data-slug="add-to-any"] > .plugin-title').length > 0) {   
   
        cy.get('[data-slug="add-to-any"] > .plugin-title').then($title => {
          if ($title.is(':visible')){
            //you get here only if it EXISTS and is VISIBLE
          } 
        });
    } else {
       //you get here if the it DOESN'T EXIST
        cy.get('#deactivate-add-to-any').should('not.exist')
    }
});