Search code examples
cypressstubstubbing

How do I stub 'prompt' method twice in my cypress test?


In one test I have to call two stubs in one test but I end up calling first one only.

My test should first create a folder and then rename it. It involves two out-of-cypress prompts which I am stubbing.

Here is folder creation method. It works perfectly fine in a test where I should only create a folder:

 addFolder(folderName) {
    let stub;

    cy.window().then(win => {
      stub = cy.stub(win, 'prompt').returns(folderName)  // types this value 
    })
    
    cy.get(this.addFolderButtonLocator).click()
    
    cy.wrap(stub).should(() => {
      expect(stub).to.have.been.calledWith()
    })

    return this;

  }

Here is folder rename method (calls only stub from first method)

rename(name, newName) {
   
    let stub;

    cy.window().then(win => {
      stub = cy.stub(win, 'prompt').returns(newName)  // types this value 
    })
    
    this.invokeSideMenu(name);
    cy.get(`[data-cy="${name}-rename"]`).click();
    
    cy.wrap(stub).should(() => {
      expect(stub).to.have.been.calledWith()
    })

    return this;
  }

When I attempt to create and then rename a folder, It only runs first stub and an error 'Attempted to wrap prompt which is already wrapped'

What mistake have I done in my code and how do I run 'prompt' stub twice in one test as i have two different prompts?


Solution

  • There is a stub.restore() method that resets the win.prompt to it's original value, which you can use after the stub has been checked.

    This limits the scope of the stub to each addFolder/rename call. Normally the stub is active until reset at the end of the test by Cypress.

    For example

    function addFolder(folderName) {
      let stub
      cy.window().then(win => {
        stub = cy.stub(win, 'prompt').returns(folderName)
      })
    
      // Invoking the stub
      cy.window().then(win => win.prompt('Adding'))
    
      cy.wrap(stub).should(() => {
        expect(stub).to.have.been.calledWith('Adding')
        stub.restore()
      })
    }
    
    function rename(name, newName) {
      let stub
      cy.window().then(win => {
        stub = cy.stub(win, 'prompt').returns(newName) // types this value
      })
    
      // Invoking the stub
      cy.window().then(win => win.prompt('Renaming'))
    
      cy.wrap(stub).should(() => {
        expect(stub).to.have.been.calledWith('Renaming')
        stub.restore()
      })
    }
    
    addFolder('my-new-folder')
    rename('my-new-name')
    

    enter image description here