From c734ee44737b2771b7539b45967c7bcc8f5fa4e8 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Fri, 19 Jan 2024 09:51:48 -0500 Subject: [PATCH] feat: support cy.not previous command (#76) * feat: support cy.not previous command * update Cy v11 --- README.md | 2 +- cypress/e2e/exists.cy.js | 18 ++++++++++++++++++ src/index-v11.js | 23 +++++++++++++++++++++++ src/index.js | 23 +++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d84aab..e2e5bbb 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Tested with `cy.get`, `cy.contains`, `cy.find`, `.then`, `.within` commands in C ## ⚠️ Warning -In general, Cypress team considers [conditional testing an anti-pattern](https://on.cypress.io/conditional-testing). Thus `cypress-if` should be used only if the test really cannot deterministically execute its steps. +In general, Cypress team considers [conditional testing an anti-pattern](https://on.cypress.io/conditional-testing). Thus `cypress-if` should be used only if the test really cannot deterministically execute its steps. You can also read my [conditional testing](https://glebbahmutov.com/cypress-examples/recipes/conditional-testing.html) examples. ## No xpath support diff --git a/cypress/e2e/exists.cy.js b/cypress/e2e/exists.cy.js index 7459d36..8919ca3 100644 --- a/cypress/e2e/exists.cy.js +++ b/cypress/e2e/exists.cy.js @@ -58,3 +58,21 @@ it('uses exists as an alias to exist', () => { cy.get('@if').should('have.been.calledOnce') cy.get('@else').should('not.have.been.called') }) + +it('supports cy.not', () => { + cy.log('**IF path**') + cy.get('#fruits li') + .not(':odd') + .if('exists') + .log('found even') + .else() + .raise('it is odd') + + cy.log('**ELSE path**') + cy.get('#fruits li') + .not('li') + .if('exists') + .raise('cy.not is not supported') + .else() + .log('cy.not is supported') +}) diff --git a/src/index-v11.js b/src/index-v11.js index a0a8c78..bfc63e7 100644 --- a/src/index-v11.js +++ b/src/index-v11.js @@ -289,6 +289,29 @@ Cypress.Commands.overwrite( }, ) +Cypress.Commands.overwrite('not', function (notCommand, prevSubject, selector) { + debug('cy.not args', { prevSubject, selector }) + + const cmd = cy.state('current') + debug(cmd) + const next = cmd.attributes.next + + if (next && next.attributes.name === 'if') { + // disable the built-in assertion + return notCommand(prevSubject, selector).then( + (getResult) => { + debug('internal cy.not result', getResult) + return getResult + }, + (noResult) => { + debug('no cy.not result', noResult) + }, + ) + } + + return notCommand(prevSubject, selector, text, options) +}) + Cypress.Commands.overwrite( 'find', function (find, prevSubject, selector, options) { diff --git a/src/index.js b/src/index.js index b69e2a0..626c085 100644 --- a/src/index.js +++ b/src/index.js @@ -359,4 +359,27 @@ if (major < 12) { ) throw e }) + + Cypress.Commands.overwriteQuery('not', function (notCommand, selector) { + debug('cy.not args', { selector }) + + const cmd = cy.state('current') + debug(cmd) + const next = cmd.attributes.next + const innerFn = notCommand.call(this, selector) + + if (isIfCommand(next)) { + // disable the built-in assertion + return (subject) => { + const res = innerFn(subject) + if (res.length) { + debug('internal not result', res) + return res + } + debug('no not result') + } + } + + return (subject) => innerFn(subject) + }) }