Cypress: Temporarily escape from a cy.within() using document().its()

Profile picture for user arilio666

In cypress, there is a way to escape from within scope temporarily. Let us first see what within is.

  • Within command in cypress is a way to isolate the child elements from the parent, or it provides a way of getting the child element from the parent element within a specific scope. 
  • It is used to fetch the scope of all subsequent elements within a particular component of technical terms.

So traversing outside is scope to search and operate on other elements is quite impossible.
Let us try to do that and see how that fails.

For this article's purpose, we will automate our traditional http://autopract.com/#/home/fashion page.

Here are the test steps:

  1. Visit the site.
  2. Close popup.
  3. Scrolldown to the subscribe section
  4. Isolate the form using the 'within' command.
  5. Type in email id.

Inside the within scope, try to assert text element outside the form scope, which should contain "Never Miss Anything From Multikart By Signing Up To Our Newsletter."

The test looks simple enough, right? Let us try to assert that text element from inside within scope typically.

Here is our DOM structure:

<div _ngcontent-serverapp-c70="" xpath="1"><h4 _ngcontent-serverapp-c70="">KNOW IT ALL FIRST!</h4><p _ngcontent-serverapp-c70="">Never Miss Anything From Multikart By Signing Up To Our Newsletter. </p></div>
<form _ngcontent-serverapp-c70="" novalidate="" action="https://pixelstrap.us19.list-manage.com/subscribe/post?u=5a128856334b598b395f1fc9b&amp;id=082f74cbda" target="_blank" method="post" class="form-inline subscribe-form ng-untouched ng-pristine ng-valid" xpath="1"><div _ngcontent-serverapp-c70="" class="form-group mx-sm-3"><input _ngcontent-serverapp-c70="" type="email" name="EMAIL" id="mce-EMAIL" placeholder="Enter your email" class="form-control"></div><button _ngcontent-serverapp-c70="" type="submit" id="subscribeBtn" onclick="subscribe()" class="btn btn-solid">subscribe</button></form>
  • Once inside the form tag using within, we need to somehow get out of its scope and assert the above outside 'p' tag element.
describe('Automate AutoPract',()=>{
    it('Should load the url',()=>{
        cy.visit('http://www.autopract.com/#/home/fashion')
        //cy.url().contains('include','home')
        
    })
    it('Should click POPUP',()=>{
        cy.get('.close').click()

    })
    it('Should click Side bar',()=>{

        cy.get('#mce-EMAIL').scrollIntoView()
        cy.get('form').within(()=>{
            cy.get('p').should('contain','Never Miss Anything From Multikart By Signing Up To Our Newsletter.')
            cy.get('#mce-EMAIL').type('blue@gmail.com')
        })
    })
})
  • So we have used a simple get command to fetch the 'p' element, and using should we are asserting that it should contain 'Never Miss Anything From Multikart By Signing Up To Our Newsletter.'

Let's run this.

  • From the output, we can see that it failed.
  • Then it can't find the element 'p' as it is outside the scope of the form tag.

Now the way to do this is by using cy.document().its('body').

  • This will help us traverse outside the entire DOM and not get constrained inside within scope.

Let us see this in action then!!

describe('Automate AutoPract',()=>{
    it('Should load the url',()=>{
        cy.visit('http://www.autopract.com/#/home/fashion')
        //cy.url().contains('include','home')
        
    })
    it('Should click POPUP',()=>{
        cy.get('.close').click()

    })
    it('Should click Side bar',()=>{

        cy.get('#mce-EMAIL').scrollIntoView()
        cy.get('form').within(()=>{
            cy.document().its('body').find('p').should('contain','Never Miss Anything From Multikart By Signing Up To Our Newsletter.')
            cy.get('#mce-EMAIL').type('mama@gmail.com')
        })
    })
})
  • We have called the document command and using 'its' command we've also called the entire body to temporarily escape the 'within' scope and assert the condition.

Let us check the result.

  • So using this method, we can see that it has successfully traversed out the context of the 'within' using the cy.document().its('body') temporarily.