cypress

Expect is failing but test is passing in cy.on confirm & alert message


I wanted to test my content of the confirmation message but it seems that even if my test fails my case passes

it('Should Get Confirm Message', () => {
        cy.get('.button')
            .click();
        cy.on('window:confirm', str => {
            expect(2 + 2).to.equal(5);
        })
    })

Image of my test


Solution

  • I actually can't reproduce this, but Cypress events are generally considered to be outside the regular test flow (the cy.on(eventName) is not a command, despite the method being on the cy object, and so it's not added to the Command queue and isn't properly awaited).

    What this means is that the window:confirm may be invoked after the test has already finished (which seems to be your case --- perhaps the click handler calls the window.confirm asynchronously?).

    The expectation still bubbles through to (and is displayed in) the Command log, but it has no effect on the test outcome.

    One thing you can do is to await the event using a proper command flow:

    describe('test', () => {
      it('test', () => {
    
        const confirmMessage = 'oi!';
    
        // (1) setup (for demonstration only)
        // -------------------------------------------------------
    
        cy.window().then(win => {
          win.document.body.innerHTML = '<button class="btn">Click me</button>';
          win.document.body.querySelector('.btn')
            .addEventListener('click', () => {
              setTimeout(() => {
                win.confirm(confirmMessage);
              }, 500 );
            });
        });    
    
        // (2) actual test code
        // -------------------------------------------------------
    
        cy.get('.btn').click();
        cy.wrap(new Promise((resolve, reject) => {
          cy.on('window:confirm', msg => {
            try {
              expect(msg).to.eq(confirmMessage);
            } catch ( err ) {
              return reject(err);
            }
            resolve();
          });
          // set a timeout to ensure we don't wait forever
          setTimeout(() => {
            reject(new Error('window.confirm wasn\'t called within 4s'));
          }, 4000);
        }), { log: false });
    
      });
    });