diff --git a/README.md b/README.md index 6a42c42..30427df 100644 --- a/README.md +++ b/README.md @@ -127,15 +127,17 @@ A function that must return a truthy value when the wait is over. Pass in an options object to change the default behavior of `cy.waitUntil()`. -| Option | Default | Description | -| --------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `errorMsg` | `Timed out retrying` | The error message to write. | -| `timeout` | `5000` | Time to wait for the `checkFunction` to return a truthy value before throwing an error. | -| `interval` | `200` | Time to wait between the `checkFunction` invocations. | -| `description` | `waitUntil` | The name logged into the Cypress Test Runner. | -| `logger` | `Cypress.log` | A custom logger in place of the default [Cypress.log](https://docs.cypress.io/api/cypress-api/cypress-log.html). It's useful just for debugging purposes. | -| `log` | `true` | Enable/disable logging. | -| `customMessage` | `undefined` | String logged after the `options.description`. | +| Option | Default | Description | +| -------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `errorMsg` | `"Timed out retrying"` | The error message to write. | +| `timeout` | `5000` | Time to wait for the `checkFunction` to return a truthy value before throwing an error. | +| `interval` | `200` | Time to wait between the `checkFunction` invocations. | +| `description` | `"waitUntil"` | The name logged into the Cypress Test Runner. | +| `logger` | `Cypress.log` | A custom logger in place of the default [Cypress.log](https://docs.cypress.io/api/cypress-api/cypress-log.html). It's useful just for debugging purposes. | +| `log` | `true` | Enable/disable logging. | +| `customMessage` | `undefined` | String logged after the `options.description`. | +| `verbose` | `false` | If every single check result must be logged. | +| `customCheckMessage` | `undefined` | Like `customMessage`, but used for every single check. Useless if `verbose` is not set to `true`. |

diff --git a/cypress/integration/plugin.spec.js b/cypress/integration/plugin.spec.js index 8e9fa88..cdc98aa 100644 --- a/cypress/integration/plugin.spec.js +++ b/cypress/integration/plugin.spec.js @@ -263,4 +263,54 @@ context("Cypress Wait Until", () => { expect(spy).not.to.have.been.called; }); }); + + it("Should log verbosely every single check", () => { + let checks = 0; + const checkFunction = () => { + checks++; + return checks > 1; + }; + + const logger = { + log: (...params) => Cypress.log(...params) + }; + const spy = cy.spy(logger, "log"); + const options = { logger: logger.log, verbose: true }; + + cy.waitUntil(checkFunction, options).then(() => { + const calls = spy.getCalls(); + const expected = [ + { + name: "waitUntil" + }, + { + name: "waitUntil", + message: "false" + }, + { + name: "waitUntil", + message: "true" + } + ]; + expect(calls).to.have.lengthOf(expected.length); + for (let n = calls.length, i = 0; i < n; i++) { + expect(calls[i].args[0]).deep.include(expected[i]); + } + }); + }); + + it("Should accept a `customCheckMessage` option", () => { + const checkFunction = () => true; + + const logger = { + log: (...params) => Cypress.log(...params) + }; + const spy = cy.spy(logger, "log"); + const customCheckMessage = "custom message check"; + const options = { logger: logger.log, verbose: true, customCheckMessage }; + + cy.waitUntil(checkFunction, options).then(() => { + expect(spy.getCalls()[1].args[0].message.toString()).to.include(customCheckMessage); + }); + }); }); diff --git a/cypress/types/plugin.spec.js b/cypress/types/plugin.spec.js index 9a3685b..5be3dce 100644 --- a/cypress/types/plugin.spec.js +++ b/cypress/types/plugin.spec.js @@ -71,35 +71,21 @@ cy.waitUntil( }, { errorMsg: "Custom error message" } ); -cy.waitUntil( - function() { - return true; - }, - { description: "Custom description" } -); -cy.waitUntil( - function() { - return true; - }, - { - logger: ({ name, message, consoleProps }) => { - console.log({ name, message, consoleProps }); - } +cy.waitUntil(() => true, { description: "Custom description" }); +cy.waitUntil(() => true, { + logger: ({ name, message, consoleProps }) => { + console.log({ name, message, consoleProps }); } -); -cy.waitUntil( - function() { - return true; - }, - { - log: false - } -); -cy.waitUntil( - function() { - return true; - }, - { - customMessage: "custom message" - } -); +}); +cy.waitUntil(() => true, { + log: false +}); +cy.waitUntil(() => true, { + customMessage: "custom message" +}); +cy.waitUntil(() => true, { + verbose: true +}); +cy.waitUntil(() => true, { + customCheckMessage: "custom check message" +}); diff --git a/index.d.ts b/index.d.ts index baefabd..98c56a9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,6 +8,8 @@ interface WaitUntilOptions { errorMsg?: string; description?: string; customMessage?: string; + verbose?: boolean; + customCheckMessage?: string; logger?: (WaitUntilLog) => any; log?: boolean; } diff --git a/src/index.js b/src/index.js index 83c636b..bd0aaaa 100644 --- a/src/index.js +++ b/src/index.js @@ -1,46 +1,65 @@ "use strict"; -// log generico del comando <- da testaree √ e documentare X + nuova options logger X -// agiungere un log verboso per debug +const logCommand = ({ options, originalOptions }) => { + if (options.log) { + options.logger({ + name: options.description, + message: options.customMessage, + consoleProps: () => originalOptions + }); + } +}; +const logCommandCheck = ({ result, options, originalOptions }) => { + if (!options.log || !options.verbose) return; -function waitUntil(subject, checkFunction, options = {}) { + const message = [result]; + if (options.customCheckMessage) { + message.unshift(options.customCheckMessage); + } + options.logger({ + name: options.description, + message, + consoleProps: () => originalOptions + }); +}; + +const waitUntil = (subject, checkFunction, originalOptions = {}) => { if (!(checkFunction instanceof Function)) { throw new Error("`checkFunction` parameter should be a function. Found: " + checkFunction); } + const defaultOptions = { + // base options interval: 200, timeout: 5000, errorMsg: "Timed out retrying", + + // log options description: "waitUntil", log: true, customMessage: undefined, - logger: Cypress.log + logger: Cypress.log, + verbose: false, + customCheckMessage: undefined }; + const options = { ...defaultOptions, ...originalOptions }; - const o = { ...defaultOptions, ...options }; + // filter out a falsy passed "customMessage" value + options.customMessage = [options.customMessage, originalOptions].filter(Boolean); - o.customMessage = [options.customMessage, options].filter(Boolean); + let retries = Math.floor(options.timeout / options.interval); - let retries = Math.floor(o.timeout / o.interval); - - if (o.log) { - o.logger({ - name: o.description, - message: o.message, - consoleProps: () => ({ - options - }) - }); - } + logCommand({ options, originalOptions }); const check = result => { + logCommandCheck({ result, options, originalOptions }); if (result) { return result; } if (retries < 1) { - throw new Error(o.errorMsg); + throw new Error(options.errorMsg); } - cy.wait(o.interval, { log: false }).then(() => { + cy.wait(options.interval, { log: false }).then(() => { retries--; return resolveValue(); }); @@ -58,13 +77,6 @@ function waitUntil(subject, checkFunction, options = {}) { }; return resolveValue(); - - // return new Promise(resolve => { - // resolveValue().then(value => { - // console.log(value); - // resolve(value); - // }); - // }); -} +}; Cypress.Commands.add("waitUntil", { prevSubject: "optional" }, waitUntil);