From 939ab7f1d7182f46c4dfa53c5e6c67e09a5bcd75 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Mon, 17 Oct 2022 22:41:23 -0400 Subject: [PATCH] fix: Subject does not exist assertion (#46) * add exist spec * fix: handle element not exist assertion --- cypress/e2e/exists.cy.js | 40 +++++++++++++++++++ src/index.js | 86 +++++++++++++++++++++------------------- 2 files changed, 86 insertions(+), 40 deletions(-) create mode 100644 cypress/e2e/exists.cy.js diff --git a/cypress/e2e/exists.cy.js b/cypress/e2e/exists.cy.js new file mode 100644 index 0000000..2f29b35 --- /dev/null +++ b/cypress/e2e/exists.cy.js @@ -0,0 +1,40 @@ +/// +// @ts-check + +import '../../src' + +beforeEach(() => { + cy.visit('cypress/index.html') +}) + +it('checks an element that exists', () => { + cy.get('#fruits') + .if('exist') + .then(cy.spy().as('if')) + .else() + .then(cy.spy().as('else')) + cy.get('@if').should('have.been.calledOnce') + cy.get('@else').should('not.have.been.called') +}) + +it('checks an element that does not exists', () => { + cy.get('#not-found') + .if('exist') + .then(cy.spy().as('if')) + .else() + .then(cy.spy().as('else')) + cy.get('@else').should('have.been.calledOnce') + cy.get('@if').should('not.have.been.called') +}) + +// https://github.com/bahmutov/cypress-if/issues/45 +it('checks an element that does not exists using not.exist', () => { + cy.get('#not-found').should('not.exist') + cy.get('#not-found') + .if('not.exist') + .then(cy.spy().as('if')) + .else() + .then(cy.spy().as('else')) + cy.get('@if').should('have.been.calledOnce') + cy.get('@else').should('not.have.been.called') +}) diff --git a/src/index.js b/src/index.js index 2b636f6..9c0a4f1 100644 --- a/src/index.js +++ b/src/index.js @@ -58,6 +58,48 @@ Cypress.Commands.add( let hasSubject = Boolean(subject) let assertionsPassed = true + const evaluateAssertion = () => { + try { + if (Cypress._.isFunction(assertion)) { + const result = assertion(subject) + if (Cypress._.isBoolean(result)) { + // function was a predicate + if (!result) { + throw new Error('Predicate function failed') + } + } + } else if ( + assertion.startsWith('not') || + assertion.startsWith('have') + ) { + const parts = assertion.split('.') + let assertionReduced = expect(subject).to + parts.forEach((assertionPart, k) => { + if ( + k === parts.length - 1 && + typeof assertionValue !== 'undefined' + ) { + assertionReduced = assertionReduced[assertionPart](assertionValue) + } else { + assertionReduced = assertionReduced[assertionPart] + } + }) + } else { + if (typeof assertionValue !== 'undefined') { + expect(subject).to.be[assertion](assertionValue) + } else { + expect(subject).to.be[assertion] + } + } + } catch (e) { + console.error(e) + assertionsPassed = false + if (e.message.includes('Invalid Chai property')) { + throw e + } + } + } + // check if the previous command was cy.task // and it has failed and it was expected if ( @@ -78,46 +120,10 @@ Cypress.Commands.add( assertionsPassed = false } } else if (hasSubject && assertion) { - try { - if (Cypress._.isFunction(assertion)) { - const result = assertion(subject) - if (Cypress._.isBoolean(result)) { - // function was a predicate - if (!result) { - throw new Error('Predicate function failed') - } - } - } else if ( - assertion.startsWith('not') || - assertion.startsWith('have') - ) { - const parts = assertion.split('.') - let assertionReduced = expect(subject).to - parts.forEach((assertionPart, k) => { - if ( - k === parts.length - 1 && - typeof assertionValue !== 'undefined' - ) { - assertionReduced = - assertionReduced[assertionPart](assertionValue) - } else { - assertionReduced = assertionReduced[assertionPart] - } - }) - } else { - if (typeof assertionValue !== 'undefined') { - expect(subject).to.be[assertion](assertionValue) - } else { - expect(subject).to.be[assertion] - } - } - } catch (e) { - console.error(e) - assertionsPassed = false - if (e.message.includes('Invalid Chai property')) { - throw e - } - } + evaluateAssertion() + } else if (subject === undefined && assertion) { + evaluateAssertion() + hasSubject = true } }